Use word_mode to push/pop register for x86
[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 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
69 UNSPEC_GOT
70 UNSPEC_GOTOFF
71 UNSPEC_GOTPCREL
72 UNSPEC_GOTTPOFF
73 UNSPEC_TPOFF
74 UNSPEC_NTPOFF
75 UNSPEC_DTPOFF
76 UNSPEC_GOTNTPOFF
77 UNSPEC_INDNTPOFF
78 UNSPEC_PLTOFF
79 UNSPEC_MACHOPIC_OFFSET
80 UNSPEC_PCREL
81
82 ;; Prologue support
83 UNSPEC_STACK_ALLOC
84 UNSPEC_SET_GOT
85 UNSPEC_REG_SAVE
86 UNSPEC_DEF_CFA
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
115 ;; For SSE/MMX support:
116 UNSPEC_FIX_NOTRUNC
117 UNSPEC_MASKMOV
118 UNSPEC_MOVMSK
119 UNSPEC_RCP
120 UNSPEC_RSQRT
121 UNSPEC_PSADBW
122
123 ;; Generic math support
124 UNSPEC_COPYSIGN
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
127
128 ;; x87 Floating point
129 UNSPEC_SIN
130 UNSPEC_COS
131 UNSPEC_FPATAN
132 UNSPEC_FYL2X
133 UNSPEC_FYL2XP1
134 UNSPEC_FRNDINT
135 UNSPEC_FIST
136 UNSPEC_F2XM1
137 UNSPEC_TAN
138 UNSPEC_FXAM
139
140 ;; x87 Rounding
141 UNSPEC_FRNDINT_FLOOR
142 UNSPEC_FRNDINT_CEIL
143 UNSPEC_FRNDINT_TRUNC
144 UNSPEC_FRNDINT_MASK_PM
145 UNSPEC_FIST_FLOOR
146 UNSPEC_FIST_CEIL
147
148 ;; x87 Double output FP
149 UNSPEC_SINCOS_COS
150 UNSPEC_SINCOS_SIN
151 UNSPEC_XTRACT_FRACT
152 UNSPEC_XTRACT_EXP
153 UNSPEC_FSCALE_FRACT
154 UNSPEC_FSCALE_EXP
155 UNSPEC_FPREM_F
156 UNSPEC_FPREM_U
157 UNSPEC_FPREM1_F
158 UNSPEC_FPREM1_U
159
160 UNSPEC_C2_FLAG
161 UNSPEC_FXAM_MEM
162
163 ;; SSP patterns
164 UNSPEC_SP_SET
165 UNSPEC_SP_TEST
166 UNSPEC_SP_TLS_SET
167 UNSPEC_SP_TLS_TEST
168
169 ;; For ROUND support
170 UNSPEC_ROUND
171
172 ;; For CRC32 support
173 UNSPEC_CRC32
174
175 ;; For RDRAND support
176 UNSPEC_RDRAND
177
178 ;; For BMI support
179 UNSPEC_BEXTR
180
181 ;; For BMI2 support
182 UNSPEC_PDEP
183 UNSPEC_PEXT
184 ])
185
186 (define_c_enum "unspecv" [
187 UNSPECV_BLOCKAGE
188 UNSPECV_STACK_PROBE
189 UNSPECV_PROBE_STACK_RANGE
190 UNSPECV_ALIGN
191 UNSPECV_PROLOGUE_USE
192 UNSPECV_SPLIT_STACK_RETURN
193 UNSPECV_CLD
194 UNSPECV_NOPS
195 UNSPECV_RDTSC
196 UNSPECV_RDTSCP
197 UNSPECV_RDPMC
198 UNSPECV_LLWP_INTRINSIC
199 UNSPECV_SLWP_INTRINSIC
200 UNSPECV_LWPVAL_INTRINSIC
201 UNSPECV_LWPINS_INTRINSIC
202 UNSPECV_RDFSBASE
203 UNSPECV_RDGSBASE
204 UNSPECV_WRFSBASE
205 UNSPECV_WRGSBASE
206 ])
207
208 ;; Constants to represent rounding modes in the ROUND instruction
209 (define_constants
210 [(ROUND_FLOOR 0x1)
211 (ROUND_CEIL 0x2)
212 (ROUND_TRUNC 0x3)
213 (ROUND_MXCSR 0x4)
214 (ROUND_NO_EXC 0x8)
215 ])
216
217 ;; Constants to represent pcomtrue/pcomfalse variants
218 (define_constants
219 [(PCOM_FALSE 0)
220 (PCOM_TRUE 1)
221 (COM_FALSE_S 2)
222 (COM_FALSE_P 3)
223 (COM_TRUE_S 4)
224 (COM_TRUE_P 5)
225 ])
226
227 ;; Constants used in the XOP pperm instruction
228 (define_constants
229 [(PPERM_SRC 0x00) /* copy source */
230 (PPERM_INVERT 0x20) /* invert source */
231 (PPERM_REVERSE 0x40) /* bit reverse source */
232 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
233 (PPERM_ZERO 0x80) /* all 0's */
234 (PPERM_ONES 0xa0) /* all 1's */
235 (PPERM_SIGN 0xc0) /* propagate sign bit */
236 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
237 (PPERM_SRC1 0x00) /* use first source byte */
238 (PPERM_SRC2 0x10) /* use second source byte */
239 ])
240
241 ;; Registers by name.
242 (define_constants
243 [(AX_REG 0)
244 (DX_REG 1)
245 (CX_REG 2)
246 (BX_REG 3)
247 (SI_REG 4)
248 (DI_REG 5)
249 (BP_REG 6)
250 (SP_REG 7)
251 (ST0_REG 8)
252 (ST1_REG 9)
253 (ST2_REG 10)
254 (ST3_REG 11)
255 (ST4_REG 12)
256 (ST5_REG 13)
257 (ST6_REG 14)
258 (ST7_REG 15)
259 (FLAGS_REG 17)
260 (FPSR_REG 18)
261 (FPCR_REG 19)
262 (XMM0_REG 21)
263 (XMM1_REG 22)
264 (XMM2_REG 23)
265 (XMM3_REG 24)
266 (XMM4_REG 25)
267 (XMM5_REG 26)
268 (XMM6_REG 27)
269 (XMM7_REG 28)
270 (MM0_REG 29)
271 (MM1_REG 30)
272 (MM2_REG 31)
273 (MM3_REG 32)
274 (MM4_REG 33)
275 (MM5_REG 34)
276 (MM6_REG 35)
277 (MM7_REG 36)
278 (R8_REG 37)
279 (R9_REG 38)
280 (R10_REG 39)
281 (R11_REG 40)
282 (R12_REG 41)
283 (R13_REG 42)
284 (XMM8_REG 45)
285 (XMM9_REG 46)
286 (XMM10_REG 47)
287 (XMM11_REG 48)
288 (XMM12_REG 49)
289 (XMM13_REG 50)
290 (XMM14_REG 51)
291 (XMM15_REG 52)
292 ])
293
294 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
295 ;; from i386.c.
296
297 ;; In C guard expressions, put expressions which may be compile-time
298 ;; constants first. This allows for better optimization. For
299 ;; example, write "TARGET_64BIT && reload_completed", not
300 ;; "reload_completed && TARGET_64BIT".
301
302 \f
303 ;; Processor type.
304 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
305 atom,generic64,amdfam10,bdver1,bdver2,btver1"
306 (const (symbol_ref "ix86_schedule")))
307
308 ;; A basic instruction type. Refinements due to arguments to be
309 ;; provided in other attributes.
310 (define_attr "type"
311 "other,multi,
312 alu,alu1,negnot,imov,imovx,lea,
313 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
314 icmp,test,ibr,setcc,icmov,
315 push,pop,call,callv,leave,
316 str,bitmanip,
317 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
318 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
319 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
320 ssemuladd,sse4arg,lwp,
321 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
322 (const_string "other"))
323
324 ;; Main data type used by the insn
325 (define_attr "mode"
326 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
327 (const_string "unknown"))
328
329 ;; The CPU unit operations uses.
330 (define_attr "unit" "integer,i387,sse,mmx,unknown"
331 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
332 (const_string "i387")
333 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
334 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
335 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
336 (const_string "sse")
337 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
338 (const_string "mmx")
339 (eq_attr "type" "other")
340 (const_string "unknown")]
341 (const_string "integer")))
342
343 ;; The (bounding maximum) length of an instruction immediate.
344 (define_attr "length_immediate" ""
345 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
346 bitmanip,imulx")
347 (const_int 0)
348 (eq_attr "unit" "i387,sse,mmx")
349 (const_int 0)
350 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
351 rotate,rotatex,rotate1,imul,icmp,push,pop")
352 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
353 (eq_attr "type" "imov,test")
354 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
355 (eq_attr "type" "call")
356 (if_then_else (match_operand 0 "constant_call_address_operand" "")
357 (const_int 4)
358 (const_int 0))
359 (eq_attr "type" "callv")
360 (if_then_else (match_operand 1 "constant_call_address_operand" "")
361 (const_int 4)
362 (const_int 0))
363 ;; We don't know the size before shorten_branches. Expect
364 ;; the instruction to fit for better scheduling.
365 (eq_attr "type" "ibr")
366 (const_int 1)
367 ]
368 (symbol_ref "/* Update immediate_length and other attributes! */
369 gcc_unreachable (),1")))
370
371 ;; The (bounding maximum) length of an instruction address.
372 (define_attr "length_address" ""
373 (cond [(eq_attr "type" "str,other,multi,fxch")
374 (const_int 0)
375 (and (eq_attr "type" "call")
376 (match_operand 0 "constant_call_address_operand" ""))
377 (const_int 0)
378 (and (eq_attr "type" "callv")
379 (match_operand 1 "constant_call_address_operand" ""))
380 (const_int 0)
381 ]
382 (symbol_ref "ix86_attr_length_address_default (insn)")))
383
384 ;; Set when length prefix is used.
385 (define_attr "prefix_data16" ""
386 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
387 (const_int 0)
388 (eq_attr "mode" "HI")
389 (const_int 1)
390 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
391 (const_int 1)
392 ]
393 (const_int 0)))
394
395 ;; Set when string REP prefix is used.
396 (define_attr "prefix_rep" ""
397 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
398 (const_int 0)
399 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
400 (const_int 1)
401 ]
402 (const_int 0)))
403
404 ;; Set when 0f opcode prefix is used.
405 (define_attr "prefix_0f" ""
406 (if_then_else
407 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
408 (eq_attr "unit" "sse,mmx"))
409 (const_int 1)
410 (const_int 0)))
411
412 ;; Set when REX opcode prefix is used.
413 (define_attr "prefix_rex" ""
414 (cond [(not (match_test "TARGET_64BIT"))
415 (const_int 0)
416 (and (eq_attr "mode" "DI")
417 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
418 (eq_attr "unit" "!mmx")))
419 (const_int 1)
420 (and (eq_attr "mode" "QI")
421 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
422 (const_int 1)
423 (match_test "x86_extended_reg_mentioned_p (insn)")
424 (const_int 1)
425 (and (eq_attr "type" "imovx")
426 (match_operand:QI 1 "ext_QIreg_operand" ""))
427 (const_int 1)
428 ]
429 (const_int 0)))
430
431 ;; There are also additional prefixes in 3DNOW, SSSE3.
432 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
433 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
434 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
435 (define_attr "prefix_extra" ""
436 (cond [(eq_attr "type" "ssemuladd,sse4arg")
437 (const_int 2)
438 (eq_attr "type" "sseiadd1,ssecvt1")
439 (const_int 1)
440 ]
441 (const_int 0)))
442
443 ;; Prefix used: original, VEX or maybe VEX.
444 (define_attr "prefix" "orig,vex,maybe_vex"
445 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
446 (const_string "vex")
447 (const_string "orig")))
448
449 ;; VEX W bit is used.
450 (define_attr "prefix_vex_w" "" (const_int 0))
451
452 ;; The length of VEX prefix
453 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
454 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
455 ;; still prefix_0f 1, with prefix_extra 1.
456 (define_attr "length_vex" ""
457 (if_then_else (and (eq_attr "prefix_0f" "1")
458 (eq_attr "prefix_extra" "0"))
459 (if_then_else (eq_attr "prefix_vex_w" "1")
460 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
461 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
462 (if_then_else (eq_attr "prefix_vex_w" "1")
463 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
464 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
465
466 ;; Set when modrm byte is used.
467 (define_attr "modrm" ""
468 (cond [(eq_attr "type" "str,leave")
469 (const_int 0)
470 (eq_attr "unit" "i387")
471 (const_int 0)
472 (and (eq_attr "type" "incdec")
473 (and (not (match_test "TARGET_64BIT"))
474 (ior (match_operand:SI 1 "register_operand" "")
475 (match_operand:HI 1 "register_operand" ""))))
476 (const_int 0)
477 (and (eq_attr "type" "push")
478 (not (match_operand 1 "memory_operand" "")))
479 (const_int 0)
480 (and (eq_attr "type" "pop")
481 (not (match_operand 0 "memory_operand" "")))
482 (const_int 0)
483 (and (eq_attr "type" "imov")
484 (and (not (eq_attr "mode" "DI"))
485 (ior (and (match_operand 0 "register_operand" "")
486 (match_operand 1 "immediate_operand" ""))
487 (ior (and (match_operand 0 "ax_reg_operand" "")
488 (match_operand 1 "memory_displacement_only_operand" ""))
489 (and (match_operand 0 "memory_displacement_only_operand" "")
490 (match_operand 1 "ax_reg_operand" ""))))))
491 (const_int 0)
492 (and (eq_attr "type" "call")
493 (match_operand 0 "constant_call_address_operand" ""))
494 (const_int 0)
495 (and (eq_attr "type" "callv")
496 (match_operand 1 "constant_call_address_operand" ""))
497 (const_int 0)
498 (and (eq_attr "type" "alu,alu1,icmp,test")
499 (match_operand 0 "ax_reg_operand" ""))
500 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
501 ]
502 (const_int 1)))
503
504 ;; The (bounding maximum) length of an instruction in bytes.
505 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
506 ;; Later we may want to split them and compute proper length as for
507 ;; other insns.
508 (define_attr "length" ""
509 (cond [(eq_attr "type" "other,multi,fistp,frndint")
510 (const_int 16)
511 (eq_attr "type" "fcmp")
512 (const_int 4)
513 (eq_attr "unit" "i387")
514 (plus (const_int 2)
515 (plus (attr "prefix_data16")
516 (attr "length_address")))
517 (ior (eq_attr "prefix" "vex")
518 (and (eq_attr "prefix" "maybe_vex")
519 (match_test "TARGET_AVX")))
520 (plus (attr "length_vex")
521 (plus (attr "length_immediate")
522 (plus (attr "modrm")
523 (attr "length_address"))))]
524 (plus (plus (attr "modrm")
525 (plus (attr "prefix_0f")
526 (plus (attr "prefix_rex")
527 (plus (attr "prefix_extra")
528 (const_int 1)))))
529 (plus (attr "prefix_rep")
530 (plus (attr "prefix_data16")
531 (plus (attr "length_immediate")
532 (attr "length_address")))))))
533
534 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
535 ;; `store' if there is a simple memory reference therein, or `unknown'
536 ;; if the instruction is complex.
537
538 (define_attr "memory" "none,load,store,both,unknown"
539 (cond [(eq_attr "type" "other,multi,str,lwp")
540 (const_string "unknown")
541 (eq_attr "type" "lea,fcmov,fpspc")
542 (const_string "none")
543 (eq_attr "type" "fistp,leave")
544 (const_string "both")
545 (eq_attr "type" "frndint")
546 (const_string "load")
547 (eq_attr "type" "push")
548 (if_then_else (match_operand 1 "memory_operand" "")
549 (const_string "both")
550 (const_string "store"))
551 (eq_attr "type" "pop")
552 (if_then_else (match_operand 0 "memory_operand" "")
553 (const_string "both")
554 (const_string "load"))
555 (eq_attr "type" "setcc")
556 (if_then_else (match_operand 0 "memory_operand" "")
557 (const_string "store")
558 (const_string "none"))
559 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
560 (if_then_else (ior (match_operand 0 "memory_operand" "")
561 (match_operand 1 "memory_operand" ""))
562 (const_string "load")
563 (const_string "none"))
564 (eq_attr "type" "ibr")
565 (if_then_else (match_operand 0 "memory_operand" "")
566 (const_string "load")
567 (const_string "none"))
568 (eq_attr "type" "call")
569 (if_then_else (match_operand 0 "constant_call_address_operand" "")
570 (const_string "none")
571 (const_string "load"))
572 (eq_attr "type" "callv")
573 (if_then_else (match_operand 1 "constant_call_address_operand" "")
574 (const_string "none")
575 (const_string "load"))
576 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
577 (match_operand 1 "memory_operand" ""))
578 (const_string "both")
579 (and (match_operand 0 "memory_operand" "")
580 (match_operand 1 "memory_operand" ""))
581 (const_string "both")
582 (match_operand 0 "memory_operand" "")
583 (const_string "store")
584 (match_operand 1 "memory_operand" "")
585 (const_string "load")
586 (and (eq_attr "type"
587 "!alu1,negnot,ishift1,
588 imov,imovx,icmp,test,bitmanip,
589 fmov,fcmp,fsgn,
590 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
591 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
592 (match_operand 2 "memory_operand" ""))
593 (const_string "load")
594 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
595 (match_operand 3 "memory_operand" ""))
596 (const_string "load")
597 ]
598 (const_string "none")))
599
600 ;; Indicates if an instruction has both an immediate and a displacement.
601
602 (define_attr "imm_disp" "false,true,unknown"
603 (cond [(eq_attr "type" "other,multi")
604 (const_string "unknown")
605 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
606 (and (match_operand 0 "memory_displacement_operand" "")
607 (match_operand 1 "immediate_operand" "")))
608 (const_string "true")
609 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
610 (and (match_operand 0 "memory_displacement_operand" "")
611 (match_operand 2 "immediate_operand" "")))
612 (const_string "true")
613 ]
614 (const_string "false")))
615
616 ;; Indicates if an FP operation has an integer source.
617
618 (define_attr "fp_int_src" "false,true"
619 (const_string "false"))
620
621 ;; Defines rounding mode of an FP operation.
622
623 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
624 (const_string "any"))
625
626 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
627 (define_attr "use_carry" "0,1" (const_string "0"))
628
629 ;; Define attribute to indicate unaligned ssemov insns
630 (define_attr "movu" "0,1" (const_string "0"))
631
632 ;; Used to control the "enabled" attribute on a per-instruction basis.
633 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
634 (const_string "base"))
635
636 (define_attr "enabled" ""
637 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
638 (eq_attr "isa" "sse2_noavx")
639 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
640 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
641 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
642 (eq_attr "isa" "sse4_noavx")
643 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
644 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
645 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
646 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
647 ]
648 (const_int 1)))
649
650 ;; Describe a user's asm statement.
651 (define_asm_attributes
652 [(set_attr "length" "128")
653 (set_attr "type" "multi")])
654
655 (define_code_iterator plusminus [plus minus])
656
657 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
658
659 ;; Base name for define_insn
660 (define_code_attr plusminus_insn
661 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
662 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
663
664 ;; Base name for insn mnemonic.
665 (define_code_attr plusminus_mnemonic
666 [(plus "add") (ss_plus "adds") (us_plus "addus")
667 (minus "sub") (ss_minus "subs") (us_minus "subus")])
668 (define_code_attr plusminus_carry_mnemonic
669 [(plus "adc") (minus "sbb")])
670
671 ;; Mark commutative operators as such in constraints.
672 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
673 (minus "") (ss_minus "") (us_minus "")])
674
675 ;; Mapping of max and min
676 (define_code_iterator maxmin [smax smin umax umin])
677
678 ;; Mapping of signed max and min
679 (define_code_iterator smaxmin [smax smin])
680
681 ;; Mapping of unsigned max and min
682 (define_code_iterator umaxmin [umax umin])
683
684 ;; Base name for integer and FP insn mnemonic
685 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
686 (umax "maxu") (umin "minu")])
687 (define_code_attr maxmin_float [(smax "max") (smin "min")])
688
689 ;; Mapping of logic operators
690 (define_code_iterator any_logic [and ior xor])
691 (define_code_iterator any_or [ior xor])
692
693 ;; Base name for insn mnemonic.
694 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
695
696 ;; Mapping of logic-shift operators
697 (define_code_iterator any_lshift [ashift lshiftrt])
698
699 ;; Mapping of shift-right operators
700 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
701
702 ;; Base name for define_insn
703 (define_code_attr shift_insn
704 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
705
706 ;; Base name for insn mnemonic.
707 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
708 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
709
710 ;; Mapping of rotate operators
711 (define_code_iterator any_rotate [rotate rotatert])
712
713 ;; Base name for define_insn
714 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
715
716 ;; Base name for insn mnemonic.
717 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
718
719 ;; Mapping of abs neg operators
720 (define_code_iterator absneg [abs neg])
721
722 ;; Base name for x87 insn mnemonic.
723 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
724
725 ;; Used in signed and unsigned widening multiplications.
726 (define_code_iterator any_extend [sign_extend zero_extend])
727
728 ;; Prefix for insn menmonic.
729 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
730
731 ;; Prefix for define_insn
732 (define_code_attr u [(sign_extend "") (zero_extend "u")])
733 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
734
735 ;; All integer modes.
736 (define_mode_iterator SWI1248x [QI HI SI DI])
737
738 ;; All integer modes without QImode.
739 (define_mode_iterator SWI248x [HI SI DI])
740
741 ;; All integer modes without QImode and HImode.
742 (define_mode_iterator SWI48x [SI DI])
743
744 ;; All integer modes without SImode and DImode.
745 (define_mode_iterator SWI12 [QI HI])
746
747 ;; All integer modes without DImode.
748 (define_mode_iterator SWI124 [QI HI SI])
749
750 ;; All integer modes without QImode and DImode.
751 (define_mode_iterator SWI24 [HI SI])
752
753 ;; Single word integer modes.
754 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
755
756 ;; Single word integer modes without QImode.
757 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
758
759 ;; Single word integer modes without QImode and HImode.
760 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
761
762 ;; All math-dependant single and double word integer modes.
763 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
764 (HI "TARGET_HIMODE_MATH")
765 SI DI (TI "TARGET_64BIT")])
766
767 ;; Math-dependant single word integer modes.
768 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
769 (HI "TARGET_HIMODE_MATH")
770 SI (DI "TARGET_64BIT")])
771
772 ;; Math-dependant integer modes without DImode.
773 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
774 (HI "TARGET_HIMODE_MATH")
775 SI])
776
777 ;; Math-dependant single word integer modes without QImode.
778 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
779 SI (DI "TARGET_64BIT")])
780
781 ;; Double word integer modes.
782 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
783 (TI "TARGET_64BIT")])
784
785 ;; Double word integer modes as mode attribute.
786 (define_mode_attr DWI [(SI "DI") (DI "TI")])
787 (define_mode_attr dwi [(SI "di") (DI "ti")])
788
789 ;; Half mode for double word integer modes.
790 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
791 (DI "TARGET_64BIT")])
792
793 ;; Instruction suffix for integer modes.
794 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
795
796 ;; Pointer size prefix for integer modes (Intel asm dialect)
797 (define_mode_attr iptrsize [(QI "BYTE")
798 (HI "WORD")
799 (SI "DWORD")
800 (DI "QWORD")])
801
802 ;; Register class for integer modes.
803 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
804
805 ;; Immediate operand constraint for integer modes.
806 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
807
808 ;; General operand constraint for word modes.
809 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
810
811 ;; Immediate operand constraint for double integer modes.
812 (define_mode_attr di [(SI "nF") (DI "e")])
813
814 ;; Immediate operand constraint for shifts.
815 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
816
817 ;; General operand predicate for integer modes.
818 (define_mode_attr general_operand
819 [(QI "general_operand")
820 (HI "general_operand")
821 (SI "x86_64_general_operand")
822 (DI "x86_64_general_operand")
823 (TI "x86_64_general_operand")])
824
825 ;; General sign/zero extend operand predicate for integer modes.
826 (define_mode_attr general_szext_operand
827 [(QI "general_operand")
828 (HI "general_operand")
829 (SI "x86_64_szext_general_operand")
830 (DI "x86_64_szext_general_operand")])
831
832 ;; Immediate operand predicate for integer modes.
833 (define_mode_attr immediate_operand
834 [(QI "immediate_operand")
835 (HI "immediate_operand")
836 (SI "x86_64_immediate_operand")
837 (DI "x86_64_immediate_operand")])
838
839 ;; Nonmemory operand predicate for integer modes.
840 (define_mode_attr nonmemory_operand
841 [(QI "nonmemory_operand")
842 (HI "nonmemory_operand")
843 (SI "x86_64_nonmemory_operand")
844 (DI "x86_64_nonmemory_operand")])
845
846 ;; Operand predicate for shifts.
847 (define_mode_attr shift_operand
848 [(QI "nonimmediate_operand")
849 (HI "nonimmediate_operand")
850 (SI "nonimmediate_operand")
851 (DI "shiftdi_operand")
852 (TI "register_operand")])
853
854 ;; Operand predicate for shift argument.
855 (define_mode_attr shift_immediate_operand
856 [(QI "const_1_to_31_operand")
857 (HI "const_1_to_31_operand")
858 (SI "const_1_to_31_operand")
859 (DI "const_1_to_63_operand")])
860
861 ;; Input operand predicate for arithmetic left shifts.
862 (define_mode_attr ashl_input_operand
863 [(QI "nonimmediate_operand")
864 (HI "nonimmediate_operand")
865 (SI "nonimmediate_operand")
866 (DI "ashldi_input_operand")
867 (TI "reg_or_pm1_operand")])
868
869 ;; SSE and x87 SFmode and DFmode floating point modes
870 (define_mode_iterator MODEF [SF DF])
871
872 ;; All x87 floating point modes
873 (define_mode_iterator X87MODEF [SF DF XF])
874
875 ;; SSE instruction suffix for various modes
876 (define_mode_attr ssemodesuffix
877 [(SF "ss") (DF "sd")
878 (V8SF "ps") (V4DF "pd")
879 (V4SF "ps") (V2DF "pd")
880 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
881 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
882
883 ;; SSE vector suffix for floating point modes
884 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
885
886 ;; SSE vector mode corresponding to a scalar mode
887 (define_mode_attr ssevecmode
888 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
889
890 ;; Instruction suffix for REX 64bit operators.
891 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
892
893 ;; This mode iterator allows :P to be used for patterns that operate on
894 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
895 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
896
897 ;; This mode iterator allows :W to be used for patterns that operate on
898 ;; word_mode sized quantities.
899 (define_mode_iterator W
900 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
901
902 ;; This mode iterator allows :PTR to be used for patterns that operate on
903 ;; ptr_mode sized quantities.
904 (define_mode_iterator PTR
905 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
906 \f
907 ;; Scheduling descriptions
908
909 (include "pentium.md")
910 (include "ppro.md")
911 (include "k6.md")
912 (include "athlon.md")
913 (include "bdver1.md")
914 (include "geode.md")
915 (include "atom.md")
916 (include "core2.md")
917
918 \f
919 ;; Operand and operator predicates and constraints
920
921 (include "predicates.md")
922 (include "constraints.md")
923
924 \f
925 ;; Compare and branch/compare and store instructions.
926
927 (define_expand "cbranch<mode>4"
928 [(set (reg:CC FLAGS_REG)
929 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
930 (match_operand:SDWIM 2 "<general_operand>" "")))
931 (set (pc) (if_then_else
932 (match_operator 0 "ordered_comparison_operator"
933 [(reg:CC FLAGS_REG) (const_int 0)])
934 (label_ref (match_operand 3 "" ""))
935 (pc)))]
936 ""
937 {
938 if (MEM_P (operands[1]) && MEM_P (operands[2]))
939 operands[1] = force_reg (<MODE>mode, operands[1]);
940 ix86_expand_branch (GET_CODE (operands[0]),
941 operands[1], operands[2], operands[3]);
942 DONE;
943 })
944
945 (define_expand "cstore<mode>4"
946 [(set (reg:CC FLAGS_REG)
947 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
948 (match_operand:SWIM 3 "<general_operand>" "")))
949 (set (match_operand:QI 0 "register_operand" "")
950 (match_operator 1 "ordered_comparison_operator"
951 [(reg:CC FLAGS_REG) (const_int 0)]))]
952 ""
953 {
954 if (MEM_P (operands[2]) && MEM_P (operands[3]))
955 operands[2] = force_reg (<MODE>mode, operands[2]);
956 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
957 operands[2], operands[3]);
958 DONE;
959 })
960
961 (define_expand "cmp<mode>_1"
962 [(set (reg:CC FLAGS_REG)
963 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
964 (match_operand:SWI48 1 "<general_operand>" "")))])
965
966 (define_insn "*cmp<mode>_ccno_1"
967 [(set (reg FLAGS_REG)
968 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
969 (match_operand:SWI 1 "const0_operand" "")))]
970 "ix86_match_ccmode (insn, CCNOmode)"
971 "@
972 test{<imodesuffix>}\t%0, %0
973 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
974 [(set_attr "type" "test,icmp")
975 (set_attr "length_immediate" "0,1")
976 (set_attr "mode" "<MODE>")])
977
978 (define_insn "*cmp<mode>_1"
979 [(set (reg FLAGS_REG)
980 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
981 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
982 "ix86_match_ccmode (insn, CCmode)"
983 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
984 [(set_attr "type" "icmp")
985 (set_attr "mode" "<MODE>")])
986
987 (define_insn "*cmp<mode>_minus_1"
988 [(set (reg FLAGS_REG)
989 (compare
990 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
991 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
992 (const_int 0)))]
993 "ix86_match_ccmode (insn, CCGOCmode)"
994 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
995 [(set_attr "type" "icmp")
996 (set_attr "mode" "<MODE>")])
997
998 (define_insn "*cmpqi_ext_1"
999 [(set (reg FLAGS_REG)
1000 (compare
1001 (match_operand:QI 0 "general_operand" "Qm")
1002 (subreg:QI
1003 (zero_extract:SI
1004 (match_operand 1 "ext_register_operand" "Q")
1005 (const_int 8)
1006 (const_int 8)) 0)))]
1007 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1008 "cmp{b}\t{%h1, %0|%0, %h1}"
1009 [(set_attr "type" "icmp")
1010 (set_attr "mode" "QI")])
1011
1012 (define_insn "*cmpqi_ext_1_rex64"
1013 [(set (reg FLAGS_REG)
1014 (compare
1015 (match_operand:QI 0 "register_operand" "Q")
1016 (subreg:QI
1017 (zero_extract:SI
1018 (match_operand 1 "ext_register_operand" "Q")
1019 (const_int 8)
1020 (const_int 8)) 0)))]
1021 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1022 "cmp{b}\t{%h1, %0|%0, %h1}"
1023 [(set_attr "type" "icmp")
1024 (set_attr "mode" "QI")])
1025
1026 (define_insn "*cmpqi_ext_2"
1027 [(set (reg FLAGS_REG)
1028 (compare
1029 (subreg:QI
1030 (zero_extract:SI
1031 (match_operand 0 "ext_register_operand" "Q")
1032 (const_int 8)
1033 (const_int 8)) 0)
1034 (match_operand:QI 1 "const0_operand" "")))]
1035 "ix86_match_ccmode (insn, CCNOmode)"
1036 "test{b}\t%h0, %h0"
1037 [(set_attr "type" "test")
1038 (set_attr "length_immediate" "0")
1039 (set_attr "mode" "QI")])
1040
1041 (define_expand "cmpqi_ext_3"
1042 [(set (reg:CC FLAGS_REG)
1043 (compare:CC
1044 (subreg:QI
1045 (zero_extract:SI
1046 (match_operand 0 "ext_register_operand" "")
1047 (const_int 8)
1048 (const_int 8)) 0)
1049 (match_operand:QI 1 "immediate_operand" "")))])
1050
1051 (define_insn "*cmpqi_ext_3_insn"
1052 [(set (reg FLAGS_REG)
1053 (compare
1054 (subreg:QI
1055 (zero_extract:SI
1056 (match_operand 0 "ext_register_operand" "Q")
1057 (const_int 8)
1058 (const_int 8)) 0)
1059 (match_operand:QI 1 "general_operand" "Qmn")))]
1060 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1061 "cmp{b}\t{%1, %h0|%h0, %1}"
1062 [(set_attr "type" "icmp")
1063 (set_attr "modrm" "1")
1064 (set_attr "mode" "QI")])
1065
1066 (define_insn "*cmpqi_ext_3_insn_rex64"
1067 [(set (reg FLAGS_REG)
1068 (compare
1069 (subreg:QI
1070 (zero_extract:SI
1071 (match_operand 0 "ext_register_operand" "Q")
1072 (const_int 8)
1073 (const_int 8)) 0)
1074 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1075 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%1, %h0|%h0, %1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "modrm" "1")
1079 (set_attr "mode" "QI")])
1080
1081 (define_insn "*cmpqi_ext_4"
1082 [(set (reg FLAGS_REG)
1083 (compare
1084 (subreg:QI
1085 (zero_extract:SI
1086 (match_operand 0 "ext_register_operand" "Q")
1087 (const_int 8)
1088 (const_int 8)) 0)
1089 (subreg:QI
1090 (zero_extract:SI
1091 (match_operand 1 "ext_register_operand" "Q")
1092 (const_int 8)
1093 (const_int 8)) 0)))]
1094 "ix86_match_ccmode (insn, CCmode)"
1095 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1096 [(set_attr "type" "icmp")
1097 (set_attr "mode" "QI")])
1098
1099 ;; These implement float point compares.
1100 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1101 ;; which would allow mix and match FP modes on the compares. Which is what
1102 ;; the old patterns did, but with many more of them.
1103
1104 (define_expand "cbranchxf4"
1105 [(set (reg:CC FLAGS_REG)
1106 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1107 (match_operand:XF 2 "nonmemory_operand" "")))
1108 (set (pc) (if_then_else
1109 (match_operator 0 "ix86_fp_comparison_operator"
1110 [(reg:CC FLAGS_REG)
1111 (const_int 0)])
1112 (label_ref (match_operand 3 "" ""))
1113 (pc)))]
1114 "TARGET_80387"
1115 {
1116 ix86_expand_branch (GET_CODE (operands[0]),
1117 operands[1], operands[2], operands[3]);
1118 DONE;
1119 })
1120
1121 (define_expand "cstorexf4"
1122 [(set (reg:CC FLAGS_REG)
1123 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1124 (match_operand:XF 3 "nonmemory_operand" "")))
1125 (set (match_operand:QI 0 "register_operand" "")
1126 (match_operator 1 "ix86_fp_comparison_operator"
1127 [(reg:CC FLAGS_REG)
1128 (const_int 0)]))]
1129 "TARGET_80387"
1130 {
1131 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1132 operands[2], operands[3]);
1133 DONE;
1134 })
1135
1136 (define_expand "cbranch<mode>4"
1137 [(set (reg:CC FLAGS_REG)
1138 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1139 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1140 (set (pc) (if_then_else
1141 (match_operator 0 "ix86_fp_comparison_operator"
1142 [(reg:CC FLAGS_REG)
1143 (const_int 0)])
1144 (label_ref (match_operand 3 "" ""))
1145 (pc)))]
1146 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1147 {
1148 ix86_expand_branch (GET_CODE (operands[0]),
1149 operands[1], operands[2], operands[3]);
1150 DONE;
1151 })
1152
1153 (define_expand "cstore<mode>4"
1154 [(set (reg:CC FLAGS_REG)
1155 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1156 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1157 (set (match_operand:QI 0 "register_operand" "")
1158 (match_operator 1 "ix86_fp_comparison_operator"
1159 [(reg:CC FLAGS_REG)
1160 (const_int 0)]))]
1161 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1162 {
1163 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1164 operands[2], operands[3]);
1165 DONE;
1166 })
1167
1168 (define_expand "cbranchcc4"
1169 [(set (pc) (if_then_else
1170 (match_operator 0 "comparison_operator"
1171 [(match_operand 1 "flags_reg_operand" "")
1172 (match_operand 2 "const0_operand" "")])
1173 (label_ref (match_operand 3 "" ""))
1174 (pc)))]
1175 ""
1176 {
1177 ix86_expand_branch (GET_CODE (operands[0]),
1178 operands[1], operands[2], operands[3]);
1179 DONE;
1180 })
1181
1182 (define_expand "cstorecc4"
1183 [(set (match_operand:QI 0 "register_operand" "")
1184 (match_operator 1 "comparison_operator"
1185 [(match_operand 2 "flags_reg_operand" "")
1186 (match_operand 3 "const0_operand" "")]))]
1187 ""
1188 {
1189 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1190 operands[2], operands[3]);
1191 DONE;
1192 })
1193
1194
1195 ;; FP compares, step 1:
1196 ;; Set the FP condition codes.
1197 ;;
1198 ;; CCFPmode compare with exceptions
1199 ;; CCFPUmode compare with no exceptions
1200
1201 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1202 ;; used to manage the reg stack popping would not be preserved.
1203
1204 (define_insn "*cmpfp_0"
1205 [(set (match_operand:HI 0 "register_operand" "=a")
1206 (unspec:HI
1207 [(compare:CCFP
1208 (match_operand 1 "register_operand" "f")
1209 (match_operand 2 "const0_operand" ""))]
1210 UNSPEC_FNSTSW))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213 "* return output_fp_compare (insn, operands, false, false);"
1214 [(set_attr "type" "multi")
1215 (set_attr "unit" "i387")
1216 (set (attr "mode")
1217 (cond [(match_operand:SF 1 "" "")
1218 (const_string "SF")
1219 (match_operand:DF 1 "" "")
1220 (const_string "DF")
1221 ]
1222 (const_string "XF")))])
1223
1224 (define_insn_and_split "*cmpfp_0_cc"
1225 [(set (reg:CCFP FLAGS_REG)
1226 (compare:CCFP
1227 (match_operand 1 "register_operand" "f")
1228 (match_operand 2 "const0_operand" "")))
1229 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1230 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231 && TARGET_SAHF && !TARGET_CMOVE
1232 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1233 "#"
1234 "&& reload_completed"
1235 [(set (match_dup 0)
1236 (unspec:HI
1237 [(compare:CCFP (match_dup 1)(match_dup 2))]
1238 UNSPEC_FNSTSW))
1239 (set (reg:CC FLAGS_REG)
1240 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1241 ""
1242 [(set_attr "type" "multi")
1243 (set_attr "unit" "i387")
1244 (set (attr "mode")
1245 (cond [(match_operand:SF 1 "" "")
1246 (const_string "SF")
1247 (match_operand:DF 1 "" "")
1248 (const_string "DF")
1249 ]
1250 (const_string "XF")))])
1251
1252 (define_insn "*cmpfp_xf"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1254 (unspec:HI
1255 [(compare:CCFP
1256 (match_operand:XF 1 "register_operand" "f")
1257 (match_operand:XF 2 "register_operand" "f"))]
1258 UNSPEC_FNSTSW))]
1259 "TARGET_80387"
1260 "* return output_fp_compare (insn, operands, false, false);"
1261 [(set_attr "type" "multi")
1262 (set_attr "unit" "i387")
1263 (set_attr "mode" "XF")])
1264
1265 (define_insn_and_split "*cmpfp_xf_cc"
1266 [(set (reg:CCFP FLAGS_REG)
1267 (compare:CCFP
1268 (match_operand:XF 1 "register_operand" "f")
1269 (match_operand:XF 2 "register_operand" "f")))
1270 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1271 "TARGET_80387
1272 && TARGET_SAHF && !TARGET_CMOVE"
1273 "#"
1274 "&& reload_completed"
1275 [(set (match_dup 0)
1276 (unspec:HI
1277 [(compare:CCFP (match_dup 1)(match_dup 2))]
1278 UNSPEC_FNSTSW))
1279 (set (reg:CC FLAGS_REG)
1280 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1281 ""
1282 [(set_attr "type" "multi")
1283 (set_attr "unit" "i387")
1284 (set_attr "mode" "XF")])
1285
1286 (define_insn "*cmpfp_<mode>"
1287 [(set (match_operand:HI 0 "register_operand" "=a")
1288 (unspec:HI
1289 [(compare:CCFP
1290 (match_operand:MODEF 1 "register_operand" "f")
1291 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1292 UNSPEC_FNSTSW))]
1293 "TARGET_80387"
1294 "* return output_fp_compare (insn, operands, false, false);"
1295 [(set_attr "type" "multi")
1296 (set_attr "unit" "i387")
1297 (set_attr "mode" "<MODE>")])
1298
1299 (define_insn_and_split "*cmpfp_<mode>_cc"
1300 [(set (reg:CCFP FLAGS_REG)
1301 (compare:CCFP
1302 (match_operand:MODEF 1 "register_operand" "f")
1303 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1304 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1305 "TARGET_80387
1306 && TARGET_SAHF && !TARGET_CMOVE"
1307 "#"
1308 "&& reload_completed"
1309 [(set (match_dup 0)
1310 (unspec:HI
1311 [(compare:CCFP (match_dup 1)(match_dup 2))]
1312 UNSPEC_FNSTSW))
1313 (set (reg:CC FLAGS_REG)
1314 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1315 ""
1316 [(set_attr "type" "multi")
1317 (set_attr "unit" "i387")
1318 (set_attr "mode" "<MODE>")])
1319
1320 (define_insn "*cmpfp_u"
1321 [(set (match_operand:HI 0 "register_operand" "=a")
1322 (unspec:HI
1323 [(compare:CCFPU
1324 (match_operand 1 "register_operand" "f")
1325 (match_operand 2 "register_operand" "f"))]
1326 UNSPEC_FNSTSW))]
1327 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1328 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1329 "* return output_fp_compare (insn, operands, false, true);"
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set (attr "mode")
1333 (cond [(match_operand:SF 1 "" "")
1334 (const_string "SF")
1335 (match_operand:DF 1 "" "")
1336 (const_string "DF")
1337 ]
1338 (const_string "XF")))])
1339
1340 (define_insn_and_split "*cmpfp_u_cc"
1341 [(set (reg:CCFPU FLAGS_REG)
1342 (compare:CCFPU
1343 (match_operand 1 "register_operand" "f")
1344 (match_operand 2 "register_operand" "f")))
1345 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1346 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1347 && TARGET_SAHF && !TARGET_CMOVE
1348 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1349 "#"
1350 "&& reload_completed"
1351 [(set (match_dup 0)
1352 (unspec:HI
1353 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1354 UNSPEC_FNSTSW))
1355 (set (reg:CC FLAGS_REG)
1356 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1357 ""
1358 [(set_attr "type" "multi")
1359 (set_attr "unit" "i387")
1360 (set (attr "mode")
1361 (cond [(match_operand:SF 1 "" "")
1362 (const_string "SF")
1363 (match_operand:DF 1 "" "")
1364 (const_string "DF")
1365 ]
1366 (const_string "XF")))])
1367
1368 (define_insn "*cmpfp_<mode>"
1369 [(set (match_operand:HI 0 "register_operand" "=a")
1370 (unspec:HI
1371 [(compare:CCFP
1372 (match_operand 1 "register_operand" "f")
1373 (match_operator 3 "float_operator"
1374 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1375 UNSPEC_FNSTSW))]
1376 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1377 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1378 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1379 "* return output_fp_compare (insn, operands, false, false);"
1380 [(set_attr "type" "multi")
1381 (set_attr "unit" "i387")
1382 (set_attr "fp_int_src" "true")
1383 (set_attr "mode" "<MODE>")])
1384
1385 (define_insn_and_split "*cmpfp_<mode>_cc"
1386 [(set (reg:CCFP FLAGS_REG)
1387 (compare:CCFP
1388 (match_operand 1 "register_operand" "f")
1389 (match_operator 3 "float_operator"
1390 [(match_operand:SWI24 2 "memory_operand" "m")])))
1391 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1392 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1393 && TARGET_SAHF && !TARGET_CMOVE
1394 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1395 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1396 "#"
1397 "&& reload_completed"
1398 [(set (match_dup 0)
1399 (unspec:HI
1400 [(compare:CCFP
1401 (match_dup 1)
1402 (match_op_dup 3 [(match_dup 2)]))]
1403 UNSPEC_FNSTSW))
1404 (set (reg:CC FLAGS_REG)
1405 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1406 ""
1407 [(set_attr "type" "multi")
1408 (set_attr "unit" "i387")
1409 (set_attr "fp_int_src" "true")
1410 (set_attr "mode" "<MODE>")])
1411
1412 ;; FP compares, step 2
1413 ;; Move the fpsw to ax.
1414
1415 (define_insn "x86_fnstsw_1"
1416 [(set (match_operand:HI 0 "register_operand" "=a")
1417 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1418 "TARGET_80387"
1419 "fnstsw\t%0"
1420 [(set (attr "length")
1421 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1422 (set_attr "mode" "SI")
1423 (set_attr "unit" "i387")])
1424
1425 ;; FP compares, step 3
1426 ;; Get ax into flags, general case.
1427
1428 (define_insn "x86_sahf_1"
1429 [(set (reg:CC FLAGS_REG)
1430 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1431 UNSPEC_SAHF))]
1432 "TARGET_SAHF"
1433 {
1434 #ifndef HAVE_AS_IX86_SAHF
1435 if (TARGET_64BIT)
1436 return ASM_BYTE "0x9e";
1437 else
1438 #endif
1439 return "sahf";
1440 }
1441 [(set_attr "length" "1")
1442 (set_attr "athlon_decode" "vector")
1443 (set_attr "amdfam10_decode" "direct")
1444 (set_attr "bdver1_decode" "direct")
1445 (set_attr "mode" "SI")])
1446
1447 ;; Pentium Pro can do steps 1 through 3 in one go.
1448 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1449 ;; (these i387 instructions set flags directly)
1450 (define_insn "*cmpfp_i_mixed"
1451 [(set (reg:CCFP FLAGS_REG)
1452 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1453 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1454 "TARGET_MIX_SSE_I387
1455 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1456 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1457 "* return output_fp_compare (insn, operands, true, false);"
1458 [(set_attr "type" "fcmp,ssecomi")
1459 (set_attr "prefix" "orig,maybe_vex")
1460 (set (attr "mode")
1461 (if_then_else (match_operand:SF 1 "" "")
1462 (const_string "SF")
1463 (const_string "DF")))
1464 (set (attr "prefix_rep")
1465 (if_then_else (eq_attr "type" "ssecomi")
1466 (const_string "0")
1467 (const_string "*")))
1468 (set (attr "prefix_data16")
1469 (cond [(eq_attr "type" "fcmp")
1470 (const_string "*")
1471 (eq_attr "mode" "DF")
1472 (const_string "1")
1473 ]
1474 (const_string "0")))
1475 (set_attr "athlon_decode" "vector")
1476 (set_attr "amdfam10_decode" "direct")
1477 (set_attr "bdver1_decode" "double")])
1478
1479 (define_insn "*cmpfp_i_sse"
1480 [(set (reg:CCFP FLAGS_REG)
1481 (compare:CCFP (match_operand 0 "register_operand" "x")
1482 (match_operand 1 "nonimmediate_operand" "xm")))]
1483 "TARGET_SSE_MATH
1484 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1485 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1486 "* return output_fp_compare (insn, operands, true, false);"
1487 [(set_attr "type" "ssecomi")
1488 (set_attr "prefix" "maybe_vex")
1489 (set (attr "mode")
1490 (if_then_else (match_operand:SF 1 "" "")
1491 (const_string "SF")
1492 (const_string "DF")))
1493 (set_attr "prefix_rep" "0")
1494 (set (attr "prefix_data16")
1495 (if_then_else (eq_attr "mode" "DF")
1496 (const_string "1")
1497 (const_string "0")))
1498 (set_attr "athlon_decode" "vector")
1499 (set_attr "amdfam10_decode" "direct")
1500 (set_attr "bdver1_decode" "double")])
1501
1502 (define_insn "*cmpfp_i_i387"
1503 [(set (reg:CCFP FLAGS_REG)
1504 (compare:CCFP (match_operand 0 "register_operand" "f")
1505 (match_operand 1 "register_operand" "f")))]
1506 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1507 && TARGET_CMOVE
1508 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1509 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510 "* return output_fp_compare (insn, operands, true, false);"
1511 [(set_attr "type" "fcmp")
1512 (set (attr "mode")
1513 (cond [(match_operand:SF 1 "" "")
1514 (const_string "SF")
1515 (match_operand:DF 1 "" "")
1516 (const_string "DF")
1517 ]
1518 (const_string "XF")))
1519 (set_attr "athlon_decode" "vector")
1520 (set_attr "amdfam10_decode" "direct")
1521 (set_attr "bdver1_decode" "double")])
1522
1523 (define_insn "*cmpfp_iu_mixed"
1524 [(set (reg:CCFPU FLAGS_REG)
1525 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1526 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1527 "TARGET_MIX_SSE_I387
1528 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1529 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1530 "* return output_fp_compare (insn, operands, true, true);"
1531 [(set_attr "type" "fcmp,ssecomi")
1532 (set_attr "prefix" "orig,maybe_vex")
1533 (set (attr "mode")
1534 (if_then_else (match_operand:SF 1 "" "")
1535 (const_string "SF")
1536 (const_string "DF")))
1537 (set (attr "prefix_rep")
1538 (if_then_else (eq_attr "type" "ssecomi")
1539 (const_string "0")
1540 (const_string "*")))
1541 (set (attr "prefix_data16")
1542 (cond [(eq_attr "type" "fcmp")
1543 (const_string "*")
1544 (eq_attr "mode" "DF")
1545 (const_string "1")
1546 ]
1547 (const_string "0")))
1548 (set_attr "athlon_decode" "vector")
1549 (set_attr "amdfam10_decode" "direct")
1550 (set_attr "bdver1_decode" "double")])
1551
1552 (define_insn "*cmpfp_iu_sse"
1553 [(set (reg:CCFPU FLAGS_REG)
1554 (compare:CCFPU (match_operand 0 "register_operand" "x")
1555 (match_operand 1 "nonimmediate_operand" "xm")))]
1556 "TARGET_SSE_MATH
1557 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1558 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1559 "* return output_fp_compare (insn, operands, true, true);"
1560 [(set_attr "type" "ssecomi")
1561 (set_attr "prefix" "maybe_vex")
1562 (set (attr "mode")
1563 (if_then_else (match_operand:SF 1 "" "")
1564 (const_string "SF")
1565 (const_string "DF")))
1566 (set_attr "prefix_rep" "0")
1567 (set (attr "prefix_data16")
1568 (if_then_else (eq_attr "mode" "DF")
1569 (const_string "1")
1570 (const_string "0")))
1571 (set_attr "athlon_decode" "vector")
1572 (set_attr "amdfam10_decode" "direct")
1573 (set_attr "bdver1_decode" "double")])
1574
1575 (define_insn "*cmpfp_iu_387"
1576 [(set (reg:CCFPU FLAGS_REG)
1577 (compare:CCFPU (match_operand 0 "register_operand" "f")
1578 (match_operand 1 "register_operand" "f")))]
1579 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1580 && TARGET_CMOVE
1581 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1582 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583 "* return output_fp_compare (insn, operands, true, true);"
1584 [(set_attr "type" "fcmp")
1585 (set (attr "mode")
1586 (cond [(match_operand:SF 1 "" "")
1587 (const_string "SF")
1588 (match_operand:DF 1 "" "")
1589 (const_string "DF")
1590 ]
1591 (const_string "XF")))
1592 (set_attr "athlon_decode" "vector")
1593 (set_attr "amdfam10_decode" "direct")
1594 (set_attr "bdver1_decode" "direct")])
1595 \f
1596 ;; Push/pop instructions.
1597
1598 (define_insn "*push<mode>2"
1599 [(set (match_operand:DWI 0 "push_operand" "=<")
1600 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1601 ""
1602 "#"
1603 [(set_attr "type" "multi")
1604 (set_attr "mode" "<MODE>")])
1605
1606 (define_split
1607 [(set (match_operand:TI 0 "push_operand" "")
1608 (match_operand:TI 1 "general_operand" ""))]
1609 "TARGET_64BIT && reload_completed
1610 && !SSE_REG_P (operands[1])"
1611 [(const_int 0)]
1612 "ix86_split_long_move (operands); DONE;")
1613
1614 (define_insn "*pushdi2_rex64"
1615 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1616 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1617 "TARGET_64BIT"
1618 "@
1619 push{q}\t%1
1620 #"
1621 [(set_attr "type" "push,multi")
1622 (set_attr "mode" "DI")])
1623
1624 ;; Convert impossible pushes of immediate to existing instructions.
1625 ;; First try to get scratch register and go through it. In case this
1626 ;; fails, push sign extended lower part first and then overwrite
1627 ;; upper part by 32bit move.
1628 (define_peephole2
1629 [(match_scratch:DI 2 "r")
1630 (set (match_operand:DI 0 "push_operand" "")
1631 (match_operand:DI 1 "immediate_operand" ""))]
1632 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1633 && !x86_64_immediate_operand (operands[1], DImode)"
1634 [(set (match_dup 2) (match_dup 1))
1635 (set (match_dup 0) (match_dup 2))])
1636
1637 ;; We need to define this as both peepholer and splitter for case
1638 ;; peephole2 pass is not run.
1639 ;; "&& 1" is needed to keep it from matching the previous pattern.
1640 (define_peephole2
1641 [(set (match_operand:DI 0 "push_operand" "")
1642 (match_operand:DI 1 "immediate_operand" ""))]
1643 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1644 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1645 [(set (match_dup 0) (match_dup 1))
1646 (set (match_dup 2) (match_dup 3))]
1647 {
1648 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1649
1650 operands[1] = gen_lowpart (DImode, operands[2]);
1651 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1652 GEN_INT (4)));
1653 })
1654
1655 (define_split
1656 [(set (match_operand:DI 0 "push_operand" "")
1657 (match_operand:DI 1 "immediate_operand" ""))]
1658 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1659 ? epilogue_completed : reload_completed)
1660 && !symbolic_operand (operands[1], DImode)
1661 && !x86_64_immediate_operand (operands[1], DImode)"
1662 [(set (match_dup 0) (match_dup 1))
1663 (set (match_dup 2) (match_dup 3))]
1664 {
1665 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1666
1667 operands[1] = gen_lowpart (DImode, operands[2]);
1668 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1669 GEN_INT (4)));
1670 })
1671
1672 (define_split
1673 [(set (match_operand:DI 0 "push_operand" "")
1674 (match_operand:DI 1 "general_operand" ""))]
1675 "!TARGET_64BIT && reload_completed
1676 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1677 [(const_int 0)]
1678 "ix86_split_long_move (operands); DONE;")
1679
1680 (define_insn "*pushsi2"
1681 [(set (match_operand:SI 0 "push_operand" "=<")
1682 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1683 "!TARGET_64BIT"
1684 "push{l}\t%1"
1685 [(set_attr "type" "push")
1686 (set_attr "mode" "SI")])
1687
1688 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1689 ;; "push a byte/word". But actually we use pushl, which has the effect
1690 ;; of rounding the amount pushed up to a word.
1691
1692 ;; For TARGET_64BIT we always round up to 8 bytes.
1693 (define_insn "*push<mode>2_rex64"
1694 [(set (match_operand:SWI124 0 "push_operand" "=X")
1695 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1696 "TARGET_64BIT"
1697 "push{q}\t%q1"
1698 [(set_attr "type" "push")
1699 (set_attr "mode" "DI")])
1700
1701 (define_insn "*push<mode>2"
1702 [(set (match_operand:SWI12 0 "push_operand" "=X")
1703 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1704 "!TARGET_64BIT"
1705 "push{l}\t%k1"
1706 [(set_attr "type" "push")
1707 (set_attr "mode" "SI")])
1708
1709 (define_insn "*push<mode>2_prologue"
1710 [(set (match_operand:W 0 "push_operand" "=<")
1711 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1712 (clobber (mem:BLK (scratch)))]
1713 ""
1714 "push{<imodesuffix>}\t%1"
1715 [(set_attr "type" "push")
1716 (set_attr "mode" "<MODE>")])
1717
1718 (define_insn "*pop<mode>1"
1719 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1720 (match_operand:W 1 "pop_operand" ">"))]
1721 ""
1722 "pop{<imodesuffix>}\t%0"
1723 [(set_attr "type" "pop")
1724 (set_attr "mode" "<MODE>")])
1725
1726 (define_insn "*pop<mode>1_epilogue"
1727 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1728 (match_operand:W 1 "pop_operand" ">"))
1729 (clobber (mem:BLK (scratch)))]
1730 ""
1731 "pop{<imodesuffix>}\t%0"
1732 [(set_attr "type" "pop")
1733 (set_attr "mode" "<MODE>")])
1734 \f
1735 ;; Move instructions.
1736
1737 (define_expand "movoi"
1738 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1739 (match_operand:OI 1 "general_operand" ""))]
1740 "TARGET_AVX"
1741 "ix86_expand_move (OImode, operands); DONE;")
1742
1743 (define_expand "movti"
1744 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1745 (match_operand:TI 1 "nonimmediate_operand" ""))]
1746 "TARGET_64BIT || TARGET_SSE"
1747 {
1748 if (TARGET_64BIT)
1749 ix86_expand_move (TImode, operands);
1750 else if (push_operand (operands[0], TImode))
1751 ix86_expand_push (TImode, operands[1]);
1752 else
1753 ix86_expand_vector_move (TImode, operands);
1754 DONE;
1755 })
1756
1757 ;; This expands to what emit_move_complex would generate if we didn't
1758 ;; have a movti pattern. Having this avoids problems with reload on
1759 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1760 ;; to have around all the time.
1761 (define_expand "movcdi"
1762 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1763 (match_operand:CDI 1 "general_operand" ""))]
1764 ""
1765 {
1766 if (push_operand (operands[0], CDImode))
1767 emit_move_complex_push (CDImode, operands[0], operands[1]);
1768 else
1769 emit_move_complex_parts (operands[0], operands[1]);
1770 DONE;
1771 })
1772
1773 (define_expand "mov<mode>"
1774 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1775 (match_operand:SWI1248x 1 "general_operand" ""))]
1776 ""
1777 "ix86_expand_move (<MODE>mode, operands); DONE;")
1778
1779 (define_insn "*mov<mode>_xor"
1780 [(set (match_operand:SWI48 0 "register_operand" "=r")
1781 (match_operand:SWI48 1 "const0_operand" ""))
1782 (clobber (reg:CC FLAGS_REG))]
1783 "reload_completed"
1784 "xor{l}\t%k0, %k0"
1785 [(set_attr "type" "alu1")
1786 (set_attr "mode" "SI")
1787 (set_attr "length_immediate" "0")])
1788
1789 (define_insn "*mov<mode>_or"
1790 [(set (match_operand:SWI48 0 "register_operand" "=r")
1791 (match_operand:SWI48 1 "const_int_operand" ""))
1792 (clobber (reg:CC FLAGS_REG))]
1793 "reload_completed
1794 && operands[1] == constm1_rtx"
1795 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1796 [(set_attr "type" "alu1")
1797 (set_attr "mode" "<MODE>")
1798 (set_attr "length_immediate" "1")])
1799
1800 (define_insn "*movoi_internal_avx"
1801 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1802 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1803 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1804 {
1805 switch (which_alternative)
1806 {
1807 case 0:
1808 return standard_sse_constant_opcode (insn, operands[1]);
1809 case 1:
1810 case 2:
1811 if (misaligned_operand (operands[0], OImode)
1812 || misaligned_operand (operands[1], OImode))
1813 return "vmovdqu\t{%1, %0|%0, %1}";
1814 else
1815 return "vmovdqa\t{%1, %0|%0, %1}";
1816 default:
1817 gcc_unreachable ();
1818 }
1819 }
1820 [(set_attr "type" "sselog1,ssemov,ssemov")
1821 (set_attr "prefix" "vex")
1822 (set_attr "mode" "OI")])
1823
1824 (define_insn "*movti_internal_rex64"
1825 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1826 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1827 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1828 {
1829 switch (which_alternative)
1830 {
1831 case 0:
1832 case 1:
1833 return "#";
1834 case 2:
1835 return standard_sse_constant_opcode (insn, operands[1]);
1836 case 3:
1837 case 4:
1838 /* TDmode values are passed as TImode on the stack. Moving them
1839 to stack may result in unaligned memory access. */
1840 if (misaligned_operand (operands[0], TImode)
1841 || misaligned_operand (operands[1], TImode))
1842 {
1843 if (get_attr_mode (insn) == MODE_V4SF)
1844 return "%vmovups\t{%1, %0|%0, %1}";
1845 else
1846 return "%vmovdqu\t{%1, %0|%0, %1}";
1847 }
1848 else
1849 {
1850 if (get_attr_mode (insn) == MODE_V4SF)
1851 return "%vmovaps\t{%1, %0|%0, %1}";
1852 else
1853 return "%vmovdqa\t{%1, %0|%0, %1}";
1854 }
1855 default:
1856 gcc_unreachable ();
1857 }
1858 }
1859 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1860 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1861 (set (attr "mode")
1862 (cond [(eq_attr "alternative" "2,3")
1863 (if_then_else
1864 (match_test "optimize_function_for_size_p (cfun)")
1865 (const_string "V4SF")
1866 (const_string "TI"))
1867 (eq_attr "alternative" "4")
1868 (if_then_else
1869 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1870 (match_test "optimize_function_for_size_p (cfun)"))
1871 (const_string "V4SF")
1872 (const_string "TI"))]
1873 (const_string "DI")))])
1874
1875 (define_split
1876 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1877 (match_operand:TI 1 "general_operand" ""))]
1878 "reload_completed
1879 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1880 [(const_int 0)]
1881 "ix86_split_long_move (operands); DONE;")
1882
1883 (define_insn "*movti_internal_sse"
1884 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1885 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1886 "TARGET_SSE && !TARGET_64BIT
1887 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1888 {
1889 switch (which_alternative)
1890 {
1891 case 0:
1892 return standard_sse_constant_opcode (insn, operands[1]);
1893 case 1:
1894 case 2:
1895 /* TDmode values are passed as TImode on the stack. Moving them
1896 to stack may result in unaligned memory access. */
1897 if (misaligned_operand (operands[0], TImode)
1898 || misaligned_operand (operands[1], TImode))
1899 {
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vmovups\t{%1, %0|%0, %1}";
1902 else
1903 return "%vmovdqu\t{%1, %0|%0, %1}";
1904 }
1905 else
1906 {
1907 if (get_attr_mode (insn) == MODE_V4SF)
1908 return "%vmovaps\t{%1, %0|%0, %1}";
1909 else
1910 return "%vmovdqa\t{%1, %0|%0, %1}";
1911 }
1912 default:
1913 gcc_unreachable ();
1914 }
1915 }
1916 [(set_attr "type" "sselog1,ssemov,ssemov")
1917 (set_attr "prefix" "maybe_vex")
1918 (set (attr "mode")
1919 (cond [(ior (not (match_test "TARGET_SSE2"))
1920 (match_test "optimize_function_for_size_p (cfun)"))
1921 (const_string "V4SF")
1922 (and (eq_attr "alternative" "2")
1923 (match_test "TARGET_SSE_TYPELESS_STORES"))
1924 (const_string "V4SF")]
1925 (const_string "TI")))])
1926
1927 (define_insn "*movdi_internal_rex64"
1928 [(set (match_operand:DI 0 "nonimmediate_operand"
1929 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1930 (match_operand:DI 1 "general_operand"
1931 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1932 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1933 {
1934 switch (get_attr_type (insn))
1935 {
1936 case TYPE_SSECVT:
1937 if (SSE_REG_P (operands[0]))
1938 return "movq2dq\t{%1, %0|%0, %1}";
1939 else
1940 return "movdq2q\t{%1, %0|%0, %1}";
1941
1942 case TYPE_SSEMOV:
1943 if (get_attr_mode (insn) == MODE_TI)
1944 return "%vmovdqa\t{%1, %0|%0, %1}";
1945 /* Handle broken assemblers that require movd instead of movq. */
1946 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1947 return "%vmovd\t{%1, %0|%0, %1}";
1948 else
1949 return "%vmovq\t{%1, %0|%0, %1}";
1950
1951 case TYPE_MMXMOV:
1952 /* Handle broken assemblers that require movd instead of movq. */
1953 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1954 return "movd\t{%1, %0|%0, %1}";
1955 else
1956 return "movq\t{%1, %0|%0, %1}";
1957
1958 case TYPE_SSELOG1:
1959 return standard_sse_constant_opcode (insn, operands[1]);
1960
1961 case TYPE_MMX:
1962 return "pxor\t%0, %0";
1963
1964 case TYPE_MULTI:
1965 return "#";
1966
1967 case TYPE_LEA:
1968 return "lea{q}\t{%a1, %0|%0, %a1}";
1969
1970 default:
1971 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1972 if (get_attr_mode (insn) == MODE_SI)
1973 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1974 else if (which_alternative == 2)
1975 return "movabs{q}\t{%1, %0|%0, %1}";
1976 else if (ix86_use_lea_for_mov (insn, operands))
1977 return "lea{q}\t{%a1, %0|%0, %a1}";
1978 else
1979 return "mov{q}\t{%1, %0|%0, %1}";
1980 }
1981 }
1982 [(set (attr "type")
1983 (cond [(eq_attr "alternative" "4")
1984 (const_string "multi")
1985 (eq_attr "alternative" "5")
1986 (const_string "mmx")
1987 (eq_attr "alternative" "6,7,8,9")
1988 (const_string "mmxmov")
1989 (eq_attr "alternative" "10")
1990 (const_string "sselog1")
1991 (eq_attr "alternative" "11,12,13,14,15")
1992 (const_string "ssemov")
1993 (eq_attr "alternative" "16,17")
1994 (const_string "ssecvt")
1995 (match_operand 1 "pic_32bit_operand" "")
1996 (const_string "lea")
1997 ]
1998 (const_string "imov")))
1999 (set (attr "modrm")
2000 (if_then_else
2001 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2002 (const_string "0")
2003 (const_string "*")))
2004 (set (attr "length_immediate")
2005 (if_then_else
2006 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2007 (const_string "8")
2008 (const_string "*")))
2009 (set (attr "prefix_rex")
2010 (if_then_else (eq_attr "alternative" "8,9")
2011 (const_string "1")
2012 (const_string "*")))
2013 (set (attr "prefix_data16")
2014 (if_then_else (eq_attr "alternative" "11")
2015 (const_string "1")
2016 (const_string "*")))
2017 (set (attr "prefix")
2018 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2019 (const_string "maybe_vex")
2020 (const_string "orig")))
2021 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2022
2023 ;; Reload patterns to support multi-word load/store
2024 ;; with non-offsetable address.
2025 (define_expand "reload_noff_store"
2026 [(parallel [(match_operand 0 "memory_operand" "=m")
2027 (match_operand 1 "register_operand" "r")
2028 (match_operand:DI 2 "register_operand" "=&r")])]
2029 "TARGET_64BIT"
2030 {
2031 rtx mem = operands[0];
2032 rtx addr = XEXP (mem, 0);
2033
2034 emit_move_insn (operands[2], addr);
2035 mem = replace_equiv_address_nv (mem, operands[2]);
2036
2037 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2038 DONE;
2039 })
2040
2041 (define_expand "reload_noff_load"
2042 [(parallel [(match_operand 0 "register_operand" "=r")
2043 (match_operand 1 "memory_operand" "m")
2044 (match_operand:DI 2 "register_operand" "=r")])]
2045 "TARGET_64BIT"
2046 {
2047 rtx mem = operands[1];
2048 rtx addr = XEXP (mem, 0);
2049
2050 emit_move_insn (operands[2], addr);
2051 mem = replace_equiv_address_nv (mem, operands[2]);
2052
2053 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2054 DONE;
2055 })
2056
2057 ;; Convert impossible stores of immediate to existing instructions.
2058 ;; First try to get scratch register and go through it. In case this
2059 ;; fails, move by 32bit parts.
2060 (define_peephole2
2061 [(match_scratch:DI 2 "r")
2062 (set (match_operand:DI 0 "memory_operand" "")
2063 (match_operand:DI 1 "immediate_operand" ""))]
2064 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2065 && !x86_64_immediate_operand (operands[1], DImode)"
2066 [(set (match_dup 2) (match_dup 1))
2067 (set (match_dup 0) (match_dup 2))])
2068
2069 ;; We need to define this as both peepholer and splitter for case
2070 ;; peephole2 pass is not run.
2071 ;; "&& 1" is needed to keep it from matching the previous pattern.
2072 (define_peephole2
2073 [(set (match_operand:DI 0 "memory_operand" "")
2074 (match_operand:DI 1 "immediate_operand" ""))]
2075 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2076 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2077 [(set (match_dup 2) (match_dup 3))
2078 (set (match_dup 4) (match_dup 5))]
2079 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2080
2081 (define_split
2082 [(set (match_operand:DI 0 "memory_operand" "")
2083 (match_operand:DI 1 "immediate_operand" ""))]
2084 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2085 ? epilogue_completed : reload_completed)
2086 && !symbolic_operand (operands[1], DImode)
2087 && !x86_64_immediate_operand (operands[1], DImode)"
2088 [(set (match_dup 2) (match_dup 3))
2089 (set (match_dup 4) (match_dup 5))]
2090 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2091
2092 (define_insn "*movdi_internal"
2093 [(set (match_operand:DI 0 "nonimmediate_operand"
2094 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2095 (match_operand:DI 1 "general_operand"
2096 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2097 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2098 {
2099 switch (get_attr_type (insn))
2100 {
2101 case TYPE_SSECVT:
2102 if (SSE_REG_P (operands[0]))
2103 return "movq2dq\t{%1, %0|%0, %1}";
2104 else
2105 return "movdq2q\t{%1, %0|%0, %1}";
2106
2107 case TYPE_SSEMOV:
2108 switch (get_attr_mode (insn))
2109 {
2110 case MODE_TI:
2111 return "%vmovdqa\t{%1, %0|%0, %1}";
2112 case MODE_DI:
2113 return "%vmovq\t{%1, %0|%0, %1}";
2114 case MODE_V4SF:
2115 return "movaps\t{%1, %0|%0, %1}";
2116 case MODE_V2SF:
2117 return "movlps\t{%1, %0|%0, %1}";
2118 default:
2119 gcc_unreachable ();
2120 }
2121
2122 case TYPE_MMXMOV:
2123 return "movq\t{%1, %0|%0, %1}";
2124
2125 case TYPE_SSELOG1:
2126 return standard_sse_constant_opcode (insn, operands[1]);
2127
2128 case TYPE_MMX:
2129 return "pxor\t%0, %0";
2130
2131 case TYPE_MULTI:
2132 return "#";
2133
2134 default:
2135 gcc_unreachable ();
2136 }
2137 }
2138 [(set (attr "isa")
2139 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2140 (const_string "sse2")
2141 (eq_attr "alternative" "9,10,11,12")
2142 (const_string "noavx")
2143 ]
2144 (const_string "*")))
2145 (set (attr "type")
2146 (cond [(eq_attr "alternative" "0,1")
2147 (const_string "multi")
2148 (eq_attr "alternative" "2")
2149 (const_string "mmx")
2150 (eq_attr "alternative" "3,4")
2151 (const_string "mmxmov")
2152 (eq_attr "alternative" "5,9")
2153 (const_string "sselog1")
2154 (eq_attr "alternative" "13,14")
2155 (const_string "ssecvt")
2156 ]
2157 (const_string "ssemov")))
2158 (set (attr "prefix")
2159 (if_then_else (eq_attr "alternative" "5,6,7,8")
2160 (const_string "maybe_vex")
2161 (const_string "orig")))
2162 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2163
2164 (define_split
2165 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2166 (match_operand:DI 1 "general_operand" ""))]
2167 "!TARGET_64BIT && reload_completed
2168 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2169 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2170 [(const_int 0)]
2171 "ix86_split_long_move (operands); DONE;")
2172
2173 (define_insn "*movsi_internal"
2174 [(set (match_operand:SI 0 "nonimmediate_operand"
2175 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2176 (match_operand:SI 1 "general_operand"
2177 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2178 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2179 {
2180 switch (get_attr_type (insn))
2181 {
2182 case TYPE_SSELOG1:
2183 return standard_sse_constant_opcode (insn, operands[1]);
2184
2185 case TYPE_SSEMOV:
2186 switch (get_attr_mode (insn))
2187 {
2188 case MODE_TI:
2189 return "%vmovdqa\t{%1, %0|%0, %1}";
2190 case MODE_V4SF:
2191 return "%vmovaps\t{%1, %0|%0, %1}";
2192 case MODE_SI:
2193 return "%vmovd\t{%1, %0|%0, %1}";
2194 case MODE_SF:
2195 return "%vmovss\t{%1, %0|%0, %1}";
2196 default:
2197 gcc_unreachable ();
2198 }
2199
2200 case TYPE_MMX:
2201 return "pxor\t%0, %0";
2202
2203 case TYPE_MMXMOV:
2204 if (get_attr_mode (insn) == MODE_DI)
2205 return "movq\t{%1, %0|%0, %1}";
2206 return "movd\t{%1, %0|%0, %1}";
2207
2208 case TYPE_LEA:
2209 return "lea{l}\t{%a1, %0|%0, %a1}";
2210
2211 default:
2212 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2213 if (ix86_use_lea_for_mov (insn, operands))
2214 return "lea{l}\t{%a1, %0|%0, %a1}";
2215 else
2216 return "mov{l}\t{%1, %0|%0, %1}";
2217 }
2218 }
2219 [(set (attr "type")
2220 (cond [(eq_attr "alternative" "2")
2221 (const_string "mmx")
2222 (eq_attr "alternative" "3,4,5")
2223 (const_string "mmxmov")
2224 (eq_attr "alternative" "6")
2225 (const_string "sselog1")
2226 (eq_attr "alternative" "7,8,9,10,11")
2227 (const_string "ssemov")
2228 (match_operand 1 "pic_32bit_operand" "")
2229 (const_string "lea")
2230 ]
2231 (const_string "imov")))
2232 (set (attr "prefix")
2233 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2234 (const_string "orig")
2235 (const_string "maybe_vex")))
2236 (set (attr "prefix_data16")
2237 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2238 (const_string "1")
2239 (const_string "*")))
2240 (set (attr "mode")
2241 (cond [(eq_attr "alternative" "2,3")
2242 (const_string "DI")
2243 (eq_attr "alternative" "6,7")
2244 (if_then_else
2245 (not (match_test "TARGET_SSE2"))
2246 (const_string "V4SF")
2247 (const_string "TI"))
2248 (and (eq_attr "alternative" "8,9,10,11")
2249 (not (match_test "TARGET_SSE2")))
2250 (const_string "SF")
2251 ]
2252 (const_string "SI")))])
2253
2254 (define_insn "*movhi_internal"
2255 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2256 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2257 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2258 {
2259 switch (get_attr_type (insn))
2260 {
2261 case TYPE_IMOVX:
2262 /* movzwl is faster than movw on p2 due to partial word stalls,
2263 though not as fast as an aligned movl. */
2264 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2265 default:
2266 if (get_attr_mode (insn) == MODE_SI)
2267 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2268 else
2269 return "mov{w}\t{%1, %0|%0, %1}";
2270 }
2271 }
2272 [(set (attr "type")
2273 (cond [(match_test "optimize_function_for_size_p (cfun)")
2274 (const_string "imov")
2275 (and (eq_attr "alternative" "0")
2276 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2277 (not (match_test "TARGET_HIMODE_MATH"))))
2278 (const_string "imov")
2279 (and (eq_attr "alternative" "1,2")
2280 (match_operand:HI 1 "aligned_operand" ""))
2281 (const_string "imov")
2282 (and (match_test "TARGET_MOVX")
2283 (eq_attr "alternative" "0,2"))
2284 (const_string "imovx")
2285 ]
2286 (const_string "imov")))
2287 (set (attr "mode")
2288 (cond [(eq_attr "type" "imovx")
2289 (const_string "SI")
2290 (and (eq_attr "alternative" "1,2")
2291 (match_operand:HI 1 "aligned_operand" ""))
2292 (const_string "SI")
2293 (and (eq_attr "alternative" "0")
2294 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2295 (not (match_test "TARGET_HIMODE_MATH"))))
2296 (const_string "SI")
2297 ]
2298 (const_string "HI")))])
2299
2300 ;; Situation is quite tricky about when to choose full sized (SImode) move
2301 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2302 ;; partial register dependency machines (such as AMD Athlon), where QImode
2303 ;; moves issue extra dependency and for partial register stalls machines
2304 ;; that don't use QImode patterns (and QImode move cause stall on the next
2305 ;; instruction).
2306 ;;
2307 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2308 ;; register stall machines with, where we use QImode instructions, since
2309 ;; partial register stall can be caused there. Then we use movzx.
2310 (define_insn "*movqi_internal"
2311 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2312 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2313 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2314 {
2315 switch (get_attr_type (insn))
2316 {
2317 case TYPE_IMOVX:
2318 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2319 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2320 default:
2321 if (get_attr_mode (insn) == MODE_SI)
2322 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2323 else
2324 return "mov{b}\t{%1, %0|%0, %1}";
2325 }
2326 }
2327 [(set (attr "type")
2328 (cond [(and (eq_attr "alternative" "5")
2329 (not (match_operand:QI 1 "aligned_operand" "")))
2330 (const_string "imovx")
2331 (match_test "optimize_function_for_size_p (cfun)")
2332 (const_string "imov")
2333 (and (eq_attr "alternative" "3")
2334 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2335 (not (match_test "TARGET_QIMODE_MATH"))))
2336 (const_string "imov")
2337 (eq_attr "alternative" "3,5")
2338 (const_string "imovx")
2339 (and (match_test "TARGET_MOVX")
2340 (eq_attr "alternative" "2"))
2341 (const_string "imovx")
2342 ]
2343 (const_string "imov")))
2344 (set (attr "mode")
2345 (cond [(eq_attr "alternative" "3,4,5")
2346 (const_string "SI")
2347 (eq_attr "alternative" "6")
2348 (const_string "QI")
2349 (eq_attr "type" "imovx")
2350 (const_string "SI")
2351 (and (eq_attr "type" "imov")
2352 (and (eq_attr "alternative" "0,1")
2353 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2354 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2355 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2356 (const_string "SI")
2357 ;; Avoid partial register stalls when not using QImode arithmetic
2358 (and (eq_attr "type" "imov")
2359 (and (eq_attr "alternative" "0,1")
2360 (and (match_test "TARGET_PARTIAL_REG_STALL")
2361 (not (match_test "TARGET_QIMODE_MATH")))))
2362 (const_string "SI")
2363 ]
2364 (const_string "QI")))])
2365
2366 ;; Stores and loads of ax to arbitrary constant address.
2367 ;; We fake an second form of instruction to force reload to load address
2368 ;; into register when rax is not available
2369 (define_insn "*movabs<mode>_1"
2370 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2371 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2372 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2373 "@
2374 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2375 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2376 [(set_attr "type" "imov")
2377 (set_attr "modrm" "0,*")
2378 (set_attr "length_address" "8,0")
2379 (set_attr "length_immediate" "0,*")
2380 (set_attr "memory" "store")
2381 (set_attr "mode" "<MODE>")])
2382
2383 (define_insn "*movabs<mode>_2"
2384 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2385 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2386 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2387 "@
2388 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2389 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2390 [(set_attr "type" "imov")
2391 (set_attr "modrm" "0,*")
2392 (set_attr "length_address" "8,0")
2393 (set_attr "length_immediate" "0")
2394 (set_attr "memory" "load")
2395 (set_attr "mode" "<MODE>")])
2396
2397 (define_insn "*swap<mode>"
2398 [(set (match_operand:SWI48 0 "register_operand" "+r")
2399 (match_operand:SWI48 1 "register_operand" "+r"))
2400 (set (match_dup 1)
2401 (match_dup 0))]
2402 ""
2403 "xchg{<imodesuffix>}\t%1, %0"
2404 [(set_attr "type" "imov")
2405 (set_attr "mode" "<MODE>")
2406 (set_attr "pent_pair" "np")
2407 (set_attr "athlon_decode" "vector")
2408 (set_attr "amdfam10_decode" "double")
2409 (set_attr "bdver1_decode" "double")])
2410
2411 (define_insn "*swap<mode>_1"
2412 [(set (match_operand:SWI12 0 "register_operand" "+r")
2413 (match_operand:SWI12 1 "register_operand" "+r"))
2414 (set (match_dup 1)
2415 (match_dup 0))]
2416 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2417 "xchg{l}\t%k1, %k0"
2418 [(set_attr "type" "imov")
2419 (set_attr "mode" "SI")
2420 (set_attr "pent_pair" "np")
2421 (set_attr "athlon_decode" "vector")
2422 (set_attr "amdfam10_decode" "double")
2423 (set_attr "bdver1_decode" "double")])
2424
2425 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2426 ;; is disabled for AMDFAM10
2427 (define_insn "*swap<mode>_2"
2428 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2429 (match_operand:SWI12 1 "register_operand" "+<r>"))
2430 (set (match_dup 1)
2431 (match_dup 0))]
2432 "TARGET_PARTIAL_REG_STALL"
2433 "xchg{<imodesuffix>}\t%1, %0"
2434 [(set_attr "type" "imov")
2435 (set_attr "mode" "<MODE>")
2436 (set_attr "pent_pair" "np")
2437 (set_attr "athlon_decode" "vector")])
2438
2439 (define_expand "movstrict<mode>"
2440 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2441 (match_operand:SWI12 1 "general_operand" ""))]
2442 ""
2443 {
2444 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2445 FAIL;
2446 if (GET_CODE (operands[0]) == SUBREG
2447 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2448 FAIL;
2449 /* Don't generate memory->memory moves, go through a register */
2450 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2451 operands[1] = force_reg (<MODE>mode, operands[1]);
2452 })
2453
2454 (define_insn "*movstrict<mode>_1"
2455 [(set (strict_low_part
2456 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2457 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2458 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2459 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2460 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2461 [(set_attr "type" "imov")
2462 (set_attr "mode" "<MODE>")])
2463
2464 (define_insn "*movstrict<mode>_xor"
2465 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2466 (match_operand:SWI12 1 "const0_operand" ""))
2467 (clobber (reg:CC FLAGS_REG))]
2468 "reload_completed"
2469 "xor{<imodesuffix>}\t%0, %0"
2470 [(set_attr "type" "alu1")
2471 (set_attr "mode" "<MODE>")
2472 (set_attr "length_immediate" "0")])
2473
2474 (define_insn "*mov<mode>_extv_1"
2475 [(set (match_operand:SWI24 0 "register_operand" "=R")
2476 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2477 (const_int 8)
2478 (const_int 8)))]
2479 ""
2480 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2481 [(set_attr "type" "imovx")
2482 (set_attr "mode" "SI")])
2483
2484 (define_insn "*movqi_extv_1_rex64"
2485 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2486 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2487 (const_int 8)
2488 (const_int 8)))]
2489 "TARGET_64BIT"
2490 {
2491 switch (get_attr_type (insn))
2492 {
2493 case TYPE_IMOVX:
2494 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2495 default:
2496 return "mov{b}\t{%h1, %0|%0, %h1}";
2497 }
2498 }
2499 [(set (attr "type")
2500 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2501 (match_test "TARGET_MOVX"))
2502 (const_string "imovx")
2503 (const_string "imov")))
2504 (set (attr "mode")
2505 (if_then_else (eq_attr "type" "imovx")
2506 (const_string "SI")
2507 (const_string "QI")))])
2508
2509 (define_insn "*movqi_extv_1"
2510 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2511 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2512 (const_int 8)
2513 (const_int 8)))]
2514 "!TARGET_64BIT"
2515 {
2516 switch (get_attr_type (insn))
2517 {
2518 case TYPE_IMOVX:
2519 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2520 default:
2521 return "mov{b}\t{%h1, %0|%0, %h1}";
2522 }
2523 }
2524 [(set (attr "type")
2525 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2526 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2527 (match_test "TARGET_MOVX")))
2528 (const_string "imovx")
2529 (const_string "imov")))
2530 (set (attr "mode")
2531 (if_then_else (eq_attr "type" "imovx")
2532 (const_string "SI")
2533 (const_string "QI")))])
2534
2535 (define_insn "*mov<mode>_extzv_1"
2536 [(set (match_operand:SWI48 0 "register_operand" "=R")
2537 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2538 (const_int 8)
2539 (const_int 8)))]
2540 ""
2541 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2542 [(set_attr "type" "imovx")
2543 (set_attr "mode" "SI")])
2544
2545 (define_insn "*movqi_extzv_2_rex64"
2546 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2547 (subreg:QI
2548 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2549 (const_int 8)
2550 (const_int 8)) 0))]
2551 "TARGET_64BIT"
2552 {
2553 switch (get_attr_type (insn))
2554 {
2555 case TYPE_IMOVX:
2556 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2557 default:
2558 return "mov{b}\t{%h1, %0|%0, %h1}";
2559 }
2560 }
2561 [(set (attr "type")
2562 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2563 (match_test "TARGET_MOVX"))
2564 (const_string "imovx")
2565 (const_string "imov")))
2566 (set (attr "mode")
2567 (if_then_else (eq_attr "type" "imovx")
2568 (const_string "SI")
2569 (const_string "QI")))])
2570
2571 (define_insn "*movqi_extzv_2"
2572 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2573 (subreg:QI
2574 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2575 (const_int 8)
2576 (const_int 8)) 0))]
2577 "!TARGET_64BIT"
2578 {
2579 switch (get_attr_type (insn))
2580 {
2581 case TYPE_IMOVX:
2582 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2583 default:
2584 return "mov{b}\t{%h1, %0|%0, %h1}";
2585 }
2586 }
2587 [(set (attr "type")
2588 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2589 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2590 (match_test "TARGET_MOVX")))
2591 (const_string "imovx")
2592 (const_string "imov")))
2593 (set (attr "mode")
2594 (if_then_else (eq_attr "type" "imovx")
2595 (const_string "SI")
2596 (const_string "QI")))])
2597
2598 (define_expand "mov<mode>_insv_1"
2599 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2600 (const_int 8)
2601 (const_int 8))
2602 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2603
2604 (define_insn "*mov<mode>_insv_1_rex64"
2605 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2606 (const_int 8)
2607 (const_int 8))
2608 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2609 "TARGET_64BIT"
2610 "mov{b}\t{%b1, %h0|%h0, %b1}"
2611 [(set_attr "type" "imov")
2612 (set_attr "mode" "QI")])
2613
2614 (define_insn "*movsi_insv_1"
2615 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2616 (const_int 8)
2617 (const_int 8))
2618 (match_operand:SI 1 "general_operand" "Qmn"))]
2619 "!TARGET_64BIT"
2620 "mov{b}\t{%b1, %h0|%h0, %b1}"
2621 [(set_attr "type" "imov")
2622 (set_attr "mode" "QI")])
2623
2624 (define_insn "*movqi_insv_2"
2625 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2626 (const_int 8)
2627 (const_int 8))
2628 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2629 (const_int 8)))]
2630 ""
2631 "mov{b}\t{%h1, %h0|%h0, %h1}"
2632 [(set_attr "type" "imov")
2633 (set_attr "mode" "QI")])
2634 \f
2635 ;; Floating point push instructions.
2636
2637 (define_insn "*pushtf"
2638 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2639 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2640 "TARGET_SSE2"
2641 {
2642 /* This insn should be already split before reg-stack. */
2643 gcc_unreachable ();
2644 }
2645 [(set_attr "type" "multi")
2646 (set_attr "unit" "sse,*,*")
2647 (set_attr "mode" "TF,SI,SI")])
2648
2649 ;; %%% Kill this when call knows how to work this out.
2650 (define_split
2651 [(set (match_operand:TF 0 "push_operand" "")
2652 (match_operand:TF 1 "sse_reg_operand" ""))]
2653 "TARGET_SSE2 && reload_completed"
2654 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2655 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2656
2657 (define_insn "*pushxf"
2658 [(set (match_operand:XF 0 "push_operand" "=<,<")
2659 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2660 "optimize_function_for_speed_p (cfun)"
2661 {
2662 /* This insn should be already split before reg-stack. */
2663 gcc_unreachable ();
2664 }
2665 [(set_attr "type" "multi")
2666 (set_attr "unit" "i387,*")
2667 (set_attr "mode" "XF,SI")])
2668
2669 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2670 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2671 ;; Pushing using integer instructions is longer except for constants
2672 ;; and direct memory references (assuming that any given constant is pushed
2673 ;; only once, but this ought to be handled elsewhere).
2674
2675 (define_insn "*pushxf_nointeger"
2676 [(set (match_operand:XF 0 "push_operand" "=<,<")
2677 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2678 "optimize_function_for_size_p (cfun)"
2679 {
2680 /* This insn should be already split before reg-stack. */
2681 gcc_unreachable ();
2682 }
2683 [(set_attr "type" "multi")
2684 (set_attr "unit" "i387,*")
2685 (set_attr "mode" "XF,SI")])
2686
2687 ;; %%% Kill this when call knows how to work this out.
2688 (define_split
2689 [(set (match_operand:XF 0 "push_operand" "")
2690 (match_operand:XF 1 "fp_register_operand" ""))]
2691 "reload_completed"
2692 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2693 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2694 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2695
2696 (define_insn "*pushdf_rex64"
2697 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2698 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2699 "TARGET_64BIT"
2700 {
2701 /* This insn should be already split before reg-stack. */
2702 gcc_unreachable ();
2703 }
2704 [(set_attr "type" "multi")
2705 (set_attr "unit" "i387,*,*")
2706 (set_attr "mode" "DF,DI,DF")])
2707
2708 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2709 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2710 ;; On the average, pushdf using integers can be still shorter.
2711
2712 (define_insn "*pushdf"
2713 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2714 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2715 "!TARGET_64BIT"
2716 {
2717 /* This insn should be already split before reg-stack. */
2718 gcc_unreachable ();
2719 }
2720 [(set_attr "isa" "*,*,sse2")
2721 (set_attr "type" "multi")
2722 (set_attr "unit" "i387,*,*")
2723 (set_attr "mode" "DF,DI,DF")])
2724
2725 ;; %%% Kill this when call knows how to work this out.
2726 (define_split
2727 [(set (match_operand:DF 0 "push_operand" "")
2728 (match_operand:DF 1 "any_fp_register_operand" ""))]
2729 "reload_completed"
2730 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2731 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2732
2733 (define_insn "*pushsf_rex64"
2734 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2735 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2736 "TARGET_64BIT"
2737 {
2738 /* Anything else should be already split before reg-stack. */
2739 gcc_assert (which_alternative == 1);
2740 return "push{q}\t%q1";
2741 }
2742 [(set_attr "type" "multi,push,multi")
2743 (set_attr "unit" "i387,*,*")
2744 (set_attr "mode" "SF,DI,SF")])
2745
2746 (define_insn "*pushsf"
2747 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2748 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2749 "!TARGET_64BIT"
2750 {
2751 /* Anything else should be already split before reg-stack. */
2752 gcc_assert (which_alternative == 1);
2753 return "push{l}\t%1";
2754 }
2755 [(set_attr "type" "multi,push,multi")
2756 (set_attr "unit" "i387,*,*")
2757 (set_attr "mode" "SF,SI,SF")])
2758
2759 ;; %%% Kill this when call knows how to work this out.
2760 (define_split
2761 [(set (match_operand:SF 0 "push_operand" "")
2762 (match_operand:SF 1 "any_fp_register_operand" ""))]
2763 "reload_completed"
2764 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2765 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2766 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2767
2768 (define_split
2769 [(set (match_operand:SF 0 "push_operand" "")
2770 (match_operand:SF 1 "memory_operand" ""))]
2771 "reload_completed
2772 && (operands[2] = find_constant_src (insn))"
2773 [(set (match_dup 0) (match_dup 2))])
2774
2775 (define_split
2776 [(set (match_operand 0 "push_operand" "")
2777 (match_operand 1 "general_operand" ""))]
2778 "reload_completed
2779 && (GET_MODE (operands[0]) == TFmode
2780 || GET_MODE (operands[0]) == XFmode
2781 || GET_MODE (operands[0]) == DFmode)
2782 && !ANY_FP_REG_P (operands[1])"
2783 [(const_int 0)]
2784 "ix86_split_long_move (operands); DONE;")
2785 \f
2786 ;; Floating point move instructions.
2787
2788 (define_expand "movtf"
2789 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2790 (match_operand:TF 1 "nonimmediate_operand" ""))]
2791 "TARGET_SSE2"
2792 {
2793 ix86_expand_move (TFmode, operands);
2794 DONE;
2795 })
2796
2797 (define_expand "mov<mode>"
2798 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2799 (match_operand:X87MODEF 1 "general_operand" ""))]
2800 ""
2801 "ix86_expand_move (<MODE>mode, operands); DONE;")
2802
2803 (define_insn "*movtf_internal"
2804 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2805 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2806 "TARGET_SSE2
2807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2808 && (!can_create_pseudo_p ()
2809 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2810 || GET_CODE (operands[1]) != CONST_DOUBLE
2811 || (optimize_function_for_size_p (cfun)
2812 && standard_sse_constant_p (operands[1])
2813 && !memory_operand (operands[0], TFmode))
2814 || (!TARGET_MEMORY_MISMATCH_STALL
2815 && memory_operand (operands[0], TFmode)))"
2816 {
2817 switch (which_alternative)
2818 {
2819 case 0:
2820 case 1:
2821 /* Handle misaligned load/store since we
2822 don't have movmisaligntf pattern. */
2823 if (misaligned_operand (operands[0], TFmode)
2824 || misaligned_operand (operands[1], TFmode))
2825 {
2826 if (get_attr_mode (insn) == MODE_V4SF)
2827 return "%vmovups\t{%1, %0|%0, %1}";
2828 else
2829 return "%vmovdqu\t{%1, %0|%0, %1}";
2830 }
2831 else
2832 {
2833 if (get_attr_mode (insn) == MODE_V4SF)
2834 return "%vmovaps\t{%1, %0|%0, %1}";
2835 else
2836 return "%vmovdqa\t{%1, %0|%0, %1}";
2837 }
2838
2839 case 2:
2840 return standard_sse_constant_opcode (insn, operands[1]);
2841
2842 case 3:
2843 case 4:
2844 return "#";
2845
2846 default:
2847 gcc_unreachable ();
2848 }
2849 }
2850 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2851 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2852 (set (attr "mode")
2853 (cond [(eq_attr "alternative" "0,2")
2854 (if_then_else
2855 (match_test "optimize_function_for_size_p (cfun)")
2856 (const_string "V4SF")
2857 (const_string "TI"))
2858 (eq_attr "alternative" "1")
2859 (if_then_else
2860 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2861 (match_test "optimize_function_for_size_p (cfun)"))
2862 (const_string "V4SF")
2863 (const_string "TI"))]
2864 (const_string "DI")))])
2865
2866 ;; Possible store forwarding (partial memory) stall in alternative 4.
2867 (define_insn "*movxf_internal"
2868 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2869 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2870 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && (!can_create_pseudo_p ()
2872 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2873 || GET_CODE (operands[1]) != CONST_DOUBLE
2874 || (optimize_function_for_size_p (cfun)
2875 && standard_80387_constant_p (operands[1]) > 0
2876 && !memory_operand (operands[0], XFmode))
2877 || (!TARGET_MEMORY_MISMATCH_STALL
2878 && memory_operand (operands[0], XFmode)))"
2879 {
2880 switch (which_alternative)
2881 {
2882 case 0:
2883 case 1:
2884 return output_387_reg_move (insn, operands);
2885
2886 case 2:
2887 return standard_80387_constant_opcode (operands[1]);
2888
2889 case 3:
2890 case 4:
2891 return "#";
2892
2893 default:
2894 gcc_unreachable ();
2895 }
2896 }
2897 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2898 (set_attr "mode" "XF,XF,XF,SI,SI")])
2899
2900 (define_insn "*movdf_internal_rex64"
2901 [(set (match_operand:DF 0 "nonimmediate_operand"
2902 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2903 (match_operand:DF 1 "general_operand"
2904 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2905 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2906 && (!can_create_pseudo_p ()
2907 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2908 || GET_CODE (operands[1]) != CONST_DOUBLE
2909 || (optimize_function_for_size_p (cfun)
2910 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2911 && standard_80387_constant_p (operands[1]) > 0)
2912 || (TARGET_SSE2 && TARGET_SSE_MATH
2913 && standard_sse_constant_p (operands[1]))))
2914 || memory_operand (operands[0], DFmode))"
2915 {
2916 switch (which_alternative)
2917 {
2918 case 0:
2919 case 1:
2920 return output_387_reg_move (insn, operands);
2921
2922 case 2:
2923 return standard_80387_constant_opcode (operands[1]);
2924
2925 case 3:
2926 case 4:
2927 return "mov{q}\t{%1, %0|%0, %1}";
2928
2929 case 5:
2930 return "movabs{q}\t{%1, %0|%0, %1}";
2931
2932 case 6:
2933 return "#";
2934
2935 case 7:
2936 return standard_sse_constant_opcode (insn, operands[1]);
2937
2938 case 8:
2939 case 9:
2940 case 10:
2941 switch (get_attr_mode (insn))
2942 {
2943 case MODE_V2DF:
2944 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2945 return "%vmovapd\t{%1, %0|%0, %1}";
2946 case MODE_V4SF:
2947 return "%vmovaps\t{%1, %0|%0, %1}";
2948
2949 case MODE_DI:
2950 return "%vmovq\t{%1, %0|%0, %1}";
2951 case MODE_DF:
2952 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2953 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2954 return "%vmovsd\t{%1, %0|%0, %1}";
2955 case MODE_V1DF:
2956 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2957 case MODE_V2SF:
2958 return "%vmovlps\t{%1, %d0|%d0, %1}";
2959 default:
2960 gcc_unreachable ();
2961 }
2962
2963 case 11:
2964 case 12:
2965 /* Handle broken assemblers that require movd instead of movq. */
2966 return "%vmovd\t{%1, %0|%0, %1}";
2967
2968 default:
2969 gcc_unreachable();
2970 }
2971 }
2972 [(set (attr "type")
2973 (cond [(eq_attr "alternative" "0,1,2")
2974 (const_string "fmov")
2975 (eq_attr "alternative" "3,4,5")
2976 (const_string "imov")
2977 (eq_attr "alternative" "6")
2978 (const_string "multi")
2979 (eq_attr "alternative" "7")
2980 (const_string "sselog1")
2981 ]
2982 (const_string "ssemov")))
2983 (set (attr "modrm")
2984 (if_then_else
2985 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2986 (const_string "0")
2987 (const_string "*")))
2988 (set (attr "length_immediate")
2989 (if_then_else
2990 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2991 (const_string "8")
2992 (const_string "*")))
2993 (set (attr "prefix")
2994 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2995 (const_string "orig")
2996 (const_string "maybe_vex")))
2997 (set (attr "prefix_data16")
2998 (if_then_else (eq_attr "mode" "V1DF")
2999 (const_string "1")
3000 (const_string "*")))
3001 (set (attr "mode")
3002 (cond [(eq_attr "alternative" "0,1,2")
3003 (const_string "DF")
3004 (eq_attr "alternative" "3,4,5,6,11,12")
3005 (const_string "DI")
3006
3007 /* xorps is one byte shorter. */
3008 (eq_attr "alternative" "7")
3009 (cond [(match_test "optimize_function_for_size_p (cfun)")
3010 (const_string "V4SF")
3011 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3012 (const_string "TI")
3013 ]
3014 (const_string "V2DF"))
3015
3016 /* For architectures resolving dependencies on
3017 whole SSE registers use APD move to break dependency
3018 chains, otherwise use short move to avoid extra work.
3019
3020 movaps encodes one byte shorter. */
3021 (eq_attr "alternative" "8")
3022 (cond
3023 [(match_test "optimize_function_for_size_p (cfun)")
3024 (const_string "V4SF")
3025 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3026 (const_string "V2DF")
3027 ]
3028 (const_string "DF"))
3029 /* For architectures resolving dependencies on register
3030 parts we may avoid extra work to zero out upper part
3031 of register. */
3032 (eq_attr "alternative" "9")
3033 (if_then_else
3034 (match_test "TARGET_SSE_SPLIT_REGS")
3035 (const_string "V1DF")
3036 (const_string "DF"))
3037 ]
3038 (const_string "DF")))])
3039
3040 ;; Possible store forwarding (partial memory) stall in alternative 4.
3041 (define_insn "*movdf_internal"
3042 [(set (match_operand:DF 0 "nonimmediate_operand"
3043 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3044 (match_operand:DF 1 "general_operand"
3045 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3046 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3047 && (!can_create_pseudo_p ()
3048 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3049 || GET_CODE (operands[1]) != CONST_DOUBLE
3050 || (optimize_function_for_size_p (cfun)
3051 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3052 && standard_80387_constant_p (operands[1]) > 0)
3053 || (TARGET_SSE2 && TARGET_SSE_MATH
3054 && standard_sse_constant_p (operands[1])))
3055 && !memory_operand (operands[0], DFmode))
3056 || (!TARGET_MEMORY_MISMATCH_STALL
3057 && memory_operand (operands[0], DFmode)))"
3058 {
3059 switch (which_alternative)
3060 {
3061 case 0:
3062 case 1:
3063 return output_387_reg_move (insn, operands);
3064
3065 case 2:
3066 return standard_80387_constant_opcode (operands[1]);
3067
3068 case 3:
3069 case 4:
3070 return "#";
3071
3072 case 5:
3073 case 9:
3074 return standard_sse_constant_opcode (insn, operands[1]);
3075
3076 case 6:
3077 case 7:
3078 case 8:
3079 case 10:
3080 case 11:
3081 case 12:
3082 switch (get_attr_mode (insn))
3083 {
3084 case MODE_V2DF:
3085 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3086 return "%vmovapd\t{%1, %0|%0, %1}";
3087 case MODE_V4SF:
3088 return "%vmovaps\t{%1, %0|%0, %1}";
3089
3090 case MODE_DI:
3091 return "%vmovq\t{%1, %0|%0, %1}";
3092 case MODE_DF:
3093 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3094 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3095 return "%vmovsd\t{%1, %0|%0, %1}";
3096 case MODE_V1DF:
3097 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3098 case MODE_V2SF:
3099 return "%vmovlps\t{%1, %d0|%d0, %1}";
3100 default:
3101 gcc_unreachable ();
3102 }
3103
3104 default:
3105 gcc_unreachable ();
3106 }
3107 }
3108 [(set (attr "isa")
3109 (if_then_else (eq_attr "alternative" "5,6,7,8")
3110 (const_string "sse2")
3111 (const_string "*")))
3112 (set (attr "type")
3113 (cond [(eq_attr "alternative" "0,1,2")
3114 (const_string "fmov")
3115 (eq_attr "alternative" "3,4")
3116 (const_string "multi")
3117 (eq_attr "alternative" "5,9")
3118 (const_string "sselog1")
3119 ]
3120 (const_string "ssemov")))
3121 (set (attr "prefix")
3122 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3123 (const_string "orig")
3124 (const_string "maybe_vex")))
3125 (set (attr "prefix_data16")
3126 (if_then_else (eq_attr "mode" "V1DF")
3127 (const_string "1")
3128 (const_string "*")))
3129 (set (attr "mode")
3130 (cond [(eq_attr "alternative" "0,1,2")
3131 (const_string "DF")
3132 (eq_attr "alternative" "3,4")
3133 (const_string "SI")
3134
3135 /* For SSE1, we have many fewer alternatives. */
3136 (not (match_test "TARGET_SSE2"))
3137 (if_then_else
3138 (eq_attr "alternative" "5,6,9,10")
3139 (const_string "V4SF")
3140 (const_string "V2SF"))
3141
3142 /* xorps is one byte shorter. */
3143 (eq_attr "alternative" "5,9")
3144 (cond [(match_test "optimize_function_for_size_p (cfun)")
3145 (const_string "V4SF")
3146 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3147 (const_string "TI")
3148 ]
3149 (const_string "V2DF"))
3150
3151 /* For architectures resolving dependencies on
3152 whole SSE registers use APD move to break dependency
3153 chains, otherwise use short move to avoid extra work.
3154
3155 movaps encodes one byte shorter. */
3156 (eq_attr "alternative" "6,10")
3157 (cond
3158 [(match_test "optimize_function_for_size_p (cfun)")
3159 (const_string "V4SF")
3160 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3161 (const_string "V2DF")
3162 ]
3163 (const_string "DF"))
3164 /* For architectures resolving dependencies on register
3165 parts we may avoid extra work to zero out upper part
3166 of register. */
3167 (eq_attr "alternative" "7,11")
3168 (if_then_else
3169 (match_test "TARGET_SSE_SPLIT_REGS")
3170 (const_string "V1DF")
3171 (const_string "DF"))
3172 ]
3173 (const_string "DF")))])
3174
3175 (define_insn "*movsf_internal"
3176 [(set (match_operand:SF 0 "nonimmediate_operand"
3177 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3178 (match_operand:SF 1 "general_operand"
3179 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (!can_create_pseudo_p ()
3182 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183 || GET_CODE (operands[1]) != CONST_DOUBLE
3184 || (optimize_function_for_size_p (cfun)
3185 && ((!TARGET_SSE_MATH
3186 && standard_80387_constant_p (operands[1]) > 0)
3187 || (TARGET_SSE_MATH
3188 && standard_sse_constant_p (operands[1]))))
3189 || memory_operand (operands[0], SFmode))"
3190 {
3191 switch (which_alternative)
3192 {
3193 case 0:
3194 case 1:
3195 return output_387_reg_move (insn, operands);
3196
3197 case 2:
3198 return standard_80387_constant_opcode (operands[1]);
3199
3200 case 3:
3201 case 4:
3202 return "mov{l}\t{%1, %0|%0, %1}";
3203
3204 case 5:
3205 return standard_sse_constant_opcode (insn, operands[1]);
3206
3207 case 6:
3208 if (get_attr_mode (insn) == MODE_V4SF)
3209 return "%vmovaps\t{%1, %0|%0, %1}";
3210 if (TARGET_AVX)
3211 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3212
3213 case 7:
3214 case 8:
3215 return "%vmovss\t{%1, %0|%0, %1}";
3216
3217 case 9:
3218 case 10:
3219 case 14:
3220 case 15:
3221 return "movd\t{%1, %0|%0, %1}";
3222
3223 case 11:
3224 return "movq\t{%1, %0|%0, %1}";
3225
3226 case 12:
3227 case 13:
3228 return "%vmovd\t{%1, %0|%0, %1}";
3229
3230 default:
3231 gcc_unreachable ();
3232 }
3233 }
3234 [(set (attr "type")
3235 (cond [(eq_attr "alternative" "0,1,2")
3236 (const_string "fmov")
3237 (eq_attr "alternative" "3,4")
3238 (const_string "multi")
3239 (eq_attr "alternative" "5")
3240 (const_string "sselog1")
3241 (eq_attr "alternative" "9,10,11,14,15")
3242 (const_string "mmxmov")
3243 ]
3244 (const_string "ssemov")))
3245 (set (attr "prefix")
3246 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3247 (const_string "maybe_vex")
3248 (const_string "orig")))
3249 (set (attr "mode")
3250 (cond [(eq_attr "alternative" "3,4,9,10")
3251 (const_string "SI")
3252 (eq_attr "alternative" "5")
3253 (if_then_else
3254 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3255 (match_test "TARGET_SSE2"))
3256 (not (match_test "optimize_function_for_size_p (cfun)")))
3257 (const_string "TI")
3258 (const_string "V4SF"))
3259 /* For architectures resolving dependencies on
3260 whole SSE registers use APS move to break dependency
3261 chains, otherwise use short move to avoid extra work.
3262
3263 Do the same for architectures resolving dependencies on
3264 the parts. While in DF mode it is better to always handle
3265 just register parts, the SF mode is different due to lack
3266 of instructions to load just part of the register. It is
3267 better to maintain the whole registers in single format
3268 to avoid problems on using packed logical operations. */
3269 (eq_attr "alternative" "6")
3270 (if_then_else
3271 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3272 (match_test "TARGET_SSE_SPLIT_REGS"))
3273 (const_string "V4SF")
3274 (const_string "SF"))
3275 (eq_attr "alternative" "11")
3276 (const_string "DI")]
3277 (const_string "SF")))])
3278
3279 (define_split
3280 [(set (match_operand 0 "any_fp_register_operand" "")
3281 (match_operand 1 "memory_operand" ""))]
3282 "reload_completed
3283 && (GET_MODE (operands[0]) == TFmode
3284 || GET_MODE (operands[0]) == XFmode
3285 || GET_MODE (operands[0]) == DFmode
3286 || GET_MODE (operands[0]) == SFmode)
3287 && (operands[2] = find_constant_src (insn))"
3288 [(set (match_dup 0) (match_dup 2))]
3289 {
3290 rtx c = operands[2];
3291 int r = REGNO (operands[0]);
3292
3293 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3294 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3295 FAIL;
3296 })
3297
3298 (define_split
3299 [(set (match_operand 0 "any_fp_register_operand" "")
3300 (float_extend (match_operand 1 "memory_operand" "")))]
3301 "reload_completed
3302 && (GET_MODE (operands[0]) == TFmode
3303 || GET_MODE (operands[0]) == XFmode
3304 || GET_MODE (operands[0]) == DFmode)
3305 && (operands[2] = find_constant_src (insn))"
3306 [(set (match_dup 0) (match_dup 2))]
3307 {
3308 rtx c = operands[2];
3309 int r = REGNO (operands[0]);
3310
3311 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3312 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3313 FAIL;
3314 })
3315
3316 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3317 (define_split
3318 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3319 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3320 "reload_completed
3321 && (standard_80387_constant_p (operands[1]) == 8
3322 || standard_80387_constant_p (operands[1]) == 9)"
3323 [(set (match_dup 0)(match_dup 1))
3324 (set (match_dup 0)
3325 (neg:X87MODEF (match_dup 0)))]
3326 {
3327 REAL_VALUE_TYPE r;
3328
3329 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3330 if (real_isnegzero (&r))
3331 operands[1] = CONST0_RTX (<MODE>mode);
3332 else
3333 operands[1] = CONST1_RTX (<MODE>mode);
3334 })
3335
3336 (define_split
3337 [(set (match_operand 0 "nonimmediate_operand" "")
3338 (match_operand 1 "general_operand" ""))]
3339 "reload_completed
3340 && (GET_MODE (operands[0]) == TFmode
3341 || GET_MODE (operands[0]) == XFmode
3342 || GET_MODE (operands[0]) == DFmode)
3343 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3344 [(const_int 0)]
3345 "ix86_split_long_move (operands); DONE;")
3346
3347 (define_insn "swapxf"
3348 [(set (match_operand:XF 0 "register_operand" "+f")
3349 (match_operand:XF 1 "register_operand" "+f"))
3350 (set (match_dup 1)
3351 (match_dup 0))]
3352 "TARGET_80387"
3353 {
3354 if (STACK_TOP_P (operands[0]))
3355 return "fxch\t%1";
3356 else
3357 return "fxch\t%0";
3358 }
3359 [(set_attr "type" "fxch")
3360 (set_attr "mode" "XF")])
3361
3362 (define_insn "*swap<mode>"
3363 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3364 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3365 (set (match_dup 1)
3366 (match_dup 0))]
3367 "TARGET_80387 || reload_completed"
3368 {
3369 if (STACK_TOP_P (operands[0]))
3370 return "fxch\t%1";
3371 else
3372 return "fxch\t%0";
3373 }
3374 [(set_attr "type" "fxch")
3375 (set_attr "mode" "<MODE>")])
3376 \f
3377 ;; Zero extension instructions
3378
3379 (define_expand "zero_extendsidi2"
3380 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3381 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))])
3382
3383 (define_insn "*zero_extendsidi2_rex64"
3384 [(set (match_operand:DI 0 "nonimmediate_operand"
3385 "=r ,o,?*Ym,?*y,?*Yi,!*x")
3386 (zero_extend:DI
3387 (match_operand:SI 1 "x86_64_zext_general_operand"
3388 "rmZ,0,r ,m ,r ,m*x")))]
3389 "TARGET_64BIT"
3390 "@
3391 mov{l}\t{%1, %k0|%k0, %1}
3392 #
3393 movd\t{%1, %0|%0, %1}
3394 movd\t{%1, %0|%0, %1}
3395 %vmovd\t{%1, %0|%0, %1}
3396 %vmovd\t{%1, %0|%0, %1}"
3397 [(set_attr "isa" "*,*,*,*,*,sse2")
3398 (set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3399 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3400 (set_attr "prefix_0f" "0,*,*,*,*,*")
3401 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3402
3403 (define_insn "*zero_extendsidi2"
3404 [(set (match_operand:DI 0 "nonimmediate_operand"
3405 "=ro,?r,?o,?*Ym,?*y,?*Yi,!*x")
3406 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3407 "0 ,rm,r ,r ,m ,r ,m*x")))]
3408 "!TARGET_64BIT"
3409 "@
3410 #
3411 #
3412 #
3413 movd\t{%1, %0|%0, %1}
3414 movd\t{%1, %0|%0, %1}
3415 %vmovd\t{%1, %0|%0, %1}
3416 %vmovd\t{%1, %0|%0, %1}"
3417 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3418 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3419 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3420 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3421
3422 (define_split
3423 [(set (match_operand:DI 0 "memory_operand" "")
3424 (zero_extend:DI (match_operand:SI 1 "memory_operand" "")))]
3425 "reload_completed"
3426 [(set (match_dup 4) (const_int 0))]
3427 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3428
3429 (define_split
3430 [(set (match_operand:DI 0 "register_operand" "")
3431 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3432 "!TARGET_64BIT && reload_completed
3433 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3434 && true_regnum (operands[0]) == true_regnum (operands[1])"
3435 [(set (match_dup 4) (const_int 0))]
3436 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3437
3438 (define_split
3439 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3440 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3441 "!TARGET_64BIT && reload_completed
3442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3443 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3444 [(set (match_dup 3) (match_dup 1))
3445 (set (match_dup 4) (const_int 0))]
3446 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3447
3448 (define_insn "zero_extend<mode>di2"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (zero_extend:DI
3451 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3452 "TARGET_64BIT"
3453 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3454 [(set_attr "type" "imovx")
3455 (set_attr "mode" "SI")])
3456
3457 (define_expand "zero_extend<mode>si2"
3458 [(set (match_operand:SI 0 "register_operand" "")
3459 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand" "")))]
3460 ""
3461 {
3462 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3463 {
3464 operands[1] = force_reg (<MODE>mode, operands[1]);
3465 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3466 DONE;
3467 }
3468 })
3469
3470 (define_insn_and_split "zero_extend<mode>si2_and"
3471 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3472 (zero_extend:SI
3473 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3474 (clobber (reg:CC FLAGS_REG))]
3475 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3476 "#"
3477 "&& reload_completed"
3478 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3479 (clobber (reg:CC FLAGS_REG))])]
3480 {
3481 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3482 {
3483 ix86_expand_clear (operands[0]);
3484
3485 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3486 emit_insn (gen_movstrict<mode>
3487 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3488 DONE;
3489 }
3490
3491 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3492 }
3493 [(set_attr "type" "alu1")
3494 (set_attr "mode" "SI")])
3495
3496 (define_insn "*zero_extend<mode>si2"
3497 [(set (match_operand:SI 0 "register_operand" "=r")
3498 (zero_extend:SI
3499 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3500 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3501 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3502 [(set_attr "type" "imovx")
3503 (set_attr "mode" "SI")])
3504
3505 (define_expand "zero_extendqihi2"
3506 [(set (match_operand:HI 0 "register_operand" "")
3507 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3508 ""
3509 {
3510 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3511 {
3512 operands[1] = force_reg (QImode, operands[1]);
3513 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3514 DONE;
3515 }
3516 })
3517
3518 (define_insn_and_split "zero_extendqihi2_and"
3519 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3520 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3521 (clobber (reg:CC FLAGS_REG))]
3522 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3523 "#"
3524 "&& reload_completed"
3525 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3526 (clobber (reg:CC FLAGS_REG))])]
3527 {
3528 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3529 {
3530 ix86_expand_clear (operands[0]);
3531
3532 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3533 emit_insn (gen_movstrictqi
3534 (gen_lowpart (QImode, operands[0]), operands[1]));
3535 DONE;
3536 }
3537
3538 operands[0] = gen_lowpart (SImode, operands[0]);
3539 }
3540 [(set_attr "type" "alu1")
3541 (set_attr "mode" "SI")])
3542
3543 ; zero extend to SImode to avoid partial register stalls
3544 (define_insn "*zero_extendqihi2"
3545 [(set (match_operand:HI 0 "register_operand" "=r")
3546 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3547 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3548 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3549 [(set_attr "type" "imovx")
3550 (set_attr "mode" "SI")])
3551 \f
3552 ;; Sign extension instructions
3553
3554 (define_expand "extendsidi2"
3555 [(set (match_operand:DI 0 "register_operand" "")
3556 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3557 ""
3558 {
3559 if (!TARGET_64BIT)
3560 {
3561 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3562 DONE;
3563 }
3564 })
3565
3566 (define_insn "*extendsidi2_rex64"
3567 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3568 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3569 "TARGET_64BIT"
3570 "@
3571 {cltq|cdqe}
3572 movs{lq|x}\t{%1, %0|%0, %1}"
3573 [(set_attr "type" "imovx")
3574 (set_attr "mode" "DI")
3575 (set_attr "prefix_0f" "0")
3576 (set_attr "modrm" "0,1")])
3577
3578 (define_insn "extendsidi2_1"
3579 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3580 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3581 (clobber (reg:CC FLAGS_REG))
3582 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3583 "!TARGET_64BIT"
3584 "#")
3585
3586 ;; Extend to memory case when source register does die.
3587 (define_split
3588 [(set (match_operand:DI 0 "memory_operand" "")
3589 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3590 (clobber (reg:CC FLAGS_REG))
3591 (clobber (match_operand:SI 2 "register_operand" ""))]
3592 "(reload_completed
3593 && dead_or_set_p (insn, operands[1])
3594 && !reg_mentioned_p (operands[1], operands[0]))"
3595 [(set (match_dup 3) (match_dup 1))
3596 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3597 (clobber (reg:CC FLAGS_REG))])
3598 (set (match_dup 4) (match_dup 1))]
3599 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3600
3601 ;; Extend to memory case when source register does not die.
3602 (define_split
3603 [(set (match_operand:DI 0 "memory_operand" "")
3604 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3605 (clobber (reg:CC FLAGS_REG))
3606 (clobber (match_operand:SI 2 "register_operand" ""))]
3607 "reload_completed"
3608 [(const_int 0)]
3609 {
3610 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3611
3612 emit_move_insn (operands[3], operands[1]);
3613
3614 /* Generate a cltd if possible and doing so it profitable. */
3615 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3616 && true_regnum (operands[1]) == AX_REG
3617 && true_regnum (operands[2]) == DX_REG)
3618 {
3619 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3620 }
3621 else
3622 {
3623 emit_move_insn (operands[2], operands[1]);
3624 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3625 }
3626 emit_move_insn (operands[4], operands[2]);
3627 DONE;
3628 })
3629
3630 ;; Extend to register case. Optimize case where source and destination
3631 ;; registers match and cases where we can use cltd.
3632 (define_split
3633 [(set (match_operand:DI 0 "register_operand" "")
3634 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3635 (clobber (reg:CC FLAGS_REG))
3636 (clobber (match_scratch:SI 2 ""))]
3637 "reload_completed"
3638 [(const_int 0)]
3639 {
3640 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3641
3642 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3643 emit_move_insn (operands[3], operands[1]);
3644
3645 /* Generate a cltd if possible and doing so it profitable. */
3646 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3647 && true_regnum (operands[3]) == AX_REG
3648 && true_regnum (operands[4]) == DX_REG)
3649 {
3650 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3651 DONE;
3652 }
3653
3654 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3655 emit_move_insn (operands[4], operands[1]);
3656
3657 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3658 DONE;
3659 })
3660
3661 (define_insn "extend<mode>di2"
3662 [(set (match_operand:DI 0 "register_operand" "=r")
3663 (sign_extend:DI
3664 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3665 "TARGET_64BIT"
3666 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3667 [(set_attr "type" "imovx")
3668 (set_attr "mode" "DI")])
3669
3670 (define_insn "extendhisi2"
3671 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3672 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3673 ""
3674 {
3675 switch (get_attr_prefix_0f (insn))
3676 {
3677 case 0:
3678 return "{cwtl|cwde}";
3679 default:
3680 return "movs{wl|x}\t{%1, %0|%0, %1}";
3681 }
3682 }
3683 [(set_attr "type" "imovx")
3684 (set_attr "mode" "SI")
3685 (set (attr "prefix_0f")
3686 ;; movsx is short decodable while cwtl is vector decoded.
3687 (if_then_else (and (eq_attr "cpu" "!k6")
3688 (eq_attr "alternative" "0"))
3689 (const_string "0")
3690 (const_string "1")))
3691 (set (attr "modrm")
3692 (if_then_else (eq_attr "prefix_0f" "0")
3693 (const_string "0")
3694 (const_string "1")))])
3695
3696 (define_insn "*extendhisi2_zext"
3697 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3698 (zero_extend:DI
3699 (sign_extend:SI
3700 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3701 "TARGET_64BIT"
3702 {
3703 switch (get_attr_prefix_0f (insn))
3704 {
3705 case 0:
3706 return "{cwtl|cwde}";
3707 default:
3708 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3709 }
3710 }
3711 [(set_attr "type" "imovx")
3712 (set_attr "mode" "SI")
3713 (set (attr "prefix_0f")
3714 ;; movsx is short decodable while cwtl is vector decoded.
3715 (if_then_else (and (eq_attr "cpu" "!k6")
3716 (eq_attr "alternative" "0"))
3717 (const_string "0")
3718 (const_string "1")))
3719 (set (attr "modrm")
3720 (if_then_else (eq_attr "prefix_0f" "0")
3721 (const_string "0")
3722 (const_string "1")))])
3723
3724 (define_insn "extendqisi2"
3725 [(set (match_operand:SI 0 "register_operand" "=r")
3726 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3727 ""
3728 "movs{bl|x}\t{%1, %0|%0, %1}"
3729 [(set_attr "type" "imovx")
3730 (set_attr "mode" "SI")])
3731
3732 (define_insn "*extendqisi2_zext"
3733 [(set (match_operand:DI 0 "register_operand" "=r")
3734 (zero_extend:DI
3735 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3736 "TARGET_64BIT"
3737 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3738 [(set_attr "type" "imovx")
3739 (set_attr "mode" "SI")])
3740
3741 (define_insn "extendqihi2"
3742 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3743 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3744 ""
3745 {
3746 switch (get_attr_prefix_0f (insn))
3747 {
3748 case 0:
3749 return "{cbtw|cbw}";
3750 default:
3751 return "movs{bw|x}\t{%1, %0|%0, %1}";
3752 }
3753 }
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "HI")
3756 (set (attr "prefix_0f")
3757 ;; movsx is short decodable while cwtl is vector decoded.
3758 (if_then_else (and (eq_attr "cpu" "!k6")
3759 (eq_attr "alternative" "0"))
3760 (const_string "0")
3761 (const_string "1")))
3762 (set (attr "modrm")
3763 (if_then_else (eq_attr "prefix_0f" "0")
3764 (const_string "0")
3765 (const_string "1")))])
3766 \f
3767 ;; Conversions between float and double.
3768
3769 ;; These are all no-ops in the model used for the 80387.
3770 ;; So just emit moves.
3771
3772 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3773 (define_split
3774 [(set (match_operand:DF 0 "push_operand" "")
3775 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3776 "reload_completed"
3777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3778 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3779
3780 (define_split
3781 [(set (match_operand:XF 0 "push_operand" "")
3782 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3783 "reload_completed"
3784 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3785 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3786 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3787
3788 (define_expand "extendsfdf2"
3789 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3790 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3791 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3792 {
3793 /* ??? Needed for compress_float_constant since all fp constants
3794 are TARGET_LEGITIMATE_CONSTANT_P. */
3795 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3796 {
3797 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3798 && standard_80387_constant_p (operands[1]) > 0)
3799 {
3800 operands[1] = simplify_const_unary_operation
3801 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3802 emit_move_insn_1 (operands[0], operands[1]);
3803 DONE;
3804 }
3805 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3806 }
3807 })
3808
3809 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3810 cvtss2sd:
3811 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3812 cvtps2pd xmm2,xmm1
3813 We do the conversion post reload to avoid producing of 128bit spills
3814 that might lead to ICE on 32bit target. The sequence unlikely combine
3815 anyway. */
3816 (define_split
3817 [(set (match_operand:DF 0 "register_operand" "")
3818 (float_extend:DF
3819 (match_operand:SF 1 "nonimmediate_operand" "")))]
3820 "TARGET_USE_VECTOR_FP_CONVERTS
3821 && optimize_insn_for_speed_p ()
3822 && reload_completed && SSE_REG_P (operands[0])"
3823 [(set (match_dup 2)
3824 (float_extend:V2DF
3825 (vec_select:V2SF
3826 (match_dup 3)
3827 (parallel [(const_int 0) (const_int 1)]))))]
3828 {
3829 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3830 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3831 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3832 Try to avoid move when unpacking can be done in source. */
3833 if (REG_P (operands[1]))
3834 {
3835 /* If it is unsafe to overwrite upper half of source, we need
3836 to move to destination and unpack there. */
3837 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3838 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3839 && true_regnum (operands[0]) != true_regnum (operands[1]))
3840 {
3841 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3842 emit_move_insn (tmp, operands[1]);
3843 }
3844 else
3845 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3846 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3847 operands[3]));
3848 }
3849 else
3850 emit_insn (gen_vec_setv4sf_0 (operands[3],
3851 CONST0_RTX (V4SFmode), operands[1]));
3852 })
3853
3854 (define_insn "*extendsfdf2_mixed"
3855 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3856 (float_extend:DF
3857 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3858 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3859 {
3860 switch (which_alternative)
3861 {
3862 case 0:
3863 case 1:
3864 return output_387_reg_move (insn, operands);
3865
3866 case 2:
3867 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3868
3869 default:
3870 gcc_unreachable ();
3871 }
3872 }
3873 [(set_attr "type" "fmov,fmov,ssecvt")
3874 (set_attr "prefix" "orig,orig,maybe_vex")
3875 (set_attr "mode" "SF,XF,DF")])
3876
3877 (define_insn "*extendsfdf2_sse"
3878 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3879 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3880 "TARGET_SSE2 && TARGET_SSE_MATH"
3881 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3882 [(set_attr "type" "ssecvt")
3883 (set_attr "prefix" "maybe_vex")
3884 (set_attr "mode" "DF")])
3885
3886 (define_insn "*extendsfdf2_i387"
3887 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3888 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3889 "TARGET_80387"
3890 "* return output_387_reg_move (insn, operands);"
3891 [(set_attr "type" "fmov")
3892 (set_attr "mode" "SF,XF")])
3893
3894 (define_expand "extend<mode>xf2"
3895 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3896 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3897 "TARGET_80387"
3898 {
3899 /* ??? Needed for compress_float_constant since all fp constants
3900 are TARGET_LEGITIMATE_CONSTANT_P. */
3901 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3902 {
3903 if (standard_80387_constant_p (operands[1]) > 0)
3904 {
3905 operands[1] = simplify_const_unary_operation
3906 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3907 emit_move_insn_1 (operands[0], operands[1]);
3908 DONE;
3909 }
3910 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3911 }
3912 })
3913
3914 (define_insn "*extend<mode>xf2_i387"
3915 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3916 (float_extend:XF
3917 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3918 "TARGET_80387"
3919 "* return output_387_reg_move (insn, operands);"
3920 [(set_attr "type" "fmov")
3921 (set_attr "mode" "<MODE>,XF")])
3922
3923 ;; %%% This seems bad bad news.
3924 ;; This cannot output into an f-reg because there is no way to be sure
3925 ;; of truncating in that case. Otherwise this is just like a simple move
3926 ;; insn. So we pretend we can output to a reg in order to get better
3927 ;; register preferencing, but we really use a stack slot.
3928
3929 ;; Conversion from DFmode to SFmode.
3930
3931 (define_expand "truncdfsf2"
3932 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3933 (float_truncate:SF
3934 (match_operand:DF 1 "nonimmediate_operand" "")))]
3935 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3936 {
3937 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3938 ;
3939 else if (flag_unsafe_math_optimizations)
3940 ;
3941 else
3942 {
3943 enum ix86_stack_slot slot = (virtuals_instantiated
3944 ? SLOT_TEMP
3945 : SLOT_VIRTUAL);
3946 rtx temp = assign_386_stack_local (SFmode, slot);
3947 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3948 DONE;
3949 }
3950 })
3951
3952 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3953 cvtsd2ss:
3954 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3955 cvtpd2ps xmm2,xmm1
3956 We do the conversion post reload to avoid producing of 128bit spills
3957 that might lead to ICE on 32bit target. The sequence unlikely combine
3958 anyway. */
3959 (define_split
3960 [(set (match_operand:SF 0 "register_operand" "")
3961 (float_truncate:SF
3962 (match_operand:DF 1 "nonimmediate_operand" "")))]
3963 "TARGET_USE_VECTOR_FP_CONVERTS
3964 && optimize_insn_for_speed_p ()
3965 && reload_completed && SSE_REG_P (operands[0])"
3966 [(set (match_dup 2)
3967 (vec_concat:V4SF
3968 (float_truncate:V2SF
3969 (match_dup 4))
3970 (match_dup 3)))]
3971 {
3972 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3973 operands[3] = CONST0_RTX (V2SFmode);
3974 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3975 /* Use movsd for loading from memory, unpcklpd for registers.
3976 Try to avoid move when unpacking can be done in source, or SSE3
3977 movddup is available. */
3978 if (REG_P (operands[1]))
3979 {
3980 if (!TARGET_SSE3
3981 && true_regnum (operands[0]) != true_regnum (operands[1])
3982 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3983 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3984 {
3985 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3986 emit_move_insn (tmp, operands[1]);
3987 operands[1] = tmp;
3988 }
3989 else if (!TARGET_SSE3)
3990 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3991 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3992 }
3993 else
3994 emit_insn (gen_sse2_loadlpd (operands[4],
3995 CONST0_RTX (V2DFmode), operands[1]));
3996 })
3997
3998 (define_expand "truncdfsf2_with_temp"
3999 [(parallel [(set (match_operand:SF 0 "" "")
4000 (float_truncate:SF (match_operand:DF 1 "" "")))
4001 (clobber (match_operand:SF 2 "" ""))])])
4002
4003 (define_insn "*truncdfsf_fast_mixed"
4004 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4005 (float_truncate:SF
4006 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4007 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4008 {
4009 switch (which_alternative)
4010 {
4011 case 0:
4012 return output_387_reg_move (insn, operands);
4013 case 1:
4014 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4015 default:
4016 gcc_unreachable ();
4017 }
4018 }
4019 [(set_attr "type" "fmov,ssecvt")
4020 (set_attr "prefix" "orig,maybe_vex")
4021 (set_attr "mode" "SF")])
4022
4023 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4024 ;; because nothing we do here is unsafe.
4025 (define_insn "*truncdfsf_fast_sse"
4026 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4027 (float_truncate:SF
4028 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4029 "TARGET_SSE2 && TARGET_SSE_MATH"
4030 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4031 [(set_attr "type" "ssecvt")
4032 (set_attr "prefix" "maybe_vex")
4033 (set_attr "mode" "SF")])
4034
4035 (define_insn "*truncdfsf_fast_i387"
4036 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4037 (float_truncate:SF
4038 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4039 "TARGET_80387 && flag_unsafe_math_optimizations"
4040 "* return output_387_reg_move (insn, operands);"
4041 [(set_attr "type" "fmov")
4042 (set_attr "mode" "SF")])
4043
4044 (define_insn "*truncdfsf_mixed"
4045 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4046 (float_truncate:SF
4047 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4048 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4049 "TARGET_MIX_SSE_I387"
4050 {
4051 switch (which_alternative)
4052 {
4053 case 0:
4054 return output_387_reg_move (insn, operands);
4055 case 1:
4056 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4057
4058 default:
4059 return "#";
4060 }
4061 }
4062 [(set_attr "isa" "*,sse2,*,*,*")
4063 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4064 (set_attr "unit" "*,*,i387,i387,i387")
4065 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4066 (set_attr "mode" "SF")])
4067
4068 (define_insn "*truncdfsf_i387"
4069 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4070 (float_truncate:SF
4071 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4072 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4073 "TARGET_80387"
4074 {
4075 switch (which_alternative)
4076 {
4077 case 0:
4078 return output_387_reg_move (insn, operands);
4079
4080 default:
4081 return "#";
4082 }
4083 }
4084 [(set_attr "type" "fmov,multi,multi,multi")
4085 (set_attr "unit" "*,i387,i387,i387")
4086 (set_attr "mode" "SF")])
4087
4088 (define_insn "*truncdfsf2_i387_1"
4089 [(set (match_operand:SF 0 "memory_operand" "=m")
4090 (float_truncate:SF
4091 (match_operand:DF 1 "register_operand" "f")))]
4092 "TARGET_80387
4093 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4094 && !TARGET_MIX_SSE_I387"
4095 "* return output_387_reg_move (insn, operands);"
4096 [(set_attr "type" "fmov")
4097 (set_attr "mode" "SF")])
4098
4099 (define_split
4100 [(set (match_operand:SF 0 "register_operand" "")
4101 (float_truncate:SF
4102 (match_operand:DF 1 "fp_register_operand" "")))
4103 (clobber (match_operand 2 "" ""))]
4104 "reload_completed"
4105 [(set (match_dup 2) (match_dup 1))
4106 (set (match_dup 0) (match_dup 2))]
4107 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4108
4109 ;; Conversion from XFmode to {SF,DF}mode
4110
4111 (define_expand "truncxf<mode>2"
4112 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4113 (float_truncate:MODEF
4114 (match_operand:XF 1 "register_operand" "")))
4115 (clobber (match_dup 2))])]
4116 "TARGET_80387"
4117 {
4118 if (flag_unsafe_math_optimizations)
4119 {
4120 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4121 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4122 if (reg != operands[0])
4123 emit_move_insn (operands[0], reg);
4124 DONE;
4125 }
4126 else
4127 {
4128 enum ix86_stack_slot slot = (virtuals_instantiated
4129 ? SLOT_TEMP
4130 : SLOT_VIRTUAL);
4131 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4132 }
4133 })
4134
4135 (define_insn "*truncxfsf2_mixed"
4136 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4137 (float_truncate:SF
4138 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4139 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4140 "TARGET_80387"
4141 {
4142 gcc_assert (!which_alternative);
4143 return output_387_reg_move (insn, operands);
4144 }
4145 [(set_attr "type" "fmov,multi,multi,multi")
4146 (set_attr "unit" "*,i387,i387,i387")
4147 (set_attr "mode" "SF")])
4148
4149 (define_insn "*truncxfdf2_mixed"
4150 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4151 (float_truncate:DF
4152 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4153 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4154 "TARGET_80387"
4155 {
4156 gcc_assert (!which_alternative);
4157 return output_387_reg_move (insn, operands);
4158 }
4159 [(set_attr "isa" "*,*,sse2,*")
4160 (set_attr "type" "fmov,multi,multi,multi")
4161 (set_attr "unit" "*,i387,i387,i387")
4162 (set_attr "mode" "DF")])
4163
4164 (define_insn "truncxf<mode>2_i387_noop"
4165 [(set (match_operand:MODEF 0 "register_operand" "=f")
4166 (float_truncate:MODEF
4167 (match_operand:XF 1 "register_operand" "f")))]
4168 "TARGET_80387 && flag_unsafe_math_optimizations"
4169 "* return output_387_reg_move (insn, operands);"
4170 [(set_attr "type" "fmov")
4171 (set_attr "mode" "<MODE>")])
4172
4173 (define_insn "*truncxf<mode>2_i387"
4174 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4175 (float_truncate:MODEF
4176 (match_operand:XF 1 "register_operand" "f")))]
4177 "TARGET_80387"
4178 "* return output_387_reg_move (insn, operands);"
4179 [(set_attr "type" "fmov")
4180 (set_attr "mode" "<MODE>")])
4181
4182 (define_split
4183 [(set (match_operand:MODEF 0 "register_operand" "")
4184 (float_truncate:MODEF
4185 (match_operand:XF 1 "register_operand" "")))
4186 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4187 "TARGET_80387 && reload_completed"
4188 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4189 (set (match_dup 0) (match_dup 2))])
4190
4191 (define_split
4192 [(set (match_operand:MODEF 0 "memory_operand" "")
4193 (float_truncate:MODEF
4194 (match_operand:XF 1 "register_operand" "")))
4195 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4196 "TARGET_80387"
4197 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4198 \f
4199 ;; Signed conversion to DImode.
4200
4201 (define_expand "fix_truncxfdi2"
4202 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4203 (fix:DI (match_operand:XF 1 "register_operand" "")))
4204 (clobber (reg:CC FLAGS_REG))])]
4205 "TARGET_80387"
4206 {
4207 if (TARGET_FISTTP)
4208 {
4209 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4210 DONE;
4211 }
4212 })
4213
4214 (define_expand "fix_trunc<mode>di2"
4215 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4216 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4217 (clobber (reg:CC FLAGS_REG))])]
4218 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4219 {
4220 if (TARGET_FISTTP
4221 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4222 {
4223 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4224 DONE;
4225 }
4226 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4227 {
4228 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4229 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4230 if (out != operands[0])
4231 emit_move_insn (operands[0], out);
4232 DONE;
4233 }
4234 })
4235
4236 ;; Signed conversion to SImode.
4237
4238 (define_expand "fix_truncxfsi2"
4239 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4240 (fix:SI (match_operand:XF 1 "register_operand" "")))
4241 (clobber (reg:CC FLAGS_REG))])]
4242 "TARGET_80387"
4243 {
4244 if (TARGET_FISTTP)
4245 {
4246 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4247 DONE;
4248 }
4249 })
4250
4251 (define_expand "fix_trunc<mode>si2"
4252 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4253 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4254 (clobber (reg:CC FLAGS_REG))])]
4255 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4256 {
4257 if (TARGET_FISTTP
4258 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4259 {
4260 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4261 DONE;
4262 }
4263 if (SSE_FLOAT_MODE_P (<MODE>mode))
4264 {
4265 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4266 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4267 if (out != operands[0])
4268 emit_move_insn (operands[0], out);
4269 DONE;
4270 }
4271 })
4272
4273 ;; Signed conversion to HImode.
4274
4275 (define_expand "fix_trunc<mode>hi2"
4276 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4277 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4278 (clobber (reg:CC FLAGS_REG))])]
4279 "TARGET_80387
4280 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4281 {
4282 if (TARGET_FISTTP)
4283 {
4284 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4285 DONE;
4286 }
4287 })
4288
4289 ;; Unsigned conversion to SImode.
4290
4291 (define_expand "fixuns_trunc<mode>si2"
4292 [(parallel
4293 [(set (match_operand:SI 0 "register_operand" "")
4294 (unsigned_fix:SI
4295 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4296 (use (match_dup 2))
4297 (clobber (match_scratch:<ssevecmode> 3 ""))
4298 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4299 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4300 {
4301 enum machine_mode mode = <MODE>mode;
4302 enum machine_mode vecmode = <ssevecmode>mode;
4303 REAL_VALUE_TYPE TWO31r;
4304 rtx two31;
4305
4306 if (optimize_insn_for_size_p ())
4307 FAIL;
4308
4309 real_ldexp (&TWO31r, &dconst1, 31);
4310 two31 = const_double_from_real_value (TWO31r, mode);
4311 two31 = ix86_build_const_vector (vecmode, true, two31);
4312 operands[2] = force_reg (vecmode, two31);
4313 })
4314
4315 (define_insn_and_split "*fixuns_trunc<mode>_1"
4316 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4317 (unsigned_fix:SI
4318 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4319 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4320 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4321 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4322 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4323 && optimize_function_for_speed_p (cfun)"
4324 "#"
4325 "&& reload_completed"
4326 [(const_int 0)]
4327 {
4328 ix86_split_convert_uns_si_sse (operands);
4329 DONE;
4330 })
4331
4332 ;; Unsigned conversion to HImode.
4333 ;; Without these patterns, we'll try the unsigned SI conversion which
4334 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4335
4336 (define_expand "fixuns_trunc<mode>hi2"
4337 [(set (match_dup 2)
4338 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4339 (set (match_operand:HI 0 "nonimmediate_operand" "")
4340 (subreg:HI (match_dup 2) 0))]
4341 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4342 "operands[2] = gen_reg_rtx (SImode);")
4343
4344 ;; When SSE is available, it is always faster to use it!
4345 (define_insn "fix_trunc<mode>di_sse"
4346 [(set (match_operand:DI 0 "register_operand" "=r,r")
4347 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4348 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4349 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4350 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4351 [(set_attr "type" "sseicvt")
4352 (set_attr "prefix" "maybe_vex")
4353 (set_attr "prefix_rex" "1")
4354 (set_attr "mode" "<MODE>")
4355 (set_attr "athlon_decode" "double,vector")
4356 (set_attr "amdfam10_decode" "double,double")
4357 (set_attr "bdver1_decode" "double,double")])
4358
4359 (define_insn "fix_trunc<mode>si_sse"
4360 [(set (match_operand:SI 0 "register_operand" "=r,r")
4361 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4362 "SSE_FLOAT_MODE_P (<MODE>mode)
4363 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4364 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4365 [(set_attr "type" "sseicvt")
4366 (set_attr "prefix" "maybe_vex")
4367 (set_attr "mode" "<MODE>")
4368 (set_attr "athlon_decode" "double,vector")
4369 (set_attr "amdfam10_decode" "double,double")
4370 (set_attr "bdver1_decode" "double,double")])
4371
4372 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4373 (define_peephole2
4374 [(set (match_operand:MODEF 0 "register_operand" "")
4375 (match_operand:MODEF 1 "memory_operand" ""))
4376 (set (match_operand:SWI48x 2 "register_operand" "")
4377 (fix:SWI48x (match_dup 0)))]
4378 "TARGET_SHORTEN_X87_SSE
4379 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4380 && peep2_reg_dead_p (2, operands[0])"
4381 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4382
4383 ;; Avoid vector decoded forms of the instruction.
4384 (define_peephole2
4385 [(match_scratch:DF 2 "x")
4386 (set (match_operand:SWI48x 0 "register_operand" "")
4387 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4388 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4389 [(set (match_dup 2) (match_dup 1))
4390 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4391
4392 (define_peephole2
4393 [(match_scratch:SF 2 "x")
4394 (set (match_operand:SWI48x 0 "register_operand" "")
4395 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4396 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4397 [(set (match_dup 2) (match_dup 1))
4398 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4399
4400 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4401 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4402 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4403 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4404 && TARGET_FISTTP
4405 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4406 && (TARGET_64BIT || <MODE>mode != DImode))
4407 && TARGET_SSE_MATH)
4408 && can_create_pseudo_p ()"
4409 "#"
4410 "&& 1"
4411 [(const_int 0)]
4412 {
4413 if (memory_operand (operands[0], VOIDmode))
4414 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4415 else
4416 {
4417 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4418 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4419 operands[1],
4420 operands[2]));
4421 }
4422 DONE;
4423 }
4424 [(set_attr "type" "fisttp")
4425 (set_attr "mode" "<MODE>")])
4426
4427 (define_insn "fix_trunc<mode>_i387_fisttp"
4428 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4429 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4430 (clobber (match_scratch:XF 2 "=&1f"))]
4431 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4432 && TARGET_FISTTP
4433 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4434 && (TARGET_64BIT || <MODE>mode != DImode))
4435 && TARGET_SSE_MATH)"
4436 "* return output_fix_trunc (insn, operands, true);"
4437 [(set_attr "type" "fisttp")
4438 (set_attr "mode" "<MODE>")])
4439
4440 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4441 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4442 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4443 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4444 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4445 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4446 && TARGET_FISTTP
4447 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4448 && (TARGET_64BIT || <MODE>mode != DImode))
4449 && TARGET_SSE_MATH)"
4450 "#"
4451 [(set_attr "type" "fisttp")
4452 (set_attr "mode" "<MODE>")])
4453
4454 (define_split
4455 [(set (match_operand:SWI248x 0 "register_operand" "")
4456 (fix:SWI248x (match_operand 1 "register_operand" "")))
4457 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4458 (clobber (match_scratch 3 ""))]
4459 "reload_completed"
4460 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4461 (clobber (match_dup 3))])
4462 (set (match_dup 0) (match_dup 2))])
4463
4464 (define_split
4465 [(set (match_operand:SWI248x 0 "memory_operand" "")
4466 (fix:SWI248x (match_operand 1 "register_operand" "")))
4467 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4468 (clobber (match_scratch 3 ""))]
4469 "reload_completed"
4470 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4471 (clobber (match_dup 3))])])
4472
4473 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4474 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4475 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4476 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4477 ;; function in i386.c.
4478 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4479 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4480 (fix:SWI248x (match_operand 1 "register_operand" "")))
4481 (clobber (reg:CC FLAGS_REG))]
4482 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4483 && !TARGET_FISTTP
4484 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4485 && (TARGET_64BIT || <MODE>mode != DImode))
4486 && can_create_pseudo_p ()"
4487 "#"
4488 "&& 1"
4489 [(const_int 0)]
4490 {
4491 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4492
4493 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4494 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4495 if (memory_operand (operands[0], VOIDmode))
4496 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4497 operands[2], operands[3]));
4498 else
4499 {
4500 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4501 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4502 operands[2], operands[3],
4503 operands[4]));
4504 }
4505 DONE;
4506 }
4507 [(set_attr "type" "fistp")
4508 (set_attr "i387_cw" "trunc")
4509 (set_attr "mode" "<MODE>")])
4510
4511 (define_insn "fix_truncdi_i387"
4512 [(set (match_operand:DI 0 "memory_operand" "=m")
4513 (fix:DI (match_operand 1 "register_operand" "f")))
4514 (use (match_operand:HI 2 "memory_operand" "m"))
4515 (use (match_operand:HI 3 "memory_operand" "m"))
4516 (clobber (match_scratch:XF 4 "=&1f"))]
4517 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4518 && !TARGET_FISTTP
4519 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4520 "* return output_fix_trunc (insn, operands, false);"
4521 [(set_attr "type" "fistp")
4522 (set_attr "i387_cw" "trunc")
4523 (set_attr "mode" "DI")])
4524
4525 (define_insn "fix_truncdi_i387_with_temp"
4526 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4527 (fix:DI (match_operand 1 "register_operand" "f,f")))
4528 (use (match_operand:HI 2 "memory_operand" "m,m"))
4529 (use (match_operand:HI 3 "memory_operand" "m,m"))
4530 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4531 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4532 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && !TARGET_FISTTP
4534 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4535 "#"
4536 [(set_attr "type" "fistp")
4537 (set_attr "i387_cw" "trunc")
4538 (set_attr "mode" "DI")])
4539
4540 (define_split
4541 [(set (match_operand:DI 0 "register_operand" "")
4542 (fix:DI (match_operand 1 "register_operand" "")))
4543 (use (match_operand:HI 2 "memory_operand" ""))
4544 (use (match_operand:HI 3 "memory_operand" ""))
4545 (clobber (match_operand:DI 4 "memory_operand" ""))
4546 (clobber (match_scratch 5 ""))]
4547 "reload_completed"
4548 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4549 (use (match_dup 2))
4550 (use (match_dup 3))
4551 (clobber (match_dup 5))])
4552 (set (match_dup 0) (match_dup 4))])
4553
4554 (define_split
4555 [(set (match_operand:DI 0 "memory_operand" "")
4556 (fix:DI (match_operand 1 "register_operand" "")))
4557 (use (match_operand:HI 2 "memory_operand" ""))
4558 (use (match_operand:HI 3 "memory_operand" ""))
4559 (clobber (match_operand:DI 4 "memory_operand" ""))
4560 (clobber (match_scratch 5 ""))]
4561 "reload_completed"
4562 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4563 (use (match_dup 2))
4564 (use (match_dup 3))
4565 (clobber (match_dup 5))])])
4566
4567 (define_insn "fix_trunc<mode>_i387"
4568 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4569 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4570 (use (match_operand:HI 2 "memory_operand" "m"))
4571 (use (match_operand:HI 3 "memory_operand" "m"))]
4572 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4573 && !TARGET_FISTTP
4574 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4575 "* return output_fix_trunc (insn, operands, false);"
4576 [(set_attr "type" "fistp")
4577 (set_attr "i387_cw" "trunc")
4578 (set_attr "mode" "<MODE>")])
4579
4580 (define_insn "fix_trunc<mode>_i387_with_temp"
4581 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4582 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4583 (use (match_operand:HI 2 "memory_operand" "m,m"))
4584 (use (match_operand:HI 3 "memory_operand" "m,m"))
4585 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4586 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4587 && !TARGET_FISTTP
4588 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4589 "#"
4590 [(set_attr "type" "fistp")
4591 (set_attr "i387_cw" "trunc")
4592 (set_attr "mode" "<MODE>")])
4593
4594 (define_split
4595 [(set (match_operand:SWI24 0 "register_operand" "")
4596 (fix:SWI24 (match_operand 1 "register_operand" "")))
4597 (use (match_operand:HI 2 "memory_operand" ""))
4598 (use (match_operand:HI 3 "memory_operand" ""))
4599 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4600 "reload_completed"
4601 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4602 (use (match_dup 2))
4603 (use (match_dup 3))])
4604 (set (match_dup 0) (match_dup 4))])
4605
4606 (define_split
4607 [(set (match_operand:SWI24 0 "memory_operand" "")
4608 (fix:SWI24 (match_operand 1 "register_operand" "")))
4609 (use (match_operand:HI 2 "memory_operand" ""))
4610 (use (match_operand:HI 3 "memory_operand" ""))
4611 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4612 "reload_completed"
4613 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4614 (use (match_dup 2))
4615 (use (match_dup 3))])])
4616
4617 (define_insn "x86_fnstcw_1"
4618 [(set (match_operand:HI 0 "memory_operand" "=m")
4619 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4620 "TARGET_80387"
4621 "fnstcw\t%0"
4622 [(set (attr "length")
4623 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4624 (set_attr "mode" "HI")
4625 (set_attr "unit" "i387")
4626 (set_attr "bdver1_decode" "vector")])
4627
4628 (define_insn "x86_fldcw_1"
4629 [(set (reg:HI FPCR_REG)
4630 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4631 "TARGET_80387"
4632 "fldcw\t%0"
4633 [(set (attr "length")
4634 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4635 (set_attr "mode" "HI")
4636 (set_attr "unit" "i387")
4637 (set_attr "athlon_decode" "vector")
4638 (set_attr "amdfam10_decode" "vector")
4639 (set_attr "bdver1_decode" "vector")])
4640 \f
4641 ;; Conversion between fixed point and floating point.
4642
4643 ;; Even though we only accept memory inputs, the backend _really_
4644 ;; wants to be able to do this between registers.
4645
4646 (define_expand "floathi<mode>2"
4647 [(set (match_operand:X87MODEF 0 "register_operand" "")
4648 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4649 "TARGET_80387
4650 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4651 || TARGET_MIX_SSE_I387)")
4652
4653 ;; Pre-reload splitter to add memory clobber to the pattern.
4654 (define_insn_and_split "*floathi<mode>2_1"
4655 [(set (match_operand:X87MODEF 0 "register_operand" "")
4656 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4657 "TARGET_80387
4658 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4659 || TARGET_MIX_SSE_I387)
4660 && can_create_pseudo_p ()"
4661 "#"
4662 "&& 1"
4663 [(parallel [(set (match_dup 0)
4664 (float:X87MODEF (match_dup 1)))
4665 (clobber (match_dup 2))])]
4666 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4667
4668 (define_insn "*floathi<mode>2_i387_with_temp"
4669 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4670 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4671 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4672 "TARGET_80387
4673 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4674 || TARGET_MIX_SSE_I387)"
4675 "#"
4676 [(set_attr "type" "fmov,multi")
4677 (set_attr "mode" "<MODE>")
4678 (set_attr "unit" "*,i387")
4679 (set_attr "fp_int_src" "true")])
4680
4681 (define_insn "*floathi<mode>2_i387"
4682 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4683 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4684 "TARGET_80387
4685 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4686 || TARGET_MIX_SSE_I387)"
4687 "fild%Z1\t%1"
4688 [(set_attr "type" "fmov")
4689 (set_attr "mode" "<MODE>")
4690 (set_attr "fp_int_src" "true")])
4691
4692 (define_split
4693 [(set (match_operand:X87MODEF 0 "register_operand" "")
4694 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4695 (clobber (match_operand:HI 2 "memory_operand" ""))]
4696 "TARGET_80387
4697 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4698 || TARGET_MIX_SSE_I387)
4699 && reload_completed"
4700 [(set (match_dup 2) (match_dup 1))
4701 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4702
4703 (define_split
4704 [(set (match_operand:X87MODEF 0 "register_operand" "")
4705 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4706 (clobber (match_operand:HI 2 "memory_operand" ""))]
4707 "TARGET_80387
4708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4709 || TARGET_MIX_SSE_I387)
4710 && reload_completed"
4711 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4712
4713 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4714 [(set (match_operand:X87MODEF 0 "register_operand" "")
4715 (float:X87MODEF
4716 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4717 "TARGET_80387
4718 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4719 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4720 {
4721 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4722 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4723 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4724 {
4725 rtx reg = gen_reg_rtx (XFmode);
4726 rtx (*insn)(rtx, rtx);
4727
4728 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4729
4730 if (<X87MODEF:MODE>mode == SFmode)
4731 insn = gen_truncxfsf2;
4732 else if (<X87MODEF:MODE>mode == DFmode)
4733 insn = gen_truncxfdf2;
4734 else
4735 gcc_unreachable ();
4736
4737 emit_insn (insn (operands[0], reg));
4738 DONE;
4739 }
4740 })
4741
4742 ;; Pre-reload splitter to add memory clobber to the pattern.
4743 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4744 [(set (match_operand:X87MODEF 0 "register_operand" "")
4745 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4746 "((TARGET_80387
4747 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4748 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4749 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4750 || TARGET_MIX_SSE_I387))
4751 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4752 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4753 && ((<SWI48x:MODE>mode == SImode
4754 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4755 && optimize_function_for_speed_p (cfun)
4756 && flag_trapping_math)
4757 || !(TARGET_INTER_UNIT_CONVERSIONS
4758 || optimize_function_for_size_p (cfun)))))
4759 && can_create_pseudo_p ()"
4760 "#"
4761 "&& 1"
4762 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4763 (clobber (match_dup 2))])]
4764 {
4765 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4766
4767 /* Avoid store forwarding (partial memory) stall penalty
4768 by passing DImode value through XMM registers. */
4769 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4770 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4771 && optimize_function_for_speed_p (cfun))
4772 {
4773 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4774 operands[1],
4775 operands[2]));
4776 DONE;
4777 }
4778 })
4779
4780 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4781 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4782 (float:MODEF
4783 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4784 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4785 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4786 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4787 "#"
4788 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4789 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4790 (set_attr "unit" "*,i387,*,*,*")
4791 (set_attr "athlon_decode" "*,*,double,direct,double")
4792 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4793 (set_attr "bdver1_decode" "*,*,double,direct,double")
4794 (set_attr "fp_int_src" "true")])
4795
4796 (define_insn "*floatsi<mode>2_vector_mixed"
4797 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4798 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4799 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4800 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4801 "@
4802 fild%Z1\t%1
4803 #"
4804 [(set_attr "type" "fmov,sseicvt")
4805 (set_attr "mode" "<MODE>,<ssevecmode>")
4806 (set_attr "unit" "i387,*")
4807 (set_attr "athlon_decode" "*,direct")
4808 (set_attr "amdfam10_decode" "*,double")
4809 (set_attr "bdver1_decode" "*,direct")
4810 (set_attr "fp_int_src" "true")])
4811
4812 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4813 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4814 (float:MODEF
4815 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4816 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4817 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4818 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4819 "#"
4820 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4821 (set_attr "mode" "<MODEF:MODE>")
4822 (set_attr "unit" "*,i387,*,*")
4823 (set_attr "athlon_decode" "*,*,double,direct")
4824 (set_attr "amdfam10_decode" "*,*,vector,double")
4825 (set_attr "bdver1_decode" "*,*,double,direct")
4826 (set_attr "fp_int_src" "true")])
4827
4828 (define_split
4829 [(set (match_operand:MODEF 0 "register_operand" "")
4830 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4831 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4832 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4833 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4834 && TARGET_INTER_UNIT_CONVERSIONS
4835 && reload_completed
4836 && (SSE_REG_P (operands[0])
4837 || (GET_CODE (operands[0]) == SUBREG
4838 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4839 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4840
4841 (define_split
4842 [(set (match_operand:MODEF 0 "register_operand" "")
4843 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4844 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4845 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4846 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4847 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4848 && reload_completed
4849 && (SSE_REG_P (operands[0])
4850 || (GET_CODE (operands[0]) == SUBREG
4851 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4852 [(set (match_dup 2) (match_dup 1))
4853 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4854
4855 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4856 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4857 (float:MODEF
4858 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4859 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4860 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4861 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4862 "@
4863 fild%Z1\t%1
4864 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4865 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4866 [(set_attr "type" "fmov,sseicvt,sseicvt")
4867 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4868 (set_attr "mode" "<MODEF:MODE>")
4869 (set (attr "prefix_rex")
4870 (if_then_else
4871 (and (eq_attr "prefix" "maybe_vex")
4872 (match_test "<SWI48x:MODE>mode == DImode"))
4873 (const_string "1")
4874 (const_string "*")))
4875 (set_attr "unit" "i387,*,*")
4876 (set_attr "athlon_decode" "*,double,direct")
4877 (set_attr "amdfam10_decode" "*,vector,double")
4878 (set_attr "bdver1_decode" "*,double,direct")
4879 (set_attr "fp_int_src" "true")])
4880
4881 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4882 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4883 (float:MODEF
4884 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4885 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4886 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4887 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4888 "@
4889 fild%Z1\t%1
4890 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4891 [(set_attr "type" "fmov,sseicvt")
4892 (set_attr "prefix" "orig,maybe_vex")
4893 (set_attr "mode" "<MODEF:MODE>")
4894 (set (attr "prefix_rex")
4895 (if_then_else
4896 (and (eq_attr "prefix" "maybe_vex")
4897 (match_test "<SWI48x:MODE>mode == DImode"))
4898 (const_string "1")
4899 (const_string "*")))
4900 (set_attr "athlon_decode" "*,direct")
4901 (set_attr "amdfam10_decode" "*,double")
4902 (set_attr "bdver1_decode" "*,direct")
4903 (set_attr "fp_int_src" "true")])
4904
4905 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4906 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4907 (float:MODEF
4908 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4909 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4910 "TARGET_SSE2 && TARGET_SSE_MATH
4911 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4912 "#"
4913 [(set_attr "type" "sseicvt")
4914 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4915 (set_attr "athlon_decode" "double,direct,double")
4916 (set_attr "amdfam10_decode" "vector,double,double")
4917 (set_attr "bdver1_decode" "double,direct,double")
4918 (set_attr "fp_int_src" "true")])
4919
4920 (define_insn "*floatsi<mode>2_vector_sse"
4921 [(set (match_operand:MODEF 0 "register_operand" "=x")
4922 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4923 "TARGET_SSE2 && TARGET_SSE_MATH
4924 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4925 "#"
4926 [(set_attr "type" "sseicvt")
4927 (set_attr "mode" "<MODE>")
4928 (set_attr "athlon_decode" "direct")
4929 (set_attr "amdfam10_decode" "double")
4930 (set_attr "bdver1_decode" "direct")
4931 (set_attr "fp_int_src" "true")])
4932
4933 (define_split
4934 [(set (match_operand:MODEF 0 "register_operand" "")
4935 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4936 (clobber (match_operand:SI 2 "memory_operand" ""))]
4937 "TARGET_SSE2 && TARGET_SSE_MATH
4938 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4939 && reload_completed
4940 && (SSE_REG_P (operands[0])
4941 || (GET_CODE (operands[0]) == SUBREG
4942 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4943 [(const_int 0)]
4944 {
4945 rtx op1 = operands[1];
4946
4947 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4948 <MODE>mode, 0);
4949 if (GET_CODE (op1) == SUBREG)
4950 op1 = SUBREG_REG (op1);
4951
4952 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4953 {
4954 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4955 emit_insn (gen_sse2_loadld (operands[4],
4956 CONST0_RTX (V4SImode), operands[1]));
4957 }
4958 /* We can ignore possible trapping value in the
4959 high part of SSE register for non-trapping math. */
4960 else if (SSE_REG_P (op1) && !flag_trapping_math)
4961 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4962 else
4963 {
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965 emit_move_insn (operands[2], operands[1]);
4966 emit_insn (gen_sse2_loadld (operands[4],
4967 CONST0_RTX (V4SImode), operands[2]));
4968 }
4969 if (<ssevecmode>mode == V4SFmode)
4970 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4971 else
4972 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4973 DONE;
4974 })
4975
4976 (define_split
4977 [(set (match_operand:MODEF 0 "register_operand" "")
4978 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4979 (clobber (match_operand:SI 2 "memory_operand" ""))]
4980 "TARGET_SSE2 && TARGET_SSE_MATH
4981 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4982 && reload_completed
4983 && (SSE_REG_P (operands[0])
4984 || (GET_CODE (operands[0]) == SUBREG
4985 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4986 [(const_int 0)]
4987 {
4988 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4989 <MODE>mode, 0);
4990 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4991
4992 emit_insn (gen_sse2_loadld (operands[4],
4993 CONST0_RTX (V4SImode), operands[1]));
4994 if (<ssevecmode>mode == V4SFmode)
4995 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4996 else
4997 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4998 DONE;
4999 })
5000
5001 (define_split
5002 [(set (match_operand:MODEF 0 "register_operand" "")
5003 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5004 "TARGET_SSE2 && TARGET_SSE_MATH
5005 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5006 && reload_completed
5007 && (SSE_REG_P (operands[0])
5008 || (GET_CODE (operands[0]) == SUBREG
5009 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5010 [(const_int 0)]
5011 {
5012 rtx op1 = operands[1];
5013
5014 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5015 <MODE>mode, 0);
5016 if (GET_CODE (op1) == SUBREG)
5017 op1 = SUBREG_REG (op1);
5018
5019 if (GENERAL_REG_P (op1))
5020 {
5021 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5022 if (TARGET_INTER_UNIT_MOVES)
5023 emit_insn (gen_sse2_loadld (operands[4],
5024 CONST0_RTX (V4SImode), operands[1]));
5025 else
5026 {
5027 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5028 operands[1]);
5029 emit_insn (gen_sse2_loadld (operands[4],
5030 CONST0_RTX (V4SImode), operands[5]));
5031 ix86_free_from_memory (GET_MODE (operands[1]));
5032 }
5033 }
5034 /* We can ignore possible trapping value in the
5035 high part of SSE register for non-trapping math. */
5036 else if (SSE_REG_P (op1) && !flag_trapping_math)
5037 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5038 else
5039 gcc_unreachable ();
5040 if (<ssevecmode>mode == V4SFmode)
5041 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5042 else
5043 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5044 DONE;
5045 })
5046
5047 (define_split
5048 [(set (match_operand:MODEF 0 "register_operand" "")
5049 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5050 "TARGET_SSE2 && TARGET_SSE_MATH
5051 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5052 && reload_completed
5053 && (SSE_REG_P (operands[0])
5054 || (GET_CODE (operands[0]) == SUBREG
5055 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5056 [(const_int 0)]
5057 {
5058 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5059 <MODE>mode, 0);
5060 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5061
5062 emit_insn (gen_sse2_loadld (operands[4],
5063 CONST0_RTX (V4SImode), operands[1]));
5064 if (<ssevecmode>mode == V4SFmode)
5065 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5066 else
5067 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5068 DONE;
5069 })
5070
5071 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5072 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5073 (float:MODEF
5074 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5075 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5076 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5077 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5078 "#"
5079 [(set_attr "type" "sseicvt")
5080 (set_attr "mode" "<MODEF:MODE>")
5081 (set_attr "athlon_decode" "double,direct")
5082 (set_attr "amdfam10_decode" "vector,double")
5083 (set_attr "bdver1_decode" "double,direct")
5084 (set_attr "fp_int_src" "true")])
5085
5086 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5087 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5088 (float:MODEF
5089 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5090 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5091 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5092 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5093 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5094 [(set_attr "type" "sseicvt")
5095 (set_attr "prefix" "maybe_vex")
5096 (set_attr "mode" "<MODEF:MODE>")
5097 (set (attr "prefix_rex")
5098 (if_then_else
5099 (and (eq_attr "prefix" "maybe_vex")
5100 (match_test "<SWI48x:MODE>mode == DImode"))
5101 (const_string "1")
5102 (const_string "*")))
5103 (set_attr "athlon_decode" "double,direct")
5104 (set_attr "amdfam10_decode" "vector,double")
5105 (set_attr "bdver1_decode" "double,direct")
5106 (set_attr "fp_int_src" "true")])
5107
5108 (define_split
5109 [(set (match_operand:MODEF 0 "register_operand" "")
5110 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5111 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5112 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5113 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5114 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5115 && reload_completed
5116 && (SSE_REG_P (operands[0])
5117 || (GET_CODE (operands[0]) == SUBREG
5118 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5119 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5120
5121 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5122 [(set (match_operand:MODEF 0 "register_operand" "=x")
5123 (float:MODEF
5124 (match_operand:SWI48x 1 "memory_operand" "m")))]
5125 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5126 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5127 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5128 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5129 [(set_attr "type" "sseicvt")
5130 (set_attr "prefix" "maybe_vex")
5131 (set_attr "mode" "<MODEF:MODE>")
5132 (set (attr "prefix_rex")
5133 (if_then_else
5134 (and (eq_attr "prefix" "maybe_vex")
5135 (match_test "<SWI48x:MODE>mode == DImode"))
5136 (const_string "1")
5137 (const_string "*")))
5138 (set_attr "athlon_decode" "direct")
5139 (set_attr "amdfam10_decode" "double")
5140 (set_attr "bdver1_decode" "direct")
5141 (set_attr "fp_int_src" "true")])
5142
5143 (define_split
5144 [(set (match_operand:MODEF 0 "register_operand" "")
5145 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5146 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5147 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5148 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5149 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5150 && reload_completed
5151 && (SSE_REG_P (operands[0])
5152 || (GET_CODE (operands[0]) == SUBREG
5153 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5154 [(set (match_dup 2) (match_dup 1))
5155 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5156
5157 (define_split
5158 [(set (match_operand:MODEF 0 "register_operand" "")
5159 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5160 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5161 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5162 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5163 && reload_completed
5164 && (SSE_REG_P (operands[0])
5165 || (GET_CODE (operands[0]) == SUBREG
5166 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5167 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5168
5169 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5170 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5171 (float:X87MODEF
5172 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5173 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5174 "TARGET_80387
5175 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5176 "@
5177 fild%Z1\t%1
5178 #"
5179 [(set_attr "type" "fmov,multi")
5180 (set_attr "mode" "<X87MODEF:MODE>")
5181 (set_attr "unit" "*,i387")
5182 (set_attr "fp_int_src" "true")])
5183
5184 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5185 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5186 (float:X87MODEF
5187 (match_operand:SWI48x 1 "memory_operand" "m")))]
5188 "TARGET_80387
5189 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5190 "fild%Z1\t%1"
5191 [(set_attr "type" "fmov")
5192 (set_attr "mode" "<X87MODEF:MODE>")
5193 (set_attr "fp_int_src" "true")])
5194
5195 (define_split
5196 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5197 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5198 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5199 "TARGET_80387
5200 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5201 && reload_completed"
5202 [(set (match_dup 2) (match_dup 1))
5203 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5204
5205 (define_split
5206 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5207 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5208 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5209 "TARGET_80387
5210 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5211 && reload_completed"
5212 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5213
5214 ;; Avoid store forwarding (partial memory) stall penalty
5215 ;; by passing DImode value through XMM registers. */
5216
5217 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5218 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5219 (float:X87MODEF
5220 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5221 (clobber (match_scratch:V4SI 3 "=X,x"))
5222 (clobber (match_scratch:V4SI 4 "=X,x"))
5223 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5224 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5225 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5226 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5227 "#"
5228 [(set_attr "type" "multi")
5229 (set_attr "mode" "<X87MODEF:MODE>")
5230 (set_attr "unit" "i387")
5231 (set_attr "fp_int_src" "true")])
5232
5233 (define_split
5234 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5235 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5236 (clobber (match_scratch:V4SI 3 ""))
5237 (clobber (match_scratch:V4SI 4 ""))
5238 (clobber (match_operand:DI 2 "memory_operand" ""))]
5239 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5240 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5241 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5242 && reload_completed"
5243 [(set (match_dup 2) (match_dup 3))
5244 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5245 {
5246 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5247 Assemble the 64-bit DImode value in an xmm register. */
5248 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5249 gen_rtx_SUBREG (SImode, operands[1], 0)));
5250 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5251 gen_rtx_SUBREG (SImode, operands[1], 4)));
5252 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5253 operands[4]));
5254
5255 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5256 })
5257
5258 (define_split
5259 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5260 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5261 (clobber (match_scratch:V4SI 3 ""))
5262 (clobber (match_scratch:V4SI 4 ""))
5263 (clobber (match_operand:DI 2 "memory_operand" ""))]
5264 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5265 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5266 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5267 && reload_completed"
5268 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5269
5270 ;; Avoid store forwarding (partial memory) stall penalty by extending
5271 ;; SImode value to DImode through XMM register instead of pushing two
5272 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5273 ;; targets benefit from this optimization. Also note that fild
5274 ;; loads from memory only.
5275
5276 (define_insn "*floatunssi<mode>2_1"
5277 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5278 (unsigned_float:X87MODEF
5279 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5280 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5281 (clobber (match_scratch:SI 3 "=X,x"))]
5282 "!TARGET_64BIT
5283 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5284 && TARGET_SSE"
5285 "#"
5286 [(set_attr "type" "multi")
5287 (set_attr "mode" "<MODE>")])
5288
5289 (define_split
5290 [(set (match_operand:X87MODEF 0 "register_operand" "")
5291 (unsigned_float:X87MODEF
5292 (match_operand:SI 1 "register_operand" "")))
5293 (clobber (match_operand:DI 2 "memory_operand" ""))
5294 (clobber (match_scratch:SI 3 ""))]
5295 "!TARGET_64BIT
5296 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5297 && TARGET_SSE
5298 && reload_completed"
5299 [(set (match_dup 2) (match_dup 1))
5300 (set (match_dup 0)
5301 (float:X87MODEF (match_dup 2)))]
5302 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5303
5304 (define_split
5305 [(set (match_operand:X87MODEF 0 "register_operand" "")
5306 (unsigned_float:X87MODEF
5307 (match_operand:SI 1 "memory_operand" "")))
5308 (clobber (match_operand:DI 2 "memory_operand" ""))
5309 (clobber (match_scratch:SI 3 ""))]
5310 "!TARGET_64BIT
5311 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5312 && TARGET_SSE
5313 && reload_completed"
5314 [(set (match_dup 2) (match_dup 3))
5315 (set (match_dup 0)
5316 (float:X87MODEF (match_dup 2)))]
5317 {
5318 emit_move_insn (operands[3], operands[1]);
5319 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5320 })
5321
5322 (define_expand "floatunssi<mode>2"
5323 [(parallel
5324 [(set (match_operand:X87MODEF 0 "register_operand" "")
5325 (unsigned_float:X87MODEF
5326 (match_operand:SI 1 "nonimmediate_operand" "")))
5327 (clobber (match_dup 2))
5328 (clobber (match_scratch:SI 3 ""))])]
5329 "!TARGET_64BIT
5330 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5331 && TARGET_SSE)
5332 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5333 {
5334 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5335 {
5336 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5337 DONE;
5338 }
5339 else
5340 {
5341 enum ix86_stack_slot slot = (virtuals_instantiated
5342 ? SLOT_TEMP
5343 : SLOT_VIRTUAL);
5344 operands[2] = assign_386_stack_local (DImode, slot);
5345 }
5346 })
5347
5348 (define_expand "floatunsdisf2"
5349 [(use (match_operand:SF 0 "register_operand" ""))
5350 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5351 "TARGET_64BIT && TARGET_SSE_MATH"
5352 "x86_emit_floatuns (operands); DONE;")
5353
5354 (define_expand "floatunsdidf2"
5355 [(use (match_operand:DF 0 "register_operand" ""))
5356 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5357 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5358 && TARGET_SSE2 && TARGET_SSE_MATH"
5359 {
5360 if (TARGET_64BIT)
5361 x86_emit_floatuns (operands);
5362 else
5363 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5364 DONE;
5365 })
5366 \f
5367 ;; Add instructions
5368
5369 (define_expand "add<mode>3"
5370 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5371 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5372 (match_operand:SDWIM 2 "<general_operand>" "")))]
5373 ""
5374 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5375
5376 (define_insn_and_split "*add<dwi>3_doubleword"
5377 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5378 (plus:<DWI>
5379 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5380 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5381 (clobber (reg:CC FLAGS_REG))]
5382 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5383 "#"
5384 "reload_completed"
5385 [(parallel [(set (reg:CC FLAGS_REG)
5386 (unspec:CC [(match_dup 1) (match_dup 2)]
5387 UNSPEC_ADD_CARRY))
5388 (set (match_dup 0)
5389 (plus:DWIH (match_dup 1) (match_dup 2)))])
5390 (parallel [(set (match_dup 3)
5391 (plus:DWIH
5392 (match_dup 4)
5393 (plus:DWIH
5394 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5395 (match_dup 5))))
5396 (clobber (reg:CC FLAGS_REG))])]
5397 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5398
5399 (define_insn "*add<mode>3_cc"
5400 [(set (reg:CC FLAGS_REG)
5401 (unspec:CC
5402 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5403 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5404 UNSPEC_ADD_CARRY))
5405 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5406 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5407 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5408 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5409 [(set_attr "type" "alu")
5410 (set_attr "mode" "<MODE>")])
5411
5412 (define_insn "addqi3_cc"
5413 [(set (reg:CC FLAGS_REG)
5414 (unspec:CC
5415 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5416 (match_operand:QI 2 "general_operand" "qn,qm")]
5417 UNSPEC_ADD_CARRY))
5418 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5419 (plus:QI (match_dup 1) (match_dup 2)))]
5420 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5421 "add{b}\t{%2, %0|%0, %2}"
5422 [(set_attr "type" "alu")
5423 (set_attr "mode" "QI")])
5424
5425 (define_insn_and_split "*lea_1"
5426 [(set (match_operand:SI 0 "register_operand" "=r")
5427 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5428 "TARGET_64BIT"
5429 "lea{l}\t{%a1, %0|%0, %a1}"
5430 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5431 [(const_int 0)]
5432 {
5433 ix86_split_lea_for_addr (operands, SImode);
5434 DONE;
5435 }
5436 [(set_attr "type" "lea")
5437 (set_attr "mode" "SI")])
5438
5439 (define_insn_and_split "*lea<mode>_2"
5440 [(set (match_operand:SWI48 0 "register_operand" "=r")
5441 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5442 ""
5443 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5444 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5445 [(const_int 0)]
5446 {
5447 ix86_split_lea_for_addr (operands, <MODE>mode);
5448 DONE;
5449 }
5450 [(set_attr "type" "lea")
5451 (set_attr "mode" "<MODE>")])
5452
5453 (define_insn "*lea_3_zext"
5454 [(set (match_operand:DI 0 "register_operand" "=r")
5455 (zero_extend:DI
5456 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5457 "TARGET_64BIT"
5458 "lea{l}\t{%a1, %k0|%k0, %a1}"
5459 [(set_attr "type" "lea")
5460 (set_attr "mode" "SI")])
5461
5462 (define_insn "*lea_4_zext"
5463 [(set (match_operand:DI 0 "register_operand" "=r")
5464 (zero_extend:DI
5465 (match_operand:SI 1 "lea_address_operand" "j")))]
5466 "TARGET_64BIT"
5467 "lea{l}\t{%a1, %k0|%k0, %a1}"
5468 [(set_attr "type" "lea")
5469 (set_attr "mode" "SI")])
5470
5471 (define_insn "*lea_5_zext"
5472 [(set (match_operand:DI 0 "register_operand" "=r")
5473 (and:DI
5474 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5475 (match_operand:DI 2 "const_32bit_mask" "n")))]
5476 "TARGET_64BIT"
5477 "lea{l}\t{%a1, %k0|%k0, %a1}"
5478 [(set_attr "type" "lea")
5479 (set_attr "mode" "SI")])
5480
5481 (define_insn "*lea_6_zext"
5482 [(set (match_operand:DI 0 "register_operand" "=r")
5483 (and:DI
5484 (match_operand:DI 1 "lea_address_operand" "p")
5485 (match_operand:DI 2 "const_32bit_mask" "n")))]
5486 "TARGET_64BIT"
5487 "lea{l}\t{%a1, %k0|%k0, %a1}"
5488 [(set_attr "type" "lea")
5489 (set_attr "mode" "SI")])
5490
5491 (define_insn "*add<mode>_1"
5492 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5493 (plus:SWI48
5494 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5495 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5496 (clobber (reg:CC FLAGS_REG))]
5497 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5498 {
5499 switch (get_attr_type (insn))
5500 {
5501 case TYPE_LEA:
5502 return "#";
5503
5504 case TYPE_INCDEC:
5505 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5506 if (operands[2] == const1_rtx)
5507 return "inc{<imodesuffix>}\t%0";
5508 else
5509 {
5510 gcc_assert (operands[2] == constm1_rtx);
5511 return "dec{<imodesuffix>}\t%0";
5512 }
5513
5514 default:
5515 /* For most processors, ADD is faster than LEA. This alternative
5516 was added to use ADD as much as possible. */
5517 if (which_alternative == 2)
5518 {
5519 rtx tmp;
5520 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5521 }
5522
5523 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5524 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5525 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5526
5527 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5528 }
5529 }
5530 [(set (attr "type")
5531 (cond [(eq_attr "alternative" "3")
5532 (const_string "lea")
5533 (match_operand:SWI48 2 "incdec_operand" "")
5534 (const_string "incdec")
5535 ]
5536 (const_string "alu")))
5537 (set (attr "length_immediate")
5538 (if_then_else
5539 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5540 (const_string "1")
5541 (const_string "*")))
5542 (set_attr "mode" "<MODE>")])
5543
5544 ;; It may seem that nonimmediate operand is proper one for operand 1.
5545 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5546 ;; we take care in ix86_binary_operator_ok to not allow two memory
5547 ;; operands so proper swapping will be done in reload. This allow
5548 ;; patterns constructed from addsi_1 to match.
5549
5550 (define_insn "addsi_1_zext"
5551 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5552 (zero_extend:DI
5553 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5554 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5555 (clobber (reg:CC FLAGS_REG))]
5556 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5557 {
5558 switch (get_attr_type (insn))
5559 {
5560 case TYPE_LEA:
5561 return "#";
5562
5563 case TYPE_INCDEC:
5564 if (operands[2] == const1_rtx)
5565 return "inc{l}\t%k0";
5566 else
5567 {
5568 gcc_assert (operands[2] == constm1_rtx);
5569 return "dec{l}\t%k0";
5570 }
5571
5572 default:
5573 /* For most processors, ADD is faster than LEA. This alternative
5574 was added to use ADD as much as possible. */
5575 if (which_alternative == 1)
5576 {
5577 rtx tmp;
5578 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5579 }
5580
5581 if (x86_maybe_negate_const_int (&operands[2], SImode))
5582 return "sub{l}\t{%2, %k0|%k0, %2}";
5583
5584 return "add{l}\t{%2, %k0|%k0, %2}";
5585 }
5586 }
5587 [(set (attr "type")
5588 (cond [(eq_attr "alternative" "2")
5589 (const_string "lea")
5590 (match_operand:SI 2 "incdec_operand" "")
5591 (const_string "incdec")
5592 ]
5593 (const_string "alu")))
5594 (set (attr "length_immediate")
5595 (if_then_else
5596 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5597 (const_string "1")
5598 (const_string "*")))
5599 (set_attr "mode" "SI")])
5600
5601 (define_insn "*addhi_1"
5602 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5603 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5604 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5605 (clobber (reg:CC FLAGS_REG))]
5606 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5607 {
5608 switch (get_attr_type (insn))
5609 {
5610 case TYPE_LEA:
5611 return "#";
5612
5613 case TYPE_INCDEC:
5614 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5615 if (operands[2] == const1_rtx)
5616 return "inc{w}\t%0";
5617 else
5618 {
5619 gcc_assert (operands[2] == constm1_rtx);
5620 return "dec{w}\t%0";
5621 }
5622
5623 default:
5624 /* For most processors, ADD is faster than LEA. This alternative
5625 was added to use ADD as much as possible. */
5626 if (which_alternative == 2)
5627 {
5628 rtx tmp;
5629 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5630 }
5631
5632 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5633 if (x86_maybe_negate_const_int (&operands[2], HImode))
5634 return "sub{w}\t{%2, %0|%0, %2}";
5635
5636 return "add{w}\t{%2, %0|%0, %2}";
5637 }
5638 }
5639 [(set (attr "type")
5640 (cond [(eq_attr "alternative" "3")
5641 (const_string "lea")
5642 (match_operand:HI 2 "incdec_operand" "")
5643 (const_string "incdec")
5644 ]
5645 (const_string "alu")))
5646 (set (attr "length_immediate")
5647 (if_then_else
5648 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5649 (const_string "1")
5650 (const_string "*")))
5651 (set_attr "mode" "HI,HI,HI,SI")])
5652
5653 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5654 (define_insn "*addqi_1"
5655 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5656 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5657 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5658 (clobber (reg:CC FLAGS_REG))]
5659 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5660 {
5661 bool widen = (which_alternative == 3 || which_alternative == 4);
5662
5663 switch (get_attr_type (insn))
5664 {
5665 case TYPE_LEA:
5666 return "#";
5667
5668 case TYPE_INCDEC:
5669 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5670 if (operands[2] == const1_rtx)
5671 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5672 else
5673 {
5674 gcc_assert (operands[2] == constm1_rtx);
5675 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5676 }
5677
5678 default:
5679 /* For most processors, ADD is faster than LEA. These alternatives
5680 were added to use ADD as much as possible. */
5681 if (which_alternative == 2 || which_alternative == 4)
5682 {
5683 rtx tmp;
5684 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5685 }
5686
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688 if (x86_maybe_negate_const_int (&operands[2], QImode))
5689 {
5690 if (widen)
5691 return "sub{l}\t{%2, %k0|%k0, %2}";
5692 else
5693 return "sub{b}\t{%2, %0|%0, %2}";
5694 }
5695 if (widen)
5696 return "add{l}\t{%k2, %k0|%k0, %k2}";
5697 else
5698 return "add{b}\t{%2, %0|%0, %2}";
5699 }
5700 }
5701 [(set (attr "type")
5702 (cond [(eq_attr "alternative" "5")
5703 (const_string "lea")
5704 (match_operand:QI 2 "incdec_operand" "")
5705 (const_string "incdec")
5706 ]
5707 (const_string "alu")))
5708 (set (attr "length_immediate")
5709 (if_then_else
5710 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5711 (const_string "1")
5712 (const_string "*")))
5713 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5714
5715 (define_insn "*addqi_1_slp"
5716 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5717 (plus:QI (match_dup 0)
5718 (match_operand:QI 1 "general_operand" "qn,qm")))
5719 (clobber (reg:CC FLAGS_REG))]
5720 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5721 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5722 {
5723 switch (get_attr_type (insn))
5724 {
5725 case TYPE_INCDEC:
5726 if (operands[1] == const1_rtx)
5727 return "inc{b}\t%0";
5728 else
5729 {
5730 gcc_assert (operands[1] == constm1_rtx);
5731 return "dec{b}\t%0";
5732 }
5733
5734 default:
5735 if (x86_maybe_negate_const_int (&operands[1], QImode))
5736 return "sub{b}\t{%1, %0|%0, %1}";
5737
5738 return "add{b}\t{%1, %0|%0, %1}";
5739 }
5740 }
5741 [(set (attr "type")
5742 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5743 (const_string "incdec")
5744 (const_string "alu1")))
5745 (set (attr "memory")
5746 (if_then_else (match_operand 1 "memory_operand" "")
5747 (const_string "load")
5748 (const_string "none")))
5749 (set_attr "mode" "QI")])
5750
5751 ;; Split non destructive adds if we cannot use lea.
5752 (define_split
5753 [(set (match_operand:SWI48 0 "register_operand" "")
5754 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5755 (match_operand:SWI48 2 "nonmemory_operand" "")))
5756 (clobber (reg:CC FLAGS_REG))]
5757 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5758 [(set (match_dup 0) (match_dup 1))
5759 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5760 (clobber (reg:CC FLAGS_REG))])])
5761
5762 ;; Convert add to the lea pattern to avoid flags dependency.
5763 (define_split
5764 [(set (match_operand:SWI 0 "register_operand" "")
5765 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5766 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5769 [(const_int 0)]
5770 {
5771 enum machine_mode mode = <MODE>mode;
5772 rtx pat;
5773
5774 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5775 {
5776 mode = SImode;
5777 operands[0] = gen_lowpart (mode, operands[0]);
5778 operands[1] = gen_lowpart (mode, operands[1]);
5779 operands[2] = gen_lowpart (mode, operands[2]);
5780 }
5781
5782 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5783
5784 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5785 DONE;
5786 })
5787
5788 ;; Convert add to the lea pattern to avoid flags dependency.
5789 (define_split
5790 [(set (match_operand:DI 0 "register_operand" "")
5791 (zero_extend:DI
5792 (plus:SI (match_operand:SI 1 "register_operand" "")
5793 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5794 (clobber (reg:CC FLAGS_REG))]
5795 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5796 [(set (match_dup 0)
5797 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5798
5799 (define_insn "*add<mode>_2"
5800 [(set (reg FLAGS_REG)
5801 (compare
5802 (plus:SWI
5803 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5804 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5805 (const_int 0)))
5806 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5807 (plus:SWI (match_dup 1) (match_dup 2)))]
5808 "ix86_match_ccmode (insn, CCGOCmode)
5809 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5810 {
5811 switch (get_attr_type (insn))
5812 {
5813 case TYPE_INCDEC:
5814 if (operands[2] == const1_rtx)
5815 return "inc{<imodesuffix>}\t%0";
5816 else
5817 {
5818 gcc_assert (operands[2] == constm1_rtx);
5819 return "dec{<imodesuffix>}\t%0";
5820 }
5821
5822 default:
5823 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5824 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5825
5826 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5827 }
5828 }
5829 [(set (attr "type")
5830 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5831 (const_string "incdec")
5832 (const_string "alu")))
5833 (set (attr "length_immediate")
5834 (if_then_else
5835 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5836 (const_string "1")
5837 (const_string "*")))
5838 (set_attr "mode" "<MODE>")])
5839
5840 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5841 (define_insn "*addsi_2_zext"
5842 [(set (reg FLAGS_REG)
5843 (compare
5844 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5845 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5846 (const_int 0)))
5847 (set (match_operand:DI 0 "register_operand" "=r")
5848 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5849 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5850 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5851 {
5852 switch (get_attr_type (insn))
5853 {
5854 case TYPE_INCDEC:
5855 if (operands[2] == const1_rtx)
5856 return "inc{l}\t%k0";
5857 else
5858 {
5859 gcc_assert (operands[2] == constm1_rtx);
5860 return "dec{l}\t%k0";
5861 }
5862
5863 default:
5864 if (x86_maybe_negate_const_int (&operands[2], SImode))
5865 return "sub{l}\t{%2, %k0|%k0, %2}";
5866
5867 return "add{l}\t{%2, %k0|%k0, %2}";
5868 }
5869 }
5870 [(set (attr "type")
5871 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5872 (const_string "incdec")
5873 (const_string "alu")))
5874 (set (attr "length_immediate")
5875 (if_then_else
5876 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5877 (const_string "1")
5878 (const_string "*")))
5879 (set_attr "mode" "SI")])
5880
5881 (define_insn "*add<mode>_3"
5882 [(set (reg FLAGS_REG)
5883 (compare
5884 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5885 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5886 (clobber (match_scratch:SWI 0 "=<r>"))]
5887 "ix86_match_ccmode (insn, CCZmode)
5888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5889 {
5890 switch (get_attr_type (insn))
5891 {
5892 case TYPE_INCDEC:
5893 if (operands[2] == const1_rtx)
5894 return "inc{<imodesuffix>}\t%0";
5895 else
5896 {
5897 gcc_assert (operands[2] == constm1_rtx);
5898 return "dec{<imodesuffix>}\t%0";
5899 }
5900
5901 default:
5902 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5903 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5904
5905 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5906 }
5907 }
5908 [(set (attr "type")
5909 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5910 (const_string "incdec")
5911 (const_string "alu")))
5912 (set (attr "length_immediate")
5913 (if_then_else
5914 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5915 (const_string "1")
5916 (const_string "*")))
5917 (set_attr "mode" "<MODE>")])
5918
5919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5920 (define_insn "*addsi_3_zext"
5921 [(set (reg FLAGS_REG)
5922 (compare
5923 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5924 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5925 (set (match_operand:DI 0 "register_operand" "=r")
5926 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5927 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5928 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5929 {
5930 switch (get_attr_type (insn))
5931 {
5932 case TYPE_INCDEC:
5933 if (operands[2] == const1_rtx)
5934 return "inc{l}\t%k0";
5935 else
5936 {
5937 gcc_assert (operands[2] == constm1_rtx);
5938 return "dec{l}\t%k0";
5939 }
5940
5941 default:
5942 if (x86_maybe_negate_const_int (&operands[2], SImode))
5943 return "sub{l}\t{%2, %k0|%k0, %2}";
5944
5945 return "add{l}\t{%2, %k0|%k0, %2}";
5946 }
5947 }
5948 [(set (attr "type")
5949 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5950 (const_string "incdec")
5951 (const_string "alu")))
5952 (set (attr "length_immediate")
5953 (if_then_else
5954 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5955 (const_string "1")
5956 (const_string "*")))
5957 (set_attr "mode" "SI")])
5958
5959 ; For comparisons against 1, -1 and 128, we may generate better code
5960 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5961 ; is matched then. We can't accept general immediate, because for
5962 ; case of overflows, the result is messed up.
5963 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5964 ; only for comparisons not depending on it.
5965
5966 (define_insn "*adddi_4"
5967 [(set (reg FLAGS_REG)
5968 (compare
5969 (match_operand:DI 1 "nonimmediate_operand" "0")
5970 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5971 (clobber (match_scratch:DI 0 "=rm"))]
5972 "TARGET_64BIT
5973 && ix86_match_ccmode (insn, CCGCmode)"
5974 {
5975 switch (get_attr_type (insn))
5976 {
5977 case TYPE_INCDEC:
5978 if (operands[2] == constm1_rtx)
5979 return "inc{q}\t%0";
5980 else
5981 {
5982 gcc_assert (operands[2] == const1_rtx);
5983 return "dec{q}\t%0";
5984 }
5985
5986 default:
5987 if (x86_maybe_negate_const_int (&operands[2], DImode))
5988 return "add{q}\t{%2, %0|%0, %2}";
5989
5990 return "sub{q}\t{%2, %0|%0, %2}";
5991 }
5992 }
5993 [(set (attr "type")
5994 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5995 (const_string "incdec")
5996 (const_string "alu")))
5997 (set (attr "length_immediate")
5998 (if_then_else
5999 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6000 (const_string "1")
6001 (const_string "*")))
6002 (set_attr "mode" "DI")])
6003
6004 ; For comparisons against 1, -1 and 128, we may generate better code
6005 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6006 ; is matched then. We can't accept general immediate, because for
6007 ; case of overflows, the result is messed up.
6008 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6009 ; only for comparisons not depending on it.
6010
6011 (define_insn "*add<mode>_4"
6012 [(set (reg FLAGS_REG)
6013 (compare
6014 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6015 (match_operand:SWI124 2 "const_int_operand" "n")))
6016 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6017 "ix86_match_ccmode (insn, CCGCmode)"
6018 {
6019 switch (get_attr_type (insn))
6020 {
6021 case TYPE_INCDEC:
6022 if (operands[2] == constm1_rtx)
6023 return "inc{<imodesuffix>}\t%0";
6024 else
6025 {
6026 gcc_assert (operands[2] == const1_rtx);
6027 return "dec{<imodesuffix>}\t%0";
6028 }
6029
6030 default:
6031 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6032 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6033
6034 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6035 }
6036 }
6037 [(set (attr "type")
6038 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6039 (const_string "incdec")
6040 (const_string "alu")))
6041 (set (attr "length_immediate")
6042 (if_then_else
6043 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6044 (const_string "1")
6045 (const_string "*")))
6046 (set_attr "mode" "<MODE>")])
6047
6048 (define_insn "*add<mode>_5"
6049 [(set (reg FLAGS_REG)
6050 (compare
6051 (plus:SWI
6052 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6053 (match_operand:SWI 2 "<general_operand>" "<g>"))
6054 (const_int 0)))
6055 (clobber (match_scratch:SWI 0 "=<r>"))]
6056 "ix86_match_ccmode (insn, CCGOCmode)
6057 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6058 {
6059 switch (get_attr_type (insn))
6060 {
6061 case TYPE_INCDEC:
6062 if (operands[2] == const1_rtx)
6063 return "inc{<imodesuffix>}\t%0";
6064 else
6065 {
6066 gcc_assert (operands[2] == constm1_rtx);
6067 return "dec{<imodesuffix>}\t%0";
6068 }
6069
6070 default:
6071 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6072 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6073
6074 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6075 }
6076 }
6077 [(set (attr "type")
6078 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6079 (const_string "incdec")
6080 (const_string "alu")))
6081 (set (attr "length_immediate")
6082 (if_then_else
6083 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6084 (const_string "1")
6085 (const_string "*")))
6086 (set_attr "mode" "<MODE>")])
6087
6088 (define_insn "*addqi_ext_1_rex64"
6089 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6090 (const_int 8)
6091 (const_int 8))
6092 (plus:SI
6093 (zero_extract:SI
6094 (match_operand 1 "ext_register_operand" "0")
6095 (const_int 8)
6096 (const_int 8))
6097 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6098 (clobber (reg:CC FLAGS_REG))]
6099 "TARGET_64BIT"
6100 {
6101 switch (get_attr_type (insn))
6102 {
6103 case TYPE_INCDEC:
6104 if (operands[2] == const1_rtx)
6105 return "inc{b}\t%h0";
6106 else
6107 {
6108 gcc_assert (operands[2] == constm1_rtx);
6109 return "dec{b}\t%h0";
6110 }
6111
6112 default:
6113 return "add{b}\t{%2, %h0|%h0, %2}";
6114 }
6115 }
6116 [(set (attr "type")
6117 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6118 (const_string "incdec")
6119 (const_string "alu")))
6120 (set_attr "modrm" "1")
6121 (set_attr "mode" "QI")])
6122
6123 (define_insn "addqi_ext_1"
6124 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6125 (const_int 8)
6126 (const_int 8))
6127 (plus:SI
6128 (zero_extract:SI
6129 (match_operand 1 "ext_register_operand" "0")
6130 (const_int 8)
6131 (const_int 8))
6132 (match_operand:QI 2 "general_operand" "Qmn")))
6133 (clobber (reg:CC FLAGS_REG))]
6134 "!TARGET_64BIT"
6135 {
6136 switch (get_attr_type (insn))
6137 {
6138 case TYPE_INCDEC:
6139 if (operands[2] == const1_rtx)
6140 return "inc{b}\t%h0";
6141 else
6142 {
6143 gcc_assert (operands[2] == constm1_rtx);
6144 return "dec{b}\t%h0";
6145 }
6146
6147 default:
6148 return "add{b}\t{%2, %h0|%h0, %2}";
6149 }
6150 }
6151 [(set (attr "type")
6152 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6153 (const_string "incdec")
6154 (const_string "alu")))
6155 (set_attr "modrm" "1")
6156 (set_attr "mode" "QI")])
6157
6158 (define_insn "*addqi_ext_2"
6159 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6160 (const_int 8)
6161 (const_int 8))
6162 (plus:SI
6163 (zero_extract:SI
6164 (match_operand 1 "ext_register_operand" "%0")
6165 (const_int 8)
6166 (const_int 8))
6167 (zero_extract:SI
6168 (match_operand 2 "ext_register_operand" "Q")
6169 (const_int 8)
6170 (const_int 8))))
6171 (clobber (reg:CC FLAGS_REG))]
6172 ""
6173 "add{b}\t{%h2, %h0|%h0, %h2}"
6174 [(set_attr "type" "alu")
6175 (set_attr "mode" "QI")])
6176
6177 ;; The lea patterns for modes less than 32 bits need to be matched by
6178 ;; several insns converted to real lea by splitters.
6179
6180 (define_insn_and_split "*lea_general_1"
6181 [(set (match_operand 0 "register_operand" "=r")
6182 (plus (plus (match_operand 1 "index_register_operand" "l")
6183 (match_operand 2 "register_operand" "r"))
6184 (match_operand 3 "immediate_operand" "i")))]
6185 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6186 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6187 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6188 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6189 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6190 || GET_MODE (operands[3]) == VOIDmode)"
6191 "#"
6192 "&& reload_completed"
6193 [(const_int 0)]
6194 {
6195 enum machine_mode mode = SImode;
6196 rtx pat;
6197
6198 operands[0] = gen_lowpart (mode, operands[0]);
6199 operands[1] = gen_lowpart (mode, operands[1]);
6200 operands[2] = gen_lowpart (mode, operands[2]);
6201 operands[3] = gen_lowpart (mode, operands[3]);
6202
6203 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6204 operands[3]);
6205
6206 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6207 DONE;
6208 }
6209 [(set_attr "type" "lea")
6210 (set_attr "mode" "SI")])
6211
6212 (define_insn_and_split "*lea_general_2"
6213 [(set (match_operand 0 "register_operand" "=r")
6214 (plus (mult (match_operand 1 "index_register_operand" "l")
6215 (match_operand 2 "const248_operand" "n"))
6216 (match_operand 3 "nonmemory_operand" "ri")))]
6217 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6218 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6219 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6220 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6221 || GET_MODE (operands[3]) == VOIDmode)"
6222 "#"
6223 "&& reload_completed"
6224 [(const_int 0)]
6225 {
6226 enum machine_mode mode = SImode;
6227 rtx pat;
6228
6229 operands[0] = gen_lowpart (mode, operands[0]);
6230 operands[1] = gen_lowpart (mode, operands[1]);
6231 operands[3] = gen_lowpart (mode, operands[3]);
6232
6233 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6234 operands[3]);
6235
6236 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6237 DONE;
6238 }
6239 [(set_attr "type" "lea")
6240 (set_attr "mode" "SI")])
6241
6242 (define_insn_and_split "*lea_general_3"
6243 [(set (match_operand 0 "register_operand" "=r")
6244 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6245 (match_operand 2 "const248_operand" "n"))
6246 (match_operand 3 "register_operand" "r"))
6247 (match_operand 4 "immediate_operand" "i")))]
6248 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6249 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6250 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6251 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6252 "#"
6253 "&& reload_completed"
6254 [(const_int 0)]
6255 {
6256 enum machine_mode mode = SImode;
6257 rtx pat;
6258
6259 operands[0] = gen_lowpart (mode, operands[0]);
6260 operands[1] = gen_lowpart (mode, operands[1]);
6261 operands[3] = gen_lowpart (mode, operands[3]);
6262 operands[4] = gen_lowpart (mode, operands[4]);
6263
6264 pat = gen_rtx_PLUS (mode,
6265 gen_rtx_PLUS (mode,
6266 gen_rtx_MULT (mode, operands[1],
6267 operands[2]),
6268 operands[3]),
6269 operands[4]);
6270
6271 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6272 DONE;
6273 }
6274 [(set_attr "type" "lea")
6275 (set_attr "mode" "SI")])
6276
6277 (define_insn_and_split "*lea_general_4"
6278 [(set (match_operand 0 "register_operand" "=r")
6279 (any_or (ashift
6280 (match_operand 1 "index_register_operand" "l")
6281 (match_operand 2 "const_int_operand" "n"))
6282 (match_operand 3 "const_int_operand" "n")))]
6283 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6284 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6285 || GET_MODE (operands[0]) == SImode
6286 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6287 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6288 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6289 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6290 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6291 "#"
6292 "&& reload_completed"
6293 [(const_int 0)]
6294 {
6295 enum machine_mode mode = GET_MODE (operands[0]);
6296 rtx pat;
6297
6298 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6299 {
6300 mode = SImode;
6301 operands[0] = gen_lowpart (mode, operands[0]);
6302 operands[1] = gen_lowpart (mode, operands[1]);
6303 }
6304
6305 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6306
6307 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6308 INTVAL (operands[3]));
6309
6310 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6311 DONE;
6312 }
6313 [(set_attr "type" "lea")
6314 (set (attr "mode")
6315 (if_then_else (match_operand:DI 0 "" "")
6316 (const_string "DI")
6317 (const_string "SI")))])
6318 \f
6319 ;; Subtract instructions
6320
6321 (define_expand "sub<mode>3"
6322 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6323 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6324 (match_operand:SDWIM 2 "<general_operand>" "")))]
6325 ""
6326 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6327
6328 (define_insn_and_split "*sub<dwi>3_doubleword"
6329 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6330 (minus:<DWI>
6331 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6332 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6333 (clobber (reg:CC FLAGS_REG))]
6334 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6335 "#"
6336 "reload_completed"
6337 [(parallel [(set (reg:CC FLAGS_REG)
6338 (compare:CC (match_dup 1) (match_dup 2)))
6339 (set (match_dup 0)
6340 (minus:DWIH (match_dup 1) (match_dup 2)))])
6341 (parallel [(set (match_dup 3)
6342 (minus:DWIH
6343 (match_dup 4)
6344 (plus:DWIH
6345 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6346 (match_dup 5))))
6347 (clobber (reg:CC FLAGS_REG))])]
6348 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6349
6350 (define_insn "*sub<mode>_1"
6351 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6352 (minus:SWI
6353 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6354 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6355 (clobber (reg:CC FLAGS_REG))]
6356 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6357 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6358 [(set_attr "type" "alu")
6359 (set_attr "mode" "<MODE>")])
6360
6361 (define_insn "*subsi_1_zext"
6362 [(set (match_operand:DI 0 "register_operand" "=r")
6363 (zero_extend:DI
6364 (minus:SI (match_operand:SI 1 "register_operand" "0")
6365 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6366 (clobber (reg:CC FLAGS_REG))]
6367 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6368 "sub{l}\t{%2, %k0|%k0, %2}"
6369 [(set_attr "type" "alu")
6370 (set_attr "mode" "SI")])
6371
6372 (define_insn "*subqi_1_slp"
6373 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6374 (minus:QI (match_dup 0)
6375 (match_operand:QI 1 "general_operand" "qn,qm")))
6376 (clobber (reg:CC FLAGS_REG))]
6377 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6378 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6379 "sub{b}\t{%1, %0|%0, %1}"
6380 [(set_attr "type" "alu1")
6381 (set_attr "mode" "QI")])
6382
6383 (define_insn "*sub<mode>_2"
6384 [(set (reg FLAGS_REG)
6385 (compare
6386 (minus:SWI
6387 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6388 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6389 (const_int 0)))
6390 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6391 (minus:SWI (match_dup 1) (match_dup 2)))]
6392 "ix86_match_ccmode (insn, CCGOCmode)
6393 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6394 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6395 [(set_attr "type" "alu")
6396 (set_attr "mode" "<MODE>")])
6397
6398 (define_insn "*subsi_2_zext"
6399 [(set (reg FLAGS_REG)
6400 (compare
6401 (minus:SI (match_operand:SI 1 "register_operand" "0")
6402 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6403 (const_int 0)))
6404 (set (match_operand:DI 0 "register_operand" "=r")
6405 (zero_extend:DI
6406 (minus:SI (match_dup 1)
6407 (match_dup 2))))]
6408 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6409 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6410 "sub{l}\t{%2, %k0|%k0, %2}"
6411 [(set_attr "type" "alu")
6412 (set_attr "mode" "SI")])
6413
6414 (define_insn "*sub<mode>_3"
6415 [(set (reg FLAGS_REG)
6416 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6417 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6418 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6419 (minus:SWI (match_dup 1) (match_dup 2)))]
6420 "ix86_match_ccmode (insn, CCmode)
6421 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6422 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6423 [(set_attr "type" "alu")
6424 (set_attr "mode" "<MODE>")])
6425
6426 (define_insn "*subsi_3_zext"
6427 [(set (reg FLAGS_REG)
6428 (compare (match_operand:SI 1 "register_operand" "0")
6429 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6430 (set (match_operand:DI 0 "register_operand" "=r")
6431 (zero_extend:DI
6432 (minus:SI (match_dup 1)
6433 (match_dup 2))))]
6434 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6435 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6436 "sub{l}\t{%2, %1|%1, %2}"
6437 [(set_attr "type" "alu")
6438 (set_attr "mode" "SI")])
6439 \f
6440 ;; Add with carry and subtract with borrow
6441
6442 (define_expand "<plusminus_insn><mode>3_carry"
6443 [(parallel
6444 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6445 (plusminus:SWI
6446 (match_operand:SWI 1 "nonimmediate_operand" "")
6447 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6448 [(match_operand 3 "flags_reg_operand" "")
6449 (const_int 0)])
6450 (match_operand:SWI 2 "<general_operand>" ""))))
6451 (clobber (reg:CC FLAGS_REG))])]
6452 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6453
6454 (define_insn "*<plusminus_insn><mode>3_carry"
6455 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6456 (plusminus:SWI
6457 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6458 (plus:SWI
6459 (match_operator 3 "ix86_carry_flag_operator"
6460 [(reg FLAGS_REG) (const_int 0)])
6461 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6462 (clobber (reg:CC FLAGS_REG))]
6463 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6464 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6465 [(set_attr "type" "alu")
6466 (set_attr "use_carry" "1")
6467 (set_attr "pent_pair" "pu")
6468 (set_attr "mode" "<MODE>")])
6469
6470 (define_insn "*addsi3_carry_zext"
6471 [(set (match_operand:DI 0 "register_operand" "=r")
6472 (zero_extend:DI
6473 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6474 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6475 [(reg FLAGS_REG) (const_int 0)])
6476 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6477 (clobber (reg:CC FLAGS_REG))]
6478 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6479 "adc{l}\t{%2, %k0|%k0, %2}"
6480 [(set_attr "type" "alu")
6481 (set_attr "use_carry" "1")
6482 (set_attr "pent_pair" "pu")
6483 (set_attr "mode" "SI")])
6484
6485 (define_insn "*subsi3_carry_zext"
6486 [(set (match_operand:DI 0 "register_operand" "=r")
6487 (zero_extend:DI
6488 (minus:SI (match_operand:SI 1 "register_operand" "0")
6489 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6490 [(reg FLAGS_REG) (const_int 0)])
6491 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6492 (clobber (reg:CC FLAGS_REG))]
6493 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6494 "sbb{l}\t{%2, %k0|%k0, %2}"
6495 [(set_attr "type" "alu")
6496 (set_attr "pent_pair" "pu")
6497 (set_attr "mode" "SI")])
6498 \f
6499 ;; Overflow setting add and subtract instructions
6500
6501 (define_insn "*add<mode>3_cconly_overflow"
6502 [(set (reg:CCC FLAGS_REG)
6503 (compare:CCC
6504 (plus:SWI
6505 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6506 (match_operand:SWI 2 "<general_operand>" "<g>"))
6507 (match_dup 1)))
6508 (clobber (match_scratch:SWI 0 "=<r>"))]
6509 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6510 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6511 [(set_attr "type" "alu")
6512 (set_attr "mode" "<MODE>")])
6513
6514 (define_insn "*sub<mode>3_cconly_overflow"
6515 [(set (reg:CCC FLAGS_REG)
6516 (compare:CCC
6517 (minus:SWI
6518 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6519 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6520 (match_dup 0)))]
6521 ""
6522 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6523 [(set_attr "type" "icmp")
6524 (set_attr "mode" "<MODE>")])
6525
6526 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6527 [(set (reg:CCC FLAGS_REG)
6528 (compare:CCC
6529 (plusminus:SWI
6530 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6531 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6532 (match_dup 1)))
6533 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6534 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6535 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6536 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6537 [(set_attr "type" "alu")
6538 (set_attr "mode" "<MODE>")])
6539
6540 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6541 [(set (reg:CCC FLAGS_REG)
6542 (compare:CCC
6543 (plusminus:SI
6544 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6545 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6546 (match_dup 1)))
6547 (set (match_operand:DI 0 "register_operand" "=r")
6548 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6549 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6550 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "mode" "SI")])
6553
6554 ;; The patterns that match these are at the end of this file.
6555
6556 (define_expand "<plusminus_insn>xf3"
6557 [(set (match_operand:XF 0 "register_operand" "")
6558 (plusminus:XF
6559 (match_operand:XF 1 "register_operand" "")
6560 (match_operand:XF 2 "register_operand" "")))]
6561 "TARGET_80387")
6562
6563 (define_expand "<plusminus_insn><mode>3"
6564 [(set (match_operand:MODEF 0 "register_operand" "")
6565 (plusminus:MODEF
6566 (match_operand:MODEF 1 "register_operand" "")
6567 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6568 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6569 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6570 \f
6571 ;; Multiply instructions
6572
6573 (define_expand "mul<mode>3"
6574 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6575 (mult:SWIM248
6576 (match_operand:SWIM248 1 "register_operand" "")
6577 (match_operand:SWIM248 2 "<general_operand>" "")))
6578 (clobber (reg:CC FLAGS_REG))])])
6579
6580 (define_expand "mulqi3"
6581 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6582 (mult:QI
6583 (match_operand:QI 1 "register_operand" "")
6584 (match_operand:QI 2 "nonimmediate_operand" "")))
6585 (clobber (reg:CC FLAGS_REG))])]
6586 "TARGET_QIMODE_MATH")
6587
6588 ;; On AMDFAM10
6589 ;; IMUL reg32/64, reg32/64, imm8 Direct
6590 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6591 ;; IMUL reg32/64, reg32/64, imm32 Direct
6592 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6593 ;; IMUL reg32/64, reg32/64 Direct
6594 ;; IMUL reg32/64, mem32/64 Direct
6595 ;;
6596 ;; On BDVER1, all above IMULs use DirectPath
6597
6598 (define_insn "*mul<mode>3_1"
6599 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6600 (mult:SWI48
6601 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6602 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6603 (clobber (reg:CC FLAGS_REG))]
6604 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6605 "@
6606 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6607 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6608 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "imul")
6610 (set_attr "prefix_0f" "0,0,1")
6611 (set (attr "athlon_decode")
6612 (cond [(eq_attr "cpu" "athlon")
6613 (const_string "vector")
6614 (eq_attr "alternative" "1")
6615 (const_string "vector")
6616 (and (eq_attr "alternative" "2")
6617 (match_operand 1 "memory_operand" ""))
6618 (const_string "vector")]
6619 (const_string "direct")))
6620 (set (attr "amdfam10_decode")
6621 (cond [(and (eq_attr "alternative" "0,1")
6622 (match_operand 1 "memory_operand" ""))
6623 (const_string "vector")]
6624 (const_string "direct")))
6625 (set_attr "bdver1_decode" "direct")
6626 (set_attr "mode" "<MODE>")])
6627
6628 (define_insn "*mulsi3_1_zext"
6629 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6630 (zero_extend:DI
6631 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6632 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "TARGET_64BIT
6635 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6636 "@
6637 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6638 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6639 imul{l}\t{%2, %k0|%k0, %2}"
6640 [(set_attr "type" "imul")
6641 (set_attr "prefix_0f" "0,0,1")
6642 (set (attr "athlon_decode")
6643 (cond [(eq_attr "cpu" "athlon")
6644 (const_string "vector")
6645 (eq_attr "alternative" "1")
6646 (const_string "vector")
6647 (and (eq_attr "alternative" "2")
6648 (match_operand 1 "memory_operand" ""))
6649 (const_string "vector")]
6650 (const_string "direct")))
6651 (set (attr "amdfam10_decode")
6652 (cond [(and (eq_attr "alternative" "0,1")
6653 (match_operand 1 "memory_operand" ""))
6654 (const_string "vector")]
6655 (const_string "direct")))
6656 (set_attr "bdver1_decode" "direct")
6657 (set_attr "mode" "SI")])
6658
6659 ;; On AMDFAM10
6660 ;; IMUL reg16, reg16, imm8 VectorPath
6661 ;; IMUL reg16, mem16, imm8 VectorPath
6662 ;; IMUL reg16, reg16, imm16 VectorPath
6663 ;; IMUL reg16, mem16, imm16 VectorPath
6664 ;; IMUL reg16, reg16 Direct
6665 ;; IMUL reg16, mem16 Direct
6666 ;;
6667 ;; On BDVER1, all HI MULs use DoublePath
6668
6669 (define_insn "*mulhi3_1"
6670 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6671 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6672 (match_operand:HI 2 "general_operand" "K,n,mr")))
6673 (clobber (reg:CC FLAGS_REG))]
6674 "TARGET_HIMODE_MATH
6675 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6676 "@
6677 imul{w}\t{%2, %1, %0|%0, %1, %2}
6678 imul{w}\t{%2, %1, %0|%0, %1, %2}
6679 imul{w}\t{%2, %0|%0, %2}"
6680 [(set_attr "type" "imul")
6681 (set_attr "prefix_0f" "0,0,1")
6682 (set (attr "athlon_decode")
6683 (cond [(eq_attr "cpu" "athlon")
6684 (const_string "vector")
6685 (eq_attr "alternative" "1,2")
6686 (const_string "vector")]
6687 (const_string "direct")))
6688 (set (attr "amdfam10_decode")
6689 (cond [(eq_attr "alternative" "0,1")
6690 (const_string "vector")]
6691 (const_string "direct")))
6692 (set_attr "bdver1_decode" "double")
6693 (set_attr "mode" "HI")])
6694
6695 ;;On AMDFAM10 and BDVER1
6696 ;; MUL reg8 Direct
6697 ;; MUL mem8 Direct
6698
6699 (define_insn "*mulqi3_1"
6700 [(set (match_operand:QI 0 "register_operand" "=a")
6701 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6702 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6703 (clobber (reg:CC FLAGS_REG))]
6704 "TARGET_QIMODE_MATH
6705 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6706 "mul{b}\t%2"
6707 [(set_attr "type" "imul")
6708 (set_attr "length_immediate" "0")
6709 (set (attr "athlon_decode")
6710 (if_then_else (eq_attr "cpu" "athlon")
6711 (const_string "vector")
6712 (const_string "direct")))
6713 (set_attr "amdfam10_decode" "direct")
6714 (set_attr "bdver1_decode" "direct")
6715 (set_attr "mode" "QI")])
6716
6717 (define_expand "<u>mul<mode><dwi>3"
6718 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6719 (mult:<DWI>
6720 (any_extend:<DWI>
6721 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6722 (any_extend:<DWI>
6723 (match_operand:DWIH 2 "register_operand" ""))))
6724 (clobber (reg:CC FLAGS_REG))])])
6725
6726 (define_expand "<u>mulqihi3"
6727 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6728 (mult:HI
6729 (any_extend:HI
6730 (match_operand:QI 1 "nonimmediate_operand" ""))
6731 (any_extend:HI
6732 (match_operand:QI 2 "register_operand" ""))))
6733 (clobber (reg:CC FLAGS_REG))])]
6734 "TARGET_QIMODE_MATH")
6735
6736 (define_insn "*bmi2_umulditi3_1"
6737 [(set (match_operand:DI 0 "register_operand" "=r")
6738 (mult:DI
6739 (match_operand:DI 2 "nonimmediate_operand" "%d")
6740 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6741 (set (match_operand:DI 1 "register_operand" "=r")
6742 (truncate:DI
6743 (lshiftrt:TI
6744 (mult:TI (zero_extend:TI (match_dup 2))
6745 (zero_extend:TI (match_dup 3)))
6746 (const_int 64))))]
6747 "TARGET_64BIT && TARGET_BMI2
6748 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6749 "mulx\t{%3, %0, %1|%1, %0, %3}"
6750 [(set_attr "type" "imulx")
6751 (set_attr "prefix" "vex")
6752 (set_attr "mode" "DI")])
6753
6754 (define_insn "*bmi2_umulsidi3_1"
6755 [(set (match_operand:SI 0 "register_operand" "=r")
6756 (mult:SI
6757 (match_operand:SI 2 "nonimmediate_operand" "%d")
6758 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6759 (set (match_operand:SI 1 "register_operand" "=r")
6760 (truncate:SI
6761 (lshiftrt:DI
6762 (mult:DI (zero_extend:DI (match_dup 2))
6763 (zero_extend:DI (match_dup 3)))
6764 (const_int 32))))]
6765 "!TARGET_64BIT && TARGET_BMI2
6766 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6767 "mulx\t{%3, %0, %1|%1, %0, %3}"
6768 [(set_attr "type" "imulx")
6769 (set_attr "prefix" "vex")
6770 (set_attr "mode" "SI")])
6771
6772 (define_insn "*umul<mode><dwi>3_1"
6773 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6774 (mult:<DWI>
6775 (zero_extend:<DWI>
6776 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6777 (zero_extend:<DWI>
6778 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6779 (clobber (reg:CC FLAGS_REG))]
6780 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6781 "@
6782 mul{<imodesuffix>}\t%2
6783 #"
6784 [(set_attr "isa" "*,bmi2")
6785 (set_attr "type" "imul,imulx")
6786 (set_attr "length_immediate" "0,*")
6787 (set (attr "athlon_decode")
6788 (cond [(eq_attr "alternative" "0")
6789 (if_then_else (eq_attr "cpu" "athlon")
6790 (const_string "vector")
6791 (const_string "double"))]
6792 (const_string "*")))
6793 (set_attr "amdfam10_decode" "double,*")
6794 (set_attr "bdver1_decode" "direct,*")
6795 (set_attr "prefix" "orig,vex")
6796 (set_attr "mode" "<MODE>")])
6797
6798 ;; Convert mul to the mulx pattern to avoid flags dependency.
6799 (define_split
6800 [(set (match_operand:<DWI> 0 "register_operand" "")
6801 (mult:<DWI>
6802 (zero_extend:<DWI>
6803 (match_operand:DWIH 1 "register_operand" ""))
6804 (zero_extend:<DWI>
6805 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6806 (clobber (reg:CC FLAGS_REG))]
6807 "TARGET_BMI2 && reload_completed
6808 && true_regnum (operands[1]) == DX_REG"
6809 [(parallel [(set (match_dup 3)
6810 (mult:DWIH (match_dup 1) (match_dup 2)))
6811 (set (match_dup 4)
6812 (truncate:DWIH
6813 (lshiftrt:<DWI>
6814 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6815 (zero_extend:<DWI> (match_dup 2)))
6816 (match_dup 5))))])]
6817 {
6818 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6819
6820 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6821 })
6822
6823 (define_insn "*mul<mode><dwi>3_1"
6824 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6825 (mult:<DWI>
6826 (sign_extend:<DWI>
6827 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6828 (sign_extend:<DWI>
6829 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6830 (clobber (reg:CC FLAGS_REG))]
6831 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6832 "imul{<imodesuffix>}\t%2"
6833 [(set_attr "type" "imul")
6834 (set_attr "length_immediate" "0")
6835 (set (attr "athlon_decode")
6836 (if_then_else (eq_attr "cpu" "athlon")
6837 (const_string "vector")
6838 (const_string "double")))
6839 (set_attr "amdfam10_decode" "double")
6840 (set_attr "bdver1_decode" "direct")
6841 (set_attr "mode" "<MODE>")])
6842
6843 (define_insn "*<u>mulqihi3_1"
6844 [(set (match_operand:HI 0 "register_operand" "=a")
6845 (mult:HI
6846 (any_extend:HI
6847 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6848 (any_extend:HI
6849 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6850 (clobber (reg:CC FLAGS_REG))]
6851 "TARGET_QIMODE_MATH
6852 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6853 "<sgnprefix>mul{b}\t%2"
6854 [(set_attr "type" "imul")
6855 (set_attr "length_immediate" "0")
6856 (set (attr "athlon_decode")
6857 (if_then_else (eq_attr "cpu" "athlon")
6858 (const_string "vector")
6859 (const_string "direct")))
6860 (set_attr "amdfam10_decode" "direct")
6861 (set_attr "bdver1_decode" "direct")
6862 (set_attr "mode" "QI")])
6863
6864 (define_expand "<s>mul<mode>3_highpart"
6865 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6866 (truncate:SWI48
6867 (lshiftrt:<DWI>
6868 (mult:<DWI>
6869 (any_extend:<DWI>
6870 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6871 (any_extend:<DWI>
6872 (match_operand:SWI48 2 "register_operand" "")))
6873 (match_dup 4))))
6874 (clobber (match_scratch:SWI48 3 ""))
6875 (clobber (reg:CC FLAGS_REG))])]
6876 ""
6877 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6878
6879 (define_insn "*<s>muldi3_highpart_1"
6880 [(set (match_operand:DI 0 "register_operand" "=d")
6881 (truncate:DI
6882 (lshiftrt:TI
6883 (mult:TI
6884 (any_extend:TI
6885 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6886 (any_extend:TI
6887 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6888 (const_int 64))))
6889 (clobber (match_scratch:DI 3 "=1"))
6890 (clobber (reg:CC FLAGS_REG))]
6891 "TARGET_64BIT
6892 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6893 "<sgnprefix>mul{q}\t%2"
6894 [(set_attr "type" "imul")
6895 (set_attr "length_immediate" "0")
6896 (set (attr "athlon_decode")
6897 (if_then_else (eq_attr "cpu" "athlon")
6898 (const_string "vector")
6899 (const_string "double")))
6900 (set_attr "amdfam10_decode" "double")
6901 (set_attr "bdver1_decode" "direct")
6902 (set_attr "mode" "DI")])
6903
6904 (define_insn "*<s>mulsi3_highpart_1"
6905 [(set (match_operand:SI 0 "register_operand" "=d")
6906 (truncate:SI
6907 (lshiftrt:DI
6908 (mult:DI
6909 (any_extend:DI
6910 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6911 (any_extend:DI
6912 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6913 (const_int 32))))
6914 (clobber (match_scratch:SI 3 "=1"))
6915 (clobber (reg:CC FLAGS_REG))]
6916 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917 "<sgnprefix>mul{l}\t%2"
6918 [(set_attr "type" "imul")
6919 (set_attr "length_immediate" "0")
6920 (set (attr "athlon_decode")
6921 (if_then_else (eq_attr "cpu" "athlon")
6922 (const_string "vector")
6923 (const_string "double")))
6924 (set_attr "amdfam10_decode" "double")
6925 (set_attr "bdver1_decode" "direct")
6926 (set_attr "mode" "SI")])
6927
6928 (define_insn "*<s>mulsi3_highpart_zext"
6929 [(set (match_operand:DI 0 "register_operand" "=d")
6930 (zero_extend:DI (truncate:SI
6931 (lshiftrt:DI
6932 (mult:DI (any_extend:DI
6933 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6934 (any_extend:DI
6935 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6936 (const_int 32)))))
6937 (clobber (match_scratch:SI 3 "=1"))
6938 (clobber (reg:CC FLAGS_REG))]
6939 "TARGET_64BIT
6940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6941 "<sgnprefix>mul{l}\t%2"
6942 [(set_attr "type" "imul")
6943 (set_attr "length_immediate" "0")
6944 (set (attr "athlon_decode")
6945 (if_then_else (eq_attr "cpu" "athlon")
6946 (const_string "vector")
6947 (const_string "double")))
6948 (set_attr "amdfam10_decode" "double")
6949 (set_attr "bdver1_decode" "direct")
6950 (set_attr "mode" "SI")])
6951
6952 ;; The patterns that match these are at the end of this file.
6953
6954 (define_expand "mulxf3"
6955 [(set (match_operand:XF 0 "register_operand" "")
6956 (mult:XF (match_operand:XF 1 "register_operand" "")
6957 (match_operand:XF 2 "register_operand" "")))]
6958 "TARGET_80387")
6959
6960 (define_expand "mul<mode>3"
6961 [(set (match_operand:MODEF 0 "register_operand" "")
6962 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6963 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6964 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6965 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6966 \f
6967 ;; Divide instructions
6968
6969 ;; The patterns that match these are at the end of this file.
6970
6971 (define_expand "divxf3"
6972 [(set (match_operand:XF 0 "register_operand" "")
6973 (div:XF (match_operand:XF 1 "register_operand" "")
6974 (match_operand:XF 2 "register_operand" "")))]
6975 "TARGET_80387")
6976
6977 (define_expand "divdf3"
6978 [(set (match_operand:DF 0 "register_operand" "")
6979 (div:DF (match_operand:DF 1 "register_operand" "")
6980 (match_operand:DF 2 "nonimmediate_operand" "")))]
6981 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6982 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6983
6984 (define_expand "divsf3"
6985 [(set (match_operand:SF 0 "register_operand" "")
6986 (div:SF (match_operand:SF 1 "register_operand" "")
6987 (match_operand:SF 2 "nonimmediate_operand" "")))]
6988 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6989 || TARGET_SSE_MATH"
6990 {
6991 if (TARGET_SSE_MATH
6992 && TARGET_RECIP_DIV
6993 && optimize_insn_for_speed_p ()
6994 && flag_finite_math_only && !flag_trapping_math
6995 && flag_unsafe_math_optimizations)
6996 {
6997 ix86_emit_swdivsf (operands[0], operands[1],
6998 operands[2], SFmode);
6999 DONE;
7000 }
7001 })
7002 \f
7003 ;; Divmod instructions.
7004
7005 (define_expand "divmod<mode>4"
7006 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7007 (div:SWIM248
7008 (match_operand:SWIM248 1 "register_operand" "")
7009 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7010 (set (match_operand:SWIM248 3 "register_operand" "")
7011 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7012 (clobber (reg:CC FLAGS_REG))])])
7013
7014 ;; Split with 8bit unsigned divide:
7015 ;; if (dividend an divisor are in [0-255])
7016 ;; use 8bit unsigned integer divide
7017 ;; else
7018 ;; use original integer divide
7019 (define_split
7020 [(set (match_operand:SWI48 0 "register_operand" "")
7021 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7022 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7023 (set (match_operand:SWI48 1 "register_operand" "")
7024 (mod:SWI48 (match_dup 2) (match_dup 3)))
7025 (clobber (reg:CC FLAGS_REG))]
7026 "TARGET_USE_8BIT_IDIV
7027 && TARGET_QIMODE_MATH
7028 && can_create_pseudo_p ()
7029 && !optimize_insn_for_size_p ()"
7030 [(const_int 0)]
7031 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7032
7033 (define_insn_and_split "divmod<mode>4_1"
7034 [(set (match_operand:SWI48 0 "register_operand" "=a")
7035 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7036 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7037 (set (match_operand:SWI48 1 "register_operand" "=&d")
7038 (mod:SWI48 (match_dup 2) (match_dup 3)))
7039 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7040 (clobber (reg:CC FLAGS_REG))]
7041 ""
7042 "#"
7043 "reload_completed"
7044 [(parallel [(set (match_dup 1)
7045 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7046 (clobber (reg:CC FLAGS_REG))])
7047 (parallel [(set (match_dup 0)
7048 (div:SWI48 (match_dup 2) (match_dup 3)))
7049 (set (match_dup 1)
7050 (mod:SWI48 (match_dup 2) (match_dup 3)))
7051 (use (match_dup 1))
7052 (clobber (reg:CC FLAGS_REG))])]
7053 {
7054 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7055
7056 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7057 operands[4] = operands[2];
7058 else
7059 {
7060 /* Avoid use of cltd in favor of a mov+shift. */
7061 emit_move_insn (operands[1], operands[2]);
7062 operands[4] = operands[1];
7063 }
7064 }
7065 [(set_attr "type" "multi")
7066 (set_attr "mode" "<MODE>")])
7067
7068 (define_insn_and_split "*divmod<mode>4"
7069 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7070 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7071 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7072 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7073 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7074 (clobber (reg:CC FLAGS_REG))]
7075 ""
7076 "#"
7077 "reload_completed"
7078 [(parallel [(set (match_dup 1)
7079 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7080 (clobber (reg:CC FLAGS_REG))])
7081 (parallel [(set (match_dup 0)
7082 (div:SWIM248 (match_dup 2) (match_dup 3)))
7083 (set (match_dup 1)
7084 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7085 (use (match_dup 1))
7086 (clobber (reg:CC FLAGS_REG))])]
7087 {
7088 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7089
7090 if (<MODE>mode != HImode
7091 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7092 operands[4] = operands[2];
7093 else
7094 {
7095 /* Avoid use of cltd in favor of a mov+shift. */
7096 emit_move_insn (operands[1], operands[2]);
7097 operands[4] = operands[1];
7098 }
7099 }
7100 [(set_attr "type" "multi")
7101 (set_attr "mode" "<MODE>")])
7102
7103 (define_insn "*divmod<mode>4_noext"
7104 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7105 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7106 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7107 (set (match_operand:SWIM248 1 "register_operand" "=d")
7108 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7109 (use (match_operand:SWIM248 4 "register_operand" "1"))
7110 (clobber (reg:CC FLAGS_REG))]
7111 ""
7112 "idiv{<imodesuffix>}\t%3"
7113 [(set_attr "type" "idiv")
7114 (set_attr "mode" "<MODE>")])
7115
7116 (define_expand "divmodqi4"
7117 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7118 (div:QI
7119 (match_operand:QI 1 "register_operand" "")
7120 (match_operand:QI 2 "nonimmediate_operand" "")))
7121 (set (match_operand:QI 3 "register_operand" "")
7122 (mod:QI (match_dup 1) (match_dup 2)))
7123 (clobber (reg:CC FLAGS_REG))])]
7124 "TARGET_QIMODE_MATH"
7125 {
7126 rtx div, mod, insn;
7127 rtx tmp0, tmp1;
7128
7129 tmp0 = gen_reg_rtx (HImode);
7130 tmp1 = gen_reg_rtx (HImode);
7131
7132 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7133 in AX. */
7134 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7135 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7136
7137 /* Extract remainder from AH. */
7138 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7139 insn = emit_move_insn (operands[3], tmp1);
7140
7141 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7142 set_unique_reg_note (insn, REG_EQUAL, mod);
7143
7144 /* Extract quotient from AL. */
7145 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7146
7147 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7148 set_unique_reg_note (insn, REG_EQUAL, div);
7149
7150 DONE;
7151 })
7152
7153 ;; Divide AX by r/m8, with result stored in
7154 ;; AL <- Quotient
7155 ;; AH <- Remainder
7156 ;; Change div/mod to HImode and extend the second argument to HImode
7157 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7158 ;; combine may fail.
7159 (define_insn "divmodhiqi3"
7160 [(set (match_operand:HI 0 "register_operand" "=a")
7161 (ior:HI
7162 (ashift:HI
7163 (zero_extend:HI
7164 (truncate:QI
7165 (mod:HI (match_operand:HI 1 "register_operand" "0")
7166 (sign_extend:HI
7167 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7168 (const_int 8))
7169 (zero_extend:HI
7170 (truncate:QI
7171 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7172 (clobber (reg:CC FLAGS_REG))]
7173 "TARGET_QIMODE_MATH"
7174 "idiv{b}\t%2"
7175 [(set_attr "type" "idiv")
7176 (set_attr "mode" "QI")])
7177
7178 (define_expand "udivmod<mode>4"
7179 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7180 (udiv:SWIM248
7181 (match_operand:SWIM248 1 "register_operand" "")
7182 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7183 (set (match_operand:SWIM248 3 "register_operand" "")
7184 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7185 (clobber (reg:CC FLAGS_REG))])])
7186
7187 ;; Split with 8bit unsigned divide:
7188 ;; if (dividend an divisor are in [0-255])
7189 ;; use 8bit unsigned integer divide
7190 ;; else
7191 ;; use original integer divide
7192 (define_split
7193 [(set (match_operand:SWI48 0 "register_operand" "")
7194 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7195 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7196 (set (match_operand:SWI48 1 "register_operand" "")
7197 (umod:SWI48 (match_dup 2) (match_dup 3)))
7198 (clobber (reg:CC FLAGS_REG))]
7199 "TARGET_USE_8BIT_IDIV
7200 && TARGET_QIMODE_MATH
7201 && can_create_pseudo_p ()
7202 && !optimize_insn_for_size_p ()"
7203 [(const_int 0)]
7204 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7205
7206 (define_insn_and_split "udivmod<mode>4_1"
7207 [(set (match_operand:SWI48 0 "register_operand" "=a")
7208 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7209 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7210 (set (match_operand:SWI48 1 "register_operand" "=&d")
7211 (umod:SWI48 (match_dup 2) (match_dup 3)))
7212 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7213 (clobber (reg:CC FLAGS_REG))]
7214 ""
7215 "#"
7216 "reload_completed"
7217 [(set (match_dup 1) (const_int 0))
7218 (parallel [(set (match_dup 0)
7219 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7220 (set (match_dup 1)
7221 (umod:SWI48 (match_dup 2) (match_dup 3)))
7222 (use (match_dup 1))
7223 (clobber (reg:CC FLAGS_REG))])]
7224 ""
7225 [(set_attr "type" "multi")
7226 (set_attr "mode" "<MODE>")])
7227
7228 (define_insn_and_split "*udivmod<mode>4"
7229 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7230 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7231 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7232 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7233 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7234 (clobber (reg:CC FLAGS_REG))]
7235 ""
7236 "#"
7237 "reload_completed"
7238 [(set (match_dup 1) (const_int 0))
7239 (parallel [(set (match_dup 0)
7240 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7241 (set (match_dup 1)
7242 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7243 (use (match_dup 1))
7244 (clobber (reg:CC FLAGS_REG))])]
7245 ""
7246 [(set_attr "type" "multi")
7247 (set_attr "mode" "<MODE>")])
7248
7249 (define_insn "*udivmod<mode>4_noext"
7250 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7251 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7252 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7253 (set (match_operand:SWIM248 1 "register_operand" "=d")
7254 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7255 (use (match_operand:SWIM248 4 "register_operand" "1"))
7256 (clobber (reg:CC FLAGS_REG))]
7257 ""
7258 "div{<imodesuffix>}\t%3"
7259 [(set_attr "type" "idiv")
7260 (set_attr "mode" "<MODE>")])
7261
7262 (define_expand "udivmodqi4"
7263 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7264 (udiv:QI
7265 (match_operand:QI 1 "register_operand" "")
7266 (match_operand:QI 2 "nonimmediate_operand" "")))
7267 (set (match_operand:QI 3 "register_operand" "")
7268 (umod:QI (match_dup 1) (match_dup 2)))
7269 (clobber (reg:CC FLAGS_REG))])]
7270 "TARGET_QIMODE_MATH"
7271 {
7272 rtx div, mod, insn;
7273 rtx tmp0, tmp1;
7274
7275 tmp0 = gen_reg_rtx (HImode);
7276 tmp1 = gen_reg_rtx (HImode);
7277
7278 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7279 in AX. */
7280 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7281 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7282
7283 /* Extract remainder from AH. */
7284 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7285 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7286 insn = emit_move_insn (operands[3], tmp1);
7287
7288 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7289 set_unique_reg_note (insn, REG_EQUAL, mod);
7290
7291 /* Extract quotient from AL. */
7292 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7293
7294 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7295 set_unique_reg_note (insn, REG_EQUAL, div);
7296
7297 DONE;
7298 })
7299
7300 (define_insn "udivmodhiqi3"
7301 [(set (match_operand:HI 0 "register_operand" "=a")
7302 (ior:HI
7303 (ashift:HI
7304 (zero_extend:HI
7305 (truncate:QI
7306 (mod:HI (match_operand:HI 1 "register_operand" "0")
7307 (zero_extend:HI
7308 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7309 (const_int 8))
7310 (zero_extend:HI
7311 (truncate:QI
7312 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7313 (clobber (reg:CC FLAGS_REG))]
7314 "TARGET_QIMODE_MATH"
7315 "div{b}\t%2"
7316 [(set_attr "type" "idiv")
7317 (set_attr "mode" "QI")])
7318
7319 ;; We cannot use div/idiv for double division, because it causes
7320 ;; "division by zero" on the overflow and that's not what we expect
7321 ;; from truncate. Because true (non truncating) double division is
7322 ;; never generated, we can't create this insn anyway.
7323 ;
7324 ;(define_insn ""
7325 ; [(set (match_operand:SI 0 "register_operand" "=a")
7326 ; (truncate:SI
7327 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7328 ; (zero_extend:DI
7329 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7330 ; (set (match_operand:SI 3 "register_operand" "=d")
7331 ; (truncate:SI
7332 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7333 ; (clobber (reg:CC FLAGS_REG))]
7334 ; ""
7335 ; "div{l}\t{%2, %0|%0, %2}"
7336 ; [(set_attr "type" "idiv")])
7337 \f
7338 ;;- Logical AND instructions
7339
7340 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7341 ;; Note that this excludes ah.
7342
7343 (define_expand "testsi_ccno_1"
7344 [(set (reg:CCNO FLAGS_REG)
7345 (compare:CCNO
7346 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7347 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7348 (const_int 0)))])
7349
7350 (define_expand "testqi_ccz_1"
7351 [(set (reg:CCZ FLAGS_REG)
7352 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7353 (match_operand:QI 1 "nonmemory_operand" ""))
7354 (const_int 0)))])
7355
7356 (define_expand "testdi_ccno_1"
7357 [(set (reg:CCNO FLAGS_REG)
7358 (compare:CCNO
7359 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7360 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7361 (const_int 0)))]
7362 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7363
7364 (define_insn "*testdi_1"
7365 [(set (reg FLAGS_REG)
7366 (compare
7367 (and:DI
7368 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7369 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7370 (const_int 0)))]
7371 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7372 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7373 "@
7374 test{l}\t{%k1, %k0|%k0, %k1}
7375 test{l}\t{%k1, %k0|%k0, %k1}
7376 test{q}\t{%1, %0|%0, %1}
7377 test{q}\t{%1, %0|%0, %1}
7378 test{q}\t{%1, %0|%0, %1}"
7379 [(set_attr "type" "test")
7380 (set_attr "modrm" "0,1,0,1,1")
7381 (set_attr "mode" "SI,SI,DI,DI,DI")])
7382
7383 (define_insn "*testqi_1_maybe_si"
7384 [(set (reg FLAGS_REG)
7385 (compare
7386 (and:QI
7387 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7388 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7389 (const_int 0)))]
7390 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7391 && ix86_match_ccmode (insn,
7392 CONST_INT_P (operands[1])
7393 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7394 {
7395 if (which_alternative == 3)
7396 {
7397 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7398 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7399 return "test{l}\t{%1, %k0|%k0, %1}";
7400 }
7401 return "test{b}\t{%1, %0|%0, %1}";
7402 }
7403 [(set_attr "type" "test")
7404 (set_attr "modrm" "0,1,1,1")
7405 (set_attr "mode" "QI,QI,QI,SI")
7406 (set_attr "pent_pair" "uv,np,uv,np")])
7407
7408 (define_insn "*test<mode>_1"
7409 [(set (reg FLAGS_REG)
7410 (compare
7411 (and:SWI124
7412 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7413 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7414 (const_int 0)))]
7415 "ix86_match_ccmode (insn, CCNOmode)
7416 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7417 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7418 [(set_attr "type" "test")
7419 (set_attr "modrm" "0,1,1")
7420 (set_attr "mode" "<MODE>")
7421 (set_attr "pent_pair" "uv,np,uv")])
7422
7423 (define_expand "testqi_ext_ccno_0"
7424 [(set (reg:CCNO FLAGS_REG)
7425 (compare:CCNO
7426 (and:SI
7427 (zero_extract:SI
7428 (match_operand 0 "ext_register_operand" "")
7429 (const_int 8)
7430 (const_int 8))
7431 (match_operand 1 "const_int_operand" ""))
7432 (const_int 0)))])
7433
7434 (define_insn "*testqi_ext_0"
7435 [(set (reg FLAGS_REG)
7436 (compare
7437 (and:SI
7438 (zero_extract:SI
7439 (match_operand 0 "ext_register_operand" "Q")
7440 (const_int 8)
7441 (const_int 8))
7442 (match_operand 1 "const_int_operand" "n"))
7443 (const_int 0)))]
7444 "ix86_match_ccmode (insn, CCNOmode)"
7445 "test{b}\t{%1, %h0|%h0, %1}"
7446 [(set_attr "type" "test")
7447 (set_attr "mode" "QI")
7448 (set_attr "length_immediate" "1")
7449 (set_attr "modrm" "1")
7450 (set_attr "pent_pair" "np")])
7451
7452 (define_insn "*testqi_ext_1_rex64"
7453 [(set (reg FLAGS_REG)
7454 (compare
7455 (and:SI
7456 (zero_extract:SI
7457 (match_operand 0 "ext_register_operand" "Q")
7458 (const_int 8)
7459 (const_int 8))
7460 (zero_extend:SI
7461 (match_operand:QI 1 "register_operand" "Q")))
7462 (const_int 0)))]
7463 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7464 "test{b}\t{%1, %h0|%h0, %1}"
7465 [(set_attr "type" "test")
7466 (set_attr "mode" "QI")])
7467
7468 (define_insn "*testqi_ext_1"
7469 [(set (reg FLAGS_REG)
7470 (compare
7471 (and:SI
7472 (zero_extract:SI
7473 (match_operand 0 "ext_register_operand" "Q")
7474 (const_int 8)
7475 (const_int 8))
7476 (zero_extend:SI
7477 (match_operand:QI 1 "general_operand" "Qm")))
7478 (const_int 0)))]
7479 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7480 "test{b}\t{%1, %h0|%h0, %1}"
7481 [(set_attr "type" "test")
7482 (set_attr "mode" "QI")])
7483
7484 (define_insn "*testqi_ext_2"
7485 [(set (reg FLAGS_REG)
7486 (compare
7487 (and:SI
7488 (zero_extract:SI
7489 (match_operand 0 "ext_register_operand" "Q")
7490 (const_int 8)
7491 (const_int 8))
7492 (zero_extract:SI
7493 (match_operand 1 "ext_register_operand" "Q")
7494 (const_int 8)
7495 (const_int 8)))
7496 (const_int 0)))]
7497 "ix86_match_ccmode (insn, CCNOmode)"
7498 "test{b}\t{%h1, %h0|%h0, %h1}"
7499 [(set_attr "type" "test")
7500 (set_attr "mode" "QI")])
7501
7502 (define_insn "*testqi_ext_3_rex64"
7503 [(set (reg FLAGS_REG)
7504 (compare (zero_extract:DI
7505 (match_operand 0 "nonimmediate_operand" "rm")
7506 (match_operand:DI 1 "const_int_operand" "")
7507 (match_operand:DI 2 "const_int_operand" ""))
7508 (const_int 0)))]
7509 "TARGET_64BIT
7510 && ix86_match_ccmode (insn, CCNOmode)
7511 && INTVAL (operands[1]) > 0
7512 && INTVAL (operands[2]) >= 0
7513 /* Ensure that resulting mask is zero or sign extended operand. */
7514 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7515 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7516 && INTVAL (operands[1]) > 32))
7517 && (GET_MODE (operands[0]) == SImode
7518 || GET_MODE (operands[0]) == DImode
7519 || GET_MODE (operands[0]) == HImode
7520 || GET_MODE (operands[0]) == QImode)"
7521 "#")
7522
7523 ;; Combine likes to form bit extractions for some tests. Humor it.
7524 (define_insn "*testqi_ext_3"
7525 [(set (reg FLAGS_REG)
7526 (compare (zero_extract:SI
7527 (match_operand 0 "nonimmediate_operand" "rm")
7528 (match_operand:SI 1 "const_int_operand" "")
7529 (match_operand:SI 2 "const_int_operand" ""))
7530 (const_int 0)))]
7531 "ix86_match_ccmode (insn, CCNOmode)
7532 && INTVAL (operands[1]) > 0
7533 && INTVAL (operands[2]) >= 0
7534 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7535 && (GET_MODE (operands[0]) == SImode
7536 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7537 || GET_MODE (operands[0]) == HImode
7538 || GET_MODE (operands[0]) == QImode)"
7539 "#")
7540
7541 (define_split
7542 [(set (match_operand 0 "flags_reg_operand" "")
7543 (match_operator 1 "compare_operator"
7544 [(zero_extract
7545 (match_operand 2 "nonimmediate_operand" "")
7546 (match_operand 3 "const_int_operand" "")
7547 (match_operand 4 "const_int_operand" ""))
7548 (const_int 0)]))]
7549 "ix86_match_ccmode (insn, CCNOmode)"
7550 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7551 {
7552 rtx val = operands[2];
7553 HOST_WIDE_INT len = INTVAL (operands[3]);
7554 HOST_WIDE_INT pos = INTVAL (operands[4]);
7555 HOST_WIDE_INT mask;
7556 enum machine_mode mode, submode;
7557
7558 mode = GET_MODE (val);
7559 if (MEM_P (val))
7560 {
7561 /* ??? Combine likes to put non-volatile mem extractions in QImode
7562 no matter the size of the test. So find a mode that works. */
7563 if (! MEM_VOLATILE_P (val))
7564 {
7565 mode = smallest_mode_for_size (pos + len, MODE_INT);
7566 val = adjust_address (val, mode, 0);
7567 }
7568 }
7569 else if (GET_CODE (val) == SUBREG
7570 && (submode = GET_MODE (SUBREG_REG (val)),
7571 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7572 && pos + len <= GET_MODE_BITSIZE (submode)
7573 && GET_MODE_CLASS (submode) == MODE_INT)
7574 {
7575 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7576 mode = submode;
7577 val = SUBREG_REG (val);
7578 }
7579 else if (mode == HImode && pos + len <= 8)
7580 {
7581 /* Small HImode tests can be converted to QImode. */
7582 mode = QImode;
7583 val = gen_lowpart (QImode, val);
7584 }
7585
7586 if (len == HOST_BITS_PER_WIDE_INT)
7587 mask = -1;
7588 else
7589 mask = ((HOST_WIDE_INT)1 << len) - 1;
7590 mask <<= pos;
7591
7592 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7593 })
7594
7595 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7596 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7597 ;; this is relatively important trick.
7598 ;; Do the conversion only post-reload to avoid limiting of the register class
7599 ;; to QI regs.
7600 (define_split
7601 [(set (match_operand 0 "flags_reg_operand" "")
7602 (match_operator 1 "compare_operator"
7603 [(and (match_operand 2 "register_operand" "")
7604 (match_operand 3 "const_int_operand" ""))
7605 (const_int 0)]))]
7606 "reload_completed
7607 && QI_REG_P (operands[2])
7608 && GET_MODE (operands[2]) != QImode
7609 && ((ix86_match_ccmode (insn, CCZmode)
7610 && !(INTVAL (operands[3]) & ~(255 << 8)))
7611 || (ix86_match_ccmode (insn, CCNOmode)
7612 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7613 [(set (match_dup 0)
7614 (match_op_dup 1
7615 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7616 (match_dup 3))
7617 (const_int 0)]))]
7618 {
7619 operands[2] = gen_lowpart (SImode, operands[2]);
7620 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7621 })
7622
7623 (define_split
7624 [(set (match_operand 0 "flags_reg_operand" "")
7625 (match_operator 1 "compare_operator"
7626 [(and (match_operand 2 "nonimmediate_operand" "")
7627 (match_operand 3 "const_int_operand" ""))
7628 (const_int 0)]))]
7629 "reload_completed
7630 && GET_MODE (operands[2]) != QImode
7631 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7632 && ((ix86_match_ccmode (insn, CCZmode)
7633 && !(INTVAL (operands[3]) & ~255))
7634 || (ix86_match_ccmode (insn, CCNOmode)
7635 && !(INTVAL (operands[3]) & ~127)))"
7636 [(set (match_dup 0)
7637 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7638 (const_int 0)]))]
7639 {
7640 operands[2] = gen_lowpart (QImode, operands[2]);
7641 operands[3] = gen_lowpart (QImode, operands[3]);
7642 })
7643
7644 ;; %%% This used to optimize known byte-wide and operations to memory,
7645 ;; and sometimes to QImode registers. If this is considered useful,
7646 ;; it should be done with splitters.
7647
7648 (define_expand "and<mode>3"
7649 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7650 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7651 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7652 ""
7653 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7654
7655 (define_insn "*anddi_1"
7656 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7657 (and:DI
7658 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7659 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7660 (clobber (reg:CC FLAGS_REG))]
7661 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7662 {
7663 switch (get_attr_type (insn))
7664 {
7665 case TYPE_IMOVX:
7666 return "#";
7667
7668 default:
7669 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7670 if (get_attr_mode (insn) == MODE_SI)
7671 return "and{l}\t{%k2, %k0|%k0, %k2}";
7672 else
7673 return "and{q}\t{%2, %0|%0, %2}";
7674 }
7675 }
7676 [(set_attr "type" "alu,alu,alu,imovx")
7677 (set_attr "length_immediate" "*,*,*,0")
7678 (set (attr "prefix_rex")
7679 (if_then_else
7680 (and (eq_attr "type" "imovx")
7681 (and (match_test "INTVAL (operands[2]) == 0xff")
7682 (match_operand 1 "ext_QIreg_operand" "")))
7683 (const_string "1")
7684 (const_string "*")))
7685 (set_attr "mode" "SI,DI,DI,SI")])
7686
7687 (define_insn "*andsi_1"
7688 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7689 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7690 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7691 (clobber (reg:CC FLAGS_REG))]
7692 "ix86_binary_operator_ok (AND, SImode, operands)"
7693 {
7694 switch (get_attr_type (insn))
7695 {
7696 case TYPE_IMOVX:
7697 return "#";
7698
7699 default:
7700 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7701 return "and{l}\t{%2, %0|%0, %2}";
7702 }
7703 }
7704 [(set_attr "type" "alu,alu,imovx")
7705 (set (attr "prefix_rex")
7706 (if_then_else
7707 (and (eq_attr "type" "imovx")
7708 (and (match_test "INTVAL (operands[2]) == 0xff")
7709 (match_operand 1 "ext_QIreg_operand" "")))
7710 (const_string "1")
7711 (const_string "*")))
7712 (set_attr "length_immediate" "*,*,0")
7713 (set_attr "mode" "SI")])
7714
7715 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7716 (define_insn "*andsi_1_zext"
7717 [(set (match_operand:DI 0 "register_operand" "=r")
7718 (zero_extend:DI
7719 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7720 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7721 (clobber (reg:CC FLAGS_REG))]
7722 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7723 "and{l}\t{%2, %k0|%k0, %2}"
7724 [(set_attr "type" "alu")
7725 (set_attr "mode" "SI")])
7726
7727 (define_insn "*andhi_1"
7728 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7729 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7730 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7731 (clobber (reg:CC FLAGS_REG))]
7732 "ix86_binary_operator_ok (AND, HImode, operands)"
7733 {
7734 switch (get_attr_type (insn))
7735 {
7736 case TYPE_IMOVX:
7737 return "#";
7738
7739 default:
7740 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7741 return "and{w}\t{%2, %0|%0, %2}";
7742 }
7743 }
7744 [(set_attr "type" "alu,alu,imovx")
7745 (set_attr "length_immediate" "*,*,0")
7746 (set (attr "prefix_rex")
7747 (if_then_else
7748 (and (eq_attr "type" "imovx")
7749 (match_operand 1 "ext_QIreg_operand" ""))
7750 (const_string "1")
7751 (const_string "*")))
7752 (set_attr "mode" "HI,HI,SI")])
7753
7754 ;; %%% Potential partial reg stall on alternative 2. What to do?
7755 (define_insn "*andqi_1"
7756 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7757 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7758 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7759 (clobber (reg:CC FLAGS_REG))]
7760 "ix86_binary_operator_ok (AND, QImode, operands)"
7761 "@
7762 and{b}\t{%2, %0|%0, %2}
7763 and{b}\t{%2, %0|%0, %2}
7764 and{l}\t{%k2, %k0|%k0, %k2}"
7765 [(set_attr "type" "alu")
7766 (set_attr "mode" "QI,QI,SI")])
7767
7768 (define_insn "*andqi_1_slp"
7769 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7770 (and:QI (match_dup 0)
7771 (match_operand:QI 1 "general_operand" "qn,qmn")))
7772 (clobber (reg:CC FLAGS_REG))]
7773 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7774 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7775 "and{b}\t{%1, %0|%0, %1}"
7776 [(set_attr "type" "alu1")
7777 (set_attr "mode" "QI")])
7778
7779 (define_split
7780 [(set (match_operand:SWI248 0 "register_operand" "")
7781 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "")
7782 (match_operand:SWI248 2 "const_int_operand" "")))
7783 (clobber (reg:CC FLAGS_REG))]
7784 "reload_completed
7785 && true_regnum (operands[0]) != true_regnum (operands[1])"
7786 [(const_int 0)]
7787 {
7788 enum machine_mode mode;
7789
7790 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7791 mode = SImode;
7792 else if (INTVAL (operands[2]) == 0xffff)
7793 mode = HImode;
7794 else
7795 {
7796 gcc_assert (INTVAL (operands[2]) == 0xff);
7797 mode = QImode;
7798 }
7799
7800 operands[1] = gen_lowpart (mode, operands[1]);
7801
7802 if (mode == SImode)
7803 emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
7804 else
7805 {
7806 rtx (*insn) (rtx, rtx);
7807
7808 /* Zero extend to SImode to avoid partial register stalls. */
7809 operands[0] = gen_lowpart (SImode, operands[0]);
7810
7811 insn = (mode == HImode) ? gen_zero_extendhisi2 : gen_zero_extendqisi2;
7812 emit_insn (insn (operands[0], operands[1]));
7813 }
7814 DONE;
7815 })
7816
7817 (define_split
7818 [(set (match_operand 0 "register_operand" "")
7819 (and (match_dup 0)
7820 (const_int -65536)))
7821 (clobber (reg:CC FLAGS_REG))]
7822 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7823 || optimize_function_for_size_p (cfun)"
7824 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7825 "operands[1] = gen_lowpart (HImode, operands[0]);")
7826
7827 (define_split
7828 [(set (match_operand 0 "ext_register_operand" "")
7829 (and (match_dup 0)
7830 (const_int -256)))
7831 (clobber (reg:CC FLAGS_REG))]
7832 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7833 && reload_completed"
7834 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7835 "operands[1] = gen_lowpart (QImode, operands[0]);")
7836
7837 (define_split
7838 [(set (match_operand 0 "ext_register_operand" "")
7839 (and (match_dup 0)
7840 (const_int -65281)))
7841 (clobber (reg:CC FLAGS_REG))]
7842 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7843 && reload_completed"
7844 [(parallel [(set (zero_extract:SI (match_dup 0)
7845 (const_int 8)
7846 (const_int 8))
7847 (xor:SI
7848 (zero_extract:SI (match_dup 0)
7849 (const_int 8)
7850 (const_int 8))
7851 (zero_extract:SI (match_dup 0)
7852 (const_int 8)
7853 (const_int 8))))
7854 (clobber (reg:CC FLAGS_REG))])]
7855 "operands[0] = gen_lowpart (SImode, operands[0]);")
7856
7857 (define_insn "*anddi_2"
7858 [(set (reg FLAGS_REG)
7859 (compare
7860 (and:DI
7861 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7862 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7863 (const_int 0)))
7864 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7865 (and:DI (match_dup 1) (match_dup 2)))]
7866 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7867 && ix86_binary_operator_ok (AND, DImode, operands)"
7868 "@
7869 and{l}\t{%k2, %k0|%k0, %k2}
7870 and{q}\t{%2, %0|%0, %2}
7871 and{q}\t{%2, %0|%0, %2}"
7872 [(set_attr "type" "alu")
7873 (set_attr "mode" "SI,DI,DI")])
7874
7875 (define_insn "*andqi_2_maybe_si"
7876 [(set (reg FLAGS_REG)
7877 (compare (and:QI
7878 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7879 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7880 (const_int 0)))
7881 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7882 (and:QI (match_dup 1) (match_dup 2)))]
7883 "ix86_binary_operator_ok (AND, QImode, operands)
7884 && ix86_match_ccmode (insn,
7885 CONST_INT_P (operands[2])
7886 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7887 {
7888 if (which_alternative == 2)
7889 {
7890 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7891 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7892 return "and{l}\t{%2, %k0|%k0, %2}";
7893 }
7894 return "and{b}\t{%2, %0|%0, %2}";
7895 }
7896 [(set_attr "type" "alu")
7897 (set_attr "mode" "QI,QI,SI")])
7898
7899 (define_insn "*and<mode>_2"
7900 [(set (reg FLAGS_REG)
7901 (compare (and:SWI124
7902 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7903 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7904 (const_int 0)))
7905 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7906 (and:SWI124 (match_dup 1) (match_dup 2)))]
7907 "ix86_match_ccmode (insn, CCNOmode)
7908 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7909 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7910 [(set_attr "type" "alu")
7911 (set_attr "mode" "<MODE>")])
7912
7913 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7914 (define_insn "*andsi_2_zext"
7915 [(set (reg FLAGS_REG)
7916 (compare (and:SI
7917 (match_operand:SI 1 "nonimmediate_operand" "%0")
7918 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7919 (const_int 0)))
7920 (set (match_operand:DI 0 "register_operand" "=r")
7921 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7922 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7923 && ix86_binary_operator_ok (AND, SImode, operands)"
7924 "and{l}\t{%2, %k0|%k0, %2}"
7925 [(set_attr "type" "alu")
7926 (set_attr "mode" "SI")])
7927
7928 (define_insn "*andqi_2_slp"
7929 [(set (reg FLAGS_REG)
7930 (compare (and:QI
7931 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7932 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7933 (const_int 0)))
7934 (set (strict_low_part (match_dup 0))
7935 (and:QI (match_dup 0) (match_dup 1)))]
7936 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7937 && ix86_match_ccmode (insn, CCNOmode)
7938 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7939 "and{b}\t{%1, %0|%0, %1}"
7940 [(set_attr "type" "alu1")
7941 (set_attr "mode" "QI")])
7942
7943 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7944 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7945 ;; for a QImode operand, which of course failed.
7946 (define_insn "andqi_ext_0"
7947 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7948 (const_int 8)
7949 (const_int 8))
7950 (and:SI
7951 (zero_extract:SI
7952 (match_operand 1 "ext_register_operand" "0")
7953 (const_int 8)
7954 (const_int 8))
7955 (match_operand 2 "const_int_operand" "n")))
7956 (clobber (reg:CC FLAGS_REG))]
7957 ""
7958 "and{b}\t{%2, %h0|%h0, %2}"
7959 [(set_attr "type" "alu")
7960 (set_attr "length_immediate" "1")
7961 (set_attr "modrm" "1")
7962 (set_attr "mode" "QI")])
7963
7964 ;; Generated by peephole translating test to and. This shows up
7965 ;; often in fp comparisons.
7966 (define_insn "*andqi_ext_0_cc"
7967 [(set (reg FLAGS_REG)
7968 (compare
7969 (and:SI
7970 (zero_extract:SI
7971 (match_operand 1 "ext_register_operand" "0")
7972 (const_int 8)
7973 (const_int 8))
7974 (match_operand 2 "const_int_operand" "n"))
7975 (const_int 0)))
7976 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7977 (const_int 8)
7978 (const_int 8))
7979 (and:SI
7980 (zero_extract:SI
7981 (match_dup 1)
7982 (const_int 8)
7983 (const_int 8))
7984 (match_dup 2)))]
7985 "ix86_match_ccmode (insn, CCNOmode)"
7986 "and{b}\t{%2, %h0|%h0, %2}"
7987 [(set_attr "type" "alu")
7988 (set_attr "length_immediate" "1")
7989 (set_attr "modrm" "1")
7990 (set_attr "mode" "QI")])
7991
7992 (define_insn "*andqi_ext_1_rex64"
7993 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7994 (const_int 8)
7995 (const_int 8))
7996 (and:SI
7997 (zero_extract:SI
7998 (match_operand 1 "ext_register_operand" "0")
7999 (const_int 8)
8000 (const_int 8))
8001 (zero_extend:SI
8002 (match_operand 2 "ext_register_operand" "Q"))))
8003 (clobber (reg:CC FLAGS_REG))]
8004 "TARGET_64BIT"
8005 "and{b}\t{%2, %h0|%h0, %2}"
8006 [(set_attr "type" "alu")
8007 (set_attr "length_immediate" "0")
8008 (set_attr "mode" "QI")])
8009
8010 (define_insn "*andqi_ext_1"
8011 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8012 (const_int 8)
8013 (const_int 8))
8014 (and:SI
8015 (zero_extract:SI
8016 (match_operand 1 "ext_register_operand" "0")
8017 (const_int 8)
8018 (const_int 8))
8019 (zero_extend:SI
8020 (match_operand:QI 2 "general_operand" "Qm"))))
8021 (clobber (reg:CC FLAGS_REG))]
8022 "!TARGET_64BIT"
8023 "and{b}\t{%2, %h0|%h0, %2}"
8024 [(set_attr "type" "alu")
8025 (set_attr "length_immediate" "0")
8026 (set_attr "mode" "QI")])
8027
8028 (define_insn "*andqi_ext_2"
8029 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8030 (const_int 8)
8031 (const_int 8))
8032 (and:SI
8033 (zero_extract:SI
8034 (match_operand 1 "ext_register_operand" "%0")
8035 (const_int 8)
8036 (const_int 8))
8037 (zero_extract:SI
8038 (match_operand 2 "ext_register_operand" "Q")
8039 (const_int 8)
8040 (const_int 8))))
8041 (clobber (reg:CC FLAGS_REG))]
8042 ""
8043 "and{b}\t{%h2, %h0|%h0, %h2}"
8044 [(set_attr "type" "alu")
8045 (set_attr "length_immediate" "0")
8046 (set_attr "mode" "QI")])
8047
8048 ;; Convert wide AND instructions with immediate operand to shorter QImode
8049 ;; equivalents when possible.
8050 ;; Don't do the splitting with memory operands, since it introduces risk
8051 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8052 ;; for size, but that can (should?) be handled by generic code instead.
8053 (define_split
8054 [(set (match_operand 0 "register_operand" "")
8055 (and (match_operand 1 "register_operand" "")
8056 (match_operand 2 "const_int_operand" "")))
8057 (clobber (reg:CC FLAGS_REG))]
8058 "reload_completed
8059 && QI_REG_P (operands[0])
8060 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8061 && !(~INTVAL (operands[2]) & ~(255 << 8))
8062 && GET_MODE (operands[0]) != QImode"
8063 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8064 (and:SI (zero_extract:SI (match_dup 1)
8065 (const_int 8) (const_int 8))
8066 (match_dup 2)))
8067 (clobber (reg:CC FLAGS_REG))])]
8068 {
8069 operands[0] = gen_lowpart (SImode, operands[0]);
8070 operands[1] = gen_lowpart (SImode, operands[1]);
8071 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8072 })
8073
8074 ;; Since AND can be encoded with sign extended immediate, this is only
8075 ;; profitable when 7th bit is not set.
8076 (define_split
8077 [(set (match_operand 0 "register_operand" "")
8078 (and (match_operand 1 "general_operand" "")
8079 (match_operand 2 "const_int_operand" "")))
8080 (clobber (reg:CC FLAGS_REG))]
8081 "reload_completed
8082 && ANY_QI_REG_P (operands[0])
8083 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8084 && !(~INTVAL (operands[2]) & ~255)
8085 && !(INTVAL (operands[2]) & 128)
8086 && GET_MODE (operands[0]) != QImode"
8087 [(parallel [(set (strict_low_part (match_dup 0))
8088 (and:QI (match_dup 1)
8089 (match_dup 2)))
8090 (clobber (reg:CC FLAGS_REG))])]
8091 {
8092 operands[0] = gen_lowpart (QImode, operands[0]);
8093 operands[1] = gen_lowpart (QImode, operands[1]);
8094 operands[2] = gen_lowpart (QImode, operands[2]);
8095 })
8096 \f
8097 ;; Logical inclusive and exclusive OR instructions
8098
8099 ;; %%% This used to optimize known byte-wide and operations to memory.
8100 ;; If this is considered useful, it should be done with splitters.
8101
8102 (define_expand "<code><mode>3"
8103 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8104 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8105 (match_operand:SWIM 2 "<general_operand>" "")))]
8106 ""
8107 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8108
8109 (define_insn "*<code><mode>_1"
8110 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8111 (any_or:SWI248
8112 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8113 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8114 (clobber (reg:CC FLAGS_REG))]
8115 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8116 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8117 [(set_attr "type" "alu")
8118 (set_attr "mode" "<MODE>")])
8119
8120 ;; %%% Potential partial reg stall on alternative 2. What to do?
8121 (define_insn "*<code>qi_1"
8122 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8123 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8124 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8125 (clobber (reg:CC FLAGS_REG))]
8126 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8127 "@
8128 <logic>{b}\t{%2, %0|%0, %2}
8129 <logic>{b}\t{%2, %0|%0, %2}
8130 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8131 [(set_attr "type" "alu")
8132 (set_attr "mode" "QI,QI,SI")])
8133
8134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8135 (define_insn "*<code>si_1_zext"
8136 [(set (match_operand:DI 0 "register_operand" "=r")
8137 (zero_extend:DI
8138 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8139 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8140 (clobber (reg:CC FLAGS_REG))]
8141 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8142 "<logic>{l}\t{%2, %k0|%k0, %2}"
8143 [(set_attr "type" "alu")
8144 (set_attr "mode" "SI")])
8145
8146 (define_insn "*<code>si_1_zext_imm"
8147 [(set (match_operand:DI 0 "register_operand" "=r")
8148 (any_or:DI
8149 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8150 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8151 (clobber (reg:CC FLAGS_REG))]
8152 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8153 "<logic>{l}\t{%2, %k0|%k0, %2}"
8154 [(set_attr "type" "alu")
8155 (set_attr "mode" "SI")])
8156
8157 (define_insn "*<code>qi_1_slp"
8158 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8159 (any_or:QI (match_dup 0)
8160 (match_operand:QI 1 "general_operand" "qmn,qn")))
8161 (clobber (reg:CC FLAGS_REG))]
8162 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8163 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8164 "<logic>{b}\t{%1, %0|%0, %1}"
8165 [(set_attr "type" "alu1")
8166 (set_attr "mode" "QI")])
8167
8168 (define_insn "*<code><mode>_2"
8169 [(set (reg FLAGS_REG)
8170 (compare (any_or:SWI
8171 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8172 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8173 (const_int 0)))
8174 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8175 (any_or:SWI (match_dup 1) (match_dup 2)))]
8176 "ix86_match_ccmode (insn, CCNOmode)
8177 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8178 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8179 [(set_attr "type" "alu")
8180 (set_attr "mode" "<MODE>")])
8181
8182 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8183 ;; ??? Special case for immediate operand is missing - it is tricky.
8184 (define_insn "*<code>si_2_zext"
8185 [(set (reg FLAGS_REG)
8186 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8187 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8188 (const_int 0)))
8189 (set (match_operand:DI 0 "register_operand" "=r")
8190 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8191 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8192 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8193 "<logic>{l}\t{%2, %k0|%k0, %2}"
8194 [(set_attr "type" "alu")
8195 (set_attr "mode" "SI")])
8196
8197 (define_insn "*<code>si_2_zext_imm"
8198 [(set (reg FLAGS_REG)
8199 (compare (any_or:SI
8200 (match_operand:SI 1 "nonimmediate_operand" "%0")
8201 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8202 (const_int 0)))
8203 (set (match_operand:DI 0 "register_operand" "=r")
8204 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8205 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8206 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8207 "<logic>{l}\t{%2, %k0|%k0, %2}"
8208 [(set_attr "type" "alu")
8209 (set_attr "mode" "SI")])
8210
8211 (define_insn "*<code>qi_2_slp"
8212 [(set (reg FLAGS_REG)
8213 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8214 (match_operand:QI 1 "general_operand" "qmn,qn"))
8215 (const_int 0)))
8216 (set (strict_low_part (match_dup 0))
8217 (any_or:QI (match_dup 0) (match_dup 1)))]
8218 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8219 && ix86_match_ccmode (insn, CCNOmode)
8220 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8221 "<logic>{b}\t{%1, %0|%0, %1}"
8222 [(set_attr "type" "alu1")
8223 (set_attr "mode" "QI")])
8224
8225 (define_insn "*<code><mode>_3"
8226 [(set (reg FLAGS_REG)
8227 (compare (any_or:SWI
8228 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8229 (match_operand:SWI 2 "<general_operand>" "<g>"))
8230 (const_int 0)))
8231 (clobber (match_scratch:SWI 0 "=<r>"))]
8232 "ix86_match_ccmode (insn, CCNOmode)
8233 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8234 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8235 [(set_attr "type" "alu")
8236 (set_attr "mode" "<MODE>")])
8237
8238 (define_insn "*<code>qi_ext_0"
8239 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8240 (const_int 8)
8241 (const_int 8))
8242 (any_or:SI
8243 (zero_extract:SI
8244 (match_operand 1 "ext_register_operand" "0")
8245 (const_int 8)
8246 (const_int 8))
8247 (match_operand 2 "const_int_operand" "n")))
8248 (clobber (reg:CC FLAGS_REG))]
8249 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8250 "<logic>{b}\t{%2, %h0|%h0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "length_immediate" "1")
8253 (set_attr "modrm" "1")
8254 (set_attr "mode" "QI")])
8255
8256 (define_insn "*<code>qi_ext_1_rex64"
8257 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8258 (const_int 8)
8259 (const_int 8))
8260 (any_or:SI
8261 (zero_extract:SI
8262 (match_operand 1 "ext_register_operand" "0")
8263 (const_int 8)
8264 (const_int 8))
8265 (zero_extend:SI
8266 (match_operand 2 "ext_register_operand" "Q"))))
8267 (clobber (reg:CC FLAGS_REG))]
8268 "TARGET_64BIT
8269 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8270 "<logic>{b}\t{%2, %h0|%h0, %2}"
8271 [(set_attr "type" "alu")
8272 (set_attr "length_immediate" "0")
8273 (set_attr "mode" "QI")])
8274
8275 (define_insn "*<code>qi_ext_1"
8276 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8277 (const_int 8)
8278 (const_int 8))
8279 (any_or:SI
8280 (zero_extract:SI
8281 (match_operand 1 "ext_register_operand" "0")
8282 (const_int 8)
8283 (const_int 8))
8284 (zero_extend:SI
8285 (match_operand:QI 2 "general_operand" "Qm"))))
8286 (clobber (reg:CC FLAGS_REG))]
8287 "!TARGET_64BIT
8288 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8289 "<logic>{b}\t{%2, %h0|%h0, %2}"
8290 [(set_attr "type" "alu")
8291 (set_attr "length_immediate" "0")
8292 (set_attr "mode" "QI")])
8293
8294 (define_insn "*<code>qi_ext_2"
8295 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8296 (const_int 8)
8297 (const_int 8))
8298 (any_or:SI
8299 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8300 (const_int 8)
8301 (const_int 8))
8302 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8303 (const_int 8)
8304 (const_int 8))))
8305 (clobber (reg:CC FLAGS_REG))]
8306 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8307 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8308 [(set_attr "type" "alu")
8309 (set_attr "length_immediate" "0")
8310 (set_attr "mode" "QI")])
8311
8312 (define_split
8313 [(set (match_operand 0 "register_operand" "")
8314 (any_or (match_operand 1 "register_operand" "")
8315 (match_operand 2 "const_int_operand" "")))
8316 (clobber (reg:CC FLAGS_REG))]
8317 "reload_completed
8318 && QI_REG_P (operands[0])
8319 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8320 && !(INTVAL (operands[2]) & ~(255 << 8))
8321 && GET_MODE (operands[0]) != QImode"
8322 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8323 (any_or:SI (zero_extract:SI (match_dup 1)
8324 (const_int 8) (const_int 8))
8325 (match_dup 2)))
8326 (clobber (reg:CC FLAGS_REG))])]
8327 {
8328 operands[0] = gen_lowpart (SImode, operands[0]);
8329 operands[1] = gen_lowpart (SImode, operands[1]);
8330 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8331 })
8332
8333 ;; Since OR can be encoded with sign extended immediate, this is only
8334 ;; profitable when 7th bit is set.
8335 (define_split
8336 [(set (match_operand 0 "register_operand" "")
8337 (any_or (match_operand 1 "general_operand" "")
8338 (match_operand 2 "const_int_operand" "")))
8339 (clobber (reg:CC FLAGS_REG))]
8340 "reload_completed
8341 && ANY_QI_REG_P (operands[0])
8342 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8343 && !(INTVAL (operands[2]) & ~255)
8344 && (INTVAL (operands[2]) & 128)
8345 && GET_MODE (operands[0]) != QImode"
8346 [(parallel [(set (strict_low_part (match_dup 0))
8347 (any_or:QI (match_dup 1)
8348 (match_dup 2)))
8349 (clobber (reg:CC FLAGS_REG))])]
8350 {
8351 operands[0] = gen_lowpart (QImode, operands[0]);
8352 operands[1] = gen_lowpart (QImode, operands[1]);
8353 operands[2] = gen_lowpart (QImode, operands[2]);
8354 })
8355
8356 (define_expand "xorqi_cc_ext_1"
8357 [(parallel [
8358 (set (reg:CCNO FLAGS_REG)
8359 (compare:CCNO
8360 (xor:SI
8361 (zero_extract:SI
8362 (match_operand 1 "ext_register_operand" "")
8363 (const_int 8)
8364 (const_int 8))
8365 (match_operand:QI 2 "general_operand" ""))
8366 (const_int 0)))
8367 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8368 (const_int 8)
8369 (const_int 8))
8370 (xor:SI
8371 (zero_extract:SI
8372 (match_dup 1)
8373 (const_int 8)
8374 (const_int 8))
8375 (match_dup 2)))])])
8376
8377 (define_insn "*xorqi_cc_ext_1_rex64"
8378 [(set (reg FLAGS_REG)
8379 (compare
8380 (xor:SI
8381 (zero_extract:SI
8382 (match_operand 1 "ext_register_operand" "0")
8383 (const_int 8)
8384 (const_int 8))
8385 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8386 (const_int 0)))
8387 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8388 (const_int 8)
8389 (const_int 8))
8390 (xor:SI
8391 (zero_extract:SI
8392 (match_dup 1)
8393 (const_int 8)
8394 (const_int 8))
8395 (match_dup 2)))]
8396 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8397 "xor{b}\t{%2, %h0|%h0, %2}"
8398 [(set_attr "type" "alu")
8399 (set_attr "modrm" "1")
8400 (set_attr "mode" "QI")])
8401
8402 (define_insn "*xorqi_cc_ext_1"
8403 [(set (reg FLAGS_REG)
8404 (compare
8405 (xor:SI
8406 (zero_extract:SI
8407 (match_operand 1 "ext_register_operand" "0")
8408 (const_int 8)
8409 (const_int 8))
8410 (match_operand:QI 2 "general_operand" "qmn"))
8411 (const_int 0)))
8412 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8413 (const_int 8)
8414 (const_int 8))
8415 (xor:SI
8416 (zero_extract:SI
8417 (match_dup 1)
8418 (const_int 8)
8419 (const_int 8))
8420 (match_dup 2)))]
8421 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8422 "xor{b}\t{%2, %h0|%h0, %2}"
8423 [(set_attr "type" "alu")
8424 (set_attr "modrm" "1")
8425 (set_attr "mode" "QI")])
8426 \f
8427 ;; Negation instructions
8428
8429 (define_expand "neg<mode>2"
8430 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8431 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8432 ""
8433 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8434
8435 (define_insn_and_split "*neg<dwi>2_doubleword"
8436 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8437 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8438 (clobber (reg:CC FLAGS_REG))]
8439 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8440 "#"
8441 "reload_completed"
8442 [(parallel
8443 [(set (reg:CCZ FLAGS_REG)
8444 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8445 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8446 (parallel
8447 [(set (match_dup 2)
8448 (plus:DWIH (match_dup 3)
8449 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8450 (const_int 0))))
8451 (clobber (reg:CC FLAGS_REG))])
8452 (parallel
8453 [(set (match_dup 2)
8454 (neg:DWIH (match_dup 2)))
8455 (clobber (reg:CC FLAGS_REG))])]
8456 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8457
8458 (define_insn "*neg<mode>2_1"
8459 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8460 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8461 (clobber (reg:CC FLAGS_REG))]
8462 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8463 "neg{<imodesuffix>}\t%0"
8464 [(set_attr "type" "negnot")
8465 (set_attr "mode" "<MODE>")])
8466
8467 ;; Combine is quite creative about this pattern.
8468 (define_insn "*negsi2_1_zext"
8469 [(set (match_operand:DI 0 "register_operand" "=r")
8470 (lshiftrt:DI
8471 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8472 (const_int 32)))
8473 (const_int 32)))
8474 (clobber (reg:CC FLAGS_REG))]
8475 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8476 "neg{l}\t%k0"
8477 [(set_attr "type" "negnot")
8478 (set_attr "mode" "SI")])
8479
8480 ;; The problem with neg is that it does not perform (compare x 0),
8481 ;; it really performs (compare 0 x), which leaves us with the zero
8482 ;; flag being the only useful item.
8483
8484 (define_insn "*neg<mode>2_cmpz"
8485 [(set (reg:CCZ FLAGS_REG)
8486 (compare:CCZ
8487 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8488 (const_int 0)))
8489 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8490 (neg:SWI (match_dup 1)))]
8491 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8492 "neg{<imodesuffix>}\t%0"
8493 [(set_attr "type" "negnot")
8494 (set_attr "mode" "<MODE>")])
8495
8496 (define_insn "*negsi2_cmpz_zext"
8497 [(set (reg:CCZ FLAGS_REG)
8498 (compare:CCZ
8499 (lshiftrt:DI
8500 (neg:DI (ashift:DI
8501 (match_operand:DI 1 "register_operand" "0")
8502 (const_int 32)))
8503 (const_int 32))
8504 (const_int 0)))
8505 (set (match_operand:DI 0 "register_operand" "=r")
8506 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8507 (const_int 32)))
8508 (const_int 32)))]
8509 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8510 "neg{l}\t%k0"
8511 [(set_attr "type" "negnot")
8512 (set_attr "mode" "SI")])
8513
8514 ;; Changing of sign for FP values is doable using integer unit too.
8515
8516 (define_expand "<code><mode>2"
8517 [(set (match_operand:X87MODEF 0 "register_operand" "")
8518 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8519 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8520 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8521
8522 (define_insn "*absneg<mode>2_mixed"
8523 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8524 (match_operator:MODEF 3 "absneg_operator"
8525 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8526 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8527 (clobber (reg:CC FLAGS_REG))]
8528 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8529 "#")
8530
8531 (define_insn "*absneg<mode>2_sse"
8532 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8533 (match_operator:MODEF 3 "absneg_operator"
8534 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8535 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8538 "#")
8539
8540 (define_insn "*absneg<mode>2_i387"
8541 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8542 (match_operator:X87MODEF 3 "absneg_operator"
8543 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8544 (use (match_operand 2 "" ""))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8547 "#")
8548
8549 (define_expand "<code>tf2"
8550 [(set (match_operand:TF 0 "register_operand" "")
8551 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8552 "TARGET_SSE2"
8553 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8554
8555 (define_insn "*absnegtf2_sse"
8556 [(set (match_operand:TF 0 "register_operand" "=x,x")
8557 (match_operator:TF 3 "absneg_operator"
8558 [(match_operand:TF 1 "register_operand" "0,x")]))
8559 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8560 (clobber (reg:CC FLAGS_REG))]
8561 "TARGET_SSE2"
8562 "#")
8563
8564 ;; Splitters for fp abs and neg.
8565
8566 (define_split
8567 [(set (match_operand 0 "fp_register_operand" "")
8568 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8569 (use (match_operand 2 "" ""))
8570 (clobber (reg:CC FLAGS_REG))]
8571 "reload_completed"
8572 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8573
8574 (define_split
8575 [(set (match_operand 0 "register_operand" "")
8576 (match_operator 3 "absneg_operator"
8577 [(match_operand 1 "register_operand" "")]))
8578 (use (match_operand 2 "nonimmediate_operand" ""))
8579 (clobber (reg:CC FLAGS_REG))]
8580 "reload_completed && SSE_REG_P (operands[0])"
8581 [(set (match_dup 0) (match_dup 3))]
8582 {
8583 enum machine_mode mode = GET_MODE (operands[0]);
8584 enum machine_mode vmode = GET_MODE (operands[2]);
8585 rtx tmp;
8586
8587 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8588 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8589 if (operands_match_p (operands[0], operands[2]))
8590 {
8591 tmp = operands[1];
8592 operands[1] = operands[2];
8593 operands[2] = tmp;
8594 }
8595 if (GET_CODE (operands[3]) == ABS)
8596 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8597 else
8598 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8599 operands[3] = tmp;
8600 })
8601
8602 (define_split
8603 [(set (match_operand:SF 0 "register_operand" "")
8604 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8605 (use (match_operand:V4SF 2 "" ""))
8606 (clobber (reg:CC FLAGS_REG))]
8607 "reload_completed"
8608 [(parallel [(set (match_dup 0) (match_dup 1))
8609 (clobber (reg:CC FLAGS_REG))])]
8610 {
8611 rtx tmp;
8612 operands[0] = gen_lowpart (SImode, operands[0]);
8613 if (GET_CODE (operands[1]) == ABS)
8614 {
8615 tmp = gen_int_mode (0x7fffffff, SImode);
8616 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8617 }
8618 else
8619 {
8620 tmp = gen_int_mode (0x80000000, SImode);
8621 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8622 }
8623 operands[1] = tmp;
8624 })
8625
8626 (define_split
8627 [(set (match_operand:DF 0 "register_operand" "")
8628 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8629 (use (match_operand 2 "" ""))
8630 (clobber (reg:CC FLAGS_REG))]
8631 "reload_completed"
8632 [(parallel [(set (match_dup 0) (match_dup 1))
8633 (clobber (reg:CC FLAGS_REG))])]
8634 {
8635 rtx tmp;
8636 if (TARGET_64BIT)
8637 {
8638 tmp = gen_lowpart (DImode, operands[0]);
8639 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8640 operands[0] = tmp;
8641
8642 if (GET_CODE (operands[1]) == ABS)
8643 tmp = const0_rtx;
8644 else
8645 tmp = gen_rtx_NOT (DImode, tmp);
8646 }
8647 else
8648 {
8649 operands[0] = gen_highpart (SImode, operands[0]);
8650 if (GET_CODE (operands[1]) == ABS)
8651 {
8652 tmp = gen_int_mode (0x7fffffff, SImode);
8653 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8654 }
8655 else
8656 {
8657 tmp = gen_int_mode (0x80000000, SImode);
8658 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8659 }
8660 }
8661 operands[1] = tmp;
8662 })
8663
8664 (define_split
8665 [(set (match_operand:XF 0 "register_operand" "")
8666 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8667 (use (match_operand 2 "" ""))
8668 (clobber (reg:CC FLAGS_REG))]
8669 "reload_completed"
8670 [(parallel [(set (match_dup 0) (match_dup 1))
8671 (clobber (reg:CC FLAGS_REG))])]
8672 {
8673 rtx tmp;
8674 operands[0] = gen_rtx_REG (SImode,
8675 true_regnum (operands[0])
8676 + (TARGET_64BIT ? 1 : 2));
8677 if (GET_CODE (operands[1]) == ABS)
8678 {
8679 tmp = GEN_INT (0x7fff);
8680 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8681 }
8682 else
8683 {
8684 tmp = GEN_INT (0x8000);
8685 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8686 }
8687 operands[1] = tmp;
8688 })
8689
8690 ;; Conditionalize these after reload. If they match before reload, we
8691 ;; lose the clobber and ability to use integer instructions.
8692
8693 (define_insn "*<code><mode>2_1"
8694 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8695 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8696 "TARGET_80387
8697 && (reload_completed
8698 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8699 "f<absneg_mnemonic>"
8700 [(set_attr "type" "fsgn")
8701 (set_attr "mode" "<MODE>")])
8702
8703 (define_insn "*<code>extendsfdf2"
8704 [(set (match_operand:DF 0 "register_operand" "=f")
8705 (absneg:DF (float_extend:DF
8706 (match_operand:SF 1 "register_operand" "0"))))]
8707 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8708 "f<absneg_mnemonic>"
8709 [(set_attr "type" "fsgn")
8710 (set_attr "mode" "DF")])
8711
8712 (define_insn "*<code>extendsfxf2"
8713 [(set (match_operand:XF 0 "register_operand" "=f")
8714 (absneg:XF (float_extend:XF
8715 (match_operand:SF 1 "register_operand" "0"))))]
8716 "TARGET_80387"
8717 "f<absneg_mnemonic>"
8718 [(set_attr "type" "fsgn")
8719 (set_attr "mode" "XF")])
8720
8721 (define_insn "*<code>extenddfxf2"
8722 [(set (match_operand:XF 0 "register_operand" "=f")
8723 (absneg:XF (float_extend:XF
8724 (match_operand:DF 1 "register_operand" "0"))))]
8725 "TARGET_80387"
8726 "f<absneg_mnemonic>"
8727 [(set_attr "type" "fsgn")
8728 (set_attr "mode" "XF")])
8729
8730 ;; Copysign instructions
8731
8732 (define_mode_iterator CSGNMODE [SF DF TF])
8733 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8734
8735 (define_expand "copysign<mode>3"
8736 [(match_operand:CSGNMODE 0 "register_operand" "")
8737 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8738 (match_operand:CSGNMODE 2 "register_operand" "")]
8739 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8740 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8741 "ix86_expand_copysign (operands); DONE;")
8742
8743 (define_insn_and_split "copysign<mode>3_const"
8744 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8745 (unspec:CSGNMODE
8746 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8747 (match_operand:CSGNMODE 2 "register_operand" "0")
8748 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8749 UNSPEC_COPYSIGN))]
8750 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8751 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8752 "#"
8753 "&& reload_completed"
8754 [(const_int 0)]
8755 "ix86_split_copysign_const (operands); DONE;")
8756
8757 (define_insn "copysign<mode>3_var"
8758 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8759 (unspec:CSGNMODE
8760 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8761 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8762 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8763 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8764 UNSPEC_COPYSIGN))
8765 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8766 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8767 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8768 "#")
8769
8770 (define_split
8771 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8772 (unspec:CSGNMODE
8773 [(match_operand:CSGNMODE 2 "register_operand" "")
8774 (match_operand:CSGNMODE 3 "register_operand" "")
8775 (match_operand:<CSGNVMODE> 4 "" "")
8776 (match_operand:<CSGNVMODE> 5 "" "")]
8777 UNSPEC_COPYSIGN))
8778 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8779 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8780 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8781 && reload_completed"
8782 [(const_int 0)]
8783 "ix86_split_copysign_var (operands); DONE;")
8784 \f
8785 ;; One complement instructions
8786
8787 (define_expand "one_cmpl<mode>2"
8788 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8789 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8790 ""
8791 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8792
8793 (define_insn "*one_cmpl<mode>2_1"
8794 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8795 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8796 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8797 "not{<imodesuffix>}\t%0"
8798 [(set_attr "type" "negnot")
8799 (set_attr "mode" "<MODE>")])
8800
8801 ;; %%% Potential partial reg stall on alternative 1. What to do?
8802 (define_insn "*one_cmplqi2_1"
8803 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8804 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8805 "ix86_unary_operator_ok (NOT, QImode, operands)"
8806 "@
8807 not{b}\t%0
8808 not{l}\t%k0"
8809 [(set_attr "type" "negnot")
8810 (set_attr "mode" "QI,SI")])
8811
8812 ;; ??? Currently never generated - xor is used instead.
8813 (define_insn "*one_cmplsi2_1_zext"
8814 [(set (match_operand:DI 0 "register_operand" "=r")
8815 (zero_extend:DI
8816 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8817 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8818 "not{l}\t%k0"
8819 [(set_attr "type" "negnot")
8820 (set_attr "mode" "SI")])
8821
8822 (define_insn "*one_cmpl<mode>2_2"
8823 [(set (reg FLAGS_REG)
8824 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8825 (const_int 0)))
8826 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8827 (not:SWI (match_dup 1)))]
8828 "ix86_match_ccmode (insn, CCNOmode)
8829 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8830 "#"
8831 [(set_attr "type" "alu1")
8832 (set_attr "mode" "<MODE>")])
8833
8834 (define_split
8835 [(set (match_operand 0 "flags_reg_operand" "")
8836 (match_operator 2 "compare_operator"
8837 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8838 (const_int 0)]))
8839 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8840 (not:SWI (match_dup 3)))]
8841 "ix86_match_ccmode (insn, CCNOmode)"
8842 [(parallel [(set (match_dup 0)
8843 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8844 (const_int 0)]))
8845 (set (match_dup 1)
8846 (xor:SWI (match_dup 3) (const_int -1)))])])
8847
8848 ;; ??? Currently never generated - xor is used instead.
8849 (define_insn "*one_cmplsi2_2_zext"
8850 [(set (reg FLAGS_REG)
8851 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8852 (const_int 0)))
8853 (set (match_operand:DI 0 "register_operand" "=r")
8854 (zero_extend:DI (not:SI (match_dup 1))))]
8855 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8856 && ix86_unary_operator_ok (NOT, SImode, operands)"
8857 "#"
8858 [(set_attr "type" "alu1")
8859 (set_attr "mode" "SI")])
8860
8861 (define_split
8862 [(set (match_operand 0 "flags_reg_operand" "")
8863 (match_operator 2 "compare_operator"
8864 [(not:SI (match_operand:SI 3 "register_operand" ""))
8865 (const_int 0)]))
8866 (set (match_operand:DI 1 "register_operand" "")
8867 (zero_extend:DI (not:SI (match_dup 3))))]
8868 "ix86_match_ccmode (insn, CCNOmode)"
8869 [(parallel [(set (match_dup 0)
8870 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8871 (const_int 0)]))
8872 (set (match_dup 1)
8873 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8874 \f
8875 ;; Shift instructions
8876
8877 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8878 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8879 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8880 ;; from the assembler input.
8881 ;;
8882 ;; This instruction shifts the target reg/mem as usual, but instead of
8883 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8884 ;; is a left shift double, bits are taken from the high order bits of
8885 ;; reg, else if the insn is a shift right double, bits are taken from the
8886 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8887 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8888 ;;
8889 ;; Since sh[lr]d does not change the `reg' operand, that is done
8890 ;; separately, making all shifts emit pairs of shift double and normal
8891 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8892 ;; support a 63 bit shift, each shift where the count is in a reg expands
8893 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8894 ;;
8895 ;; If the shift count is a constant, we need never emit more than one
8896 ;; shift pair, instead using moves and sign extension for counts greater
8897 ;; than 31.
8898
8899 (define_expand "ashl<mode>3"
8900 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8901 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8902 (match_operand:QI 2 "nonmemory_operand" "")))]
8903 ""
8904 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8905
8906 (define_insn "*ashl<mode>3_doubleword"
8907 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8908 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8909 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8910 (clobber (reg:CC FLAGS_REG))]
8911 ""
8912 "#"
8913 [(set_attr "type" "multi")])
8914
8915 (define_split
8916 [(set (match_operand:DWI 0 "register_operand" "")
8917 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8918 (match_operand:QI 2 "nonmemory_operand" "")))
8919 (clobber (reg:CC FLAGS_REG))]
8920 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8921 [(const_int 0)]
8922 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8923
8924 ;; By default we don't ask for a scratch register, because when DWImode
8925 ;; values are manipulated, registers are already at a premium. But if
8926 ;; we have one handy, we won't turn it away.
8927
8928 (define_peephole2
8929 [(match_scratch:DWIH 3 "r")
8930 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8931 (ashift:<DWI>
8932 (match_operand:<DWI> 1 "nonmemory_operand" "")
8933 (match_operand:QI 2 "nonmemory_operand" "")))
8934 (clobber (reg:CC FLAGS_REG))])
8935 (match_dup 3)]
8936 "TARGET_CMOVE"
8937 [(const_int 0)]
8938 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8939
8940 (define_insn "x86_64_shld"
8941 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8942 (ior:DI (ashift:DI (match_dup 0)
8943 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8944 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8945 (minus:QI (const_int 64) (match_dup 2)))))
8946 (clobber (reg:CC FLAGS_REG))]
8947 "TARGET_64BIT"
8948 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8949 [(set_attr "type" "ishift")
8950 (set_attr "prefix_0f" "1")
8951 (set_attr "mode" "DI")
8952 (set_attr "athlon_decode" "vector")
8953 (set_attr "amdfam10_decode" "vector")
8954 (set_attr "bdver1_decode" "vector")])
8955
8956 (define_insn "x86_shld"
8957 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8958 (ior:SI (ashift:SI (match_dup 0)
8959 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8960 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8961 (minus:QI (const_int 32) (match_dup 2)))))
8962 (clobber (reg:CC FLAGS_REG))]
8963 ""
8964 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8965 [(set_attr "type" "ishift")
8966 (set_attr "prefix_0f" "1")
8967 (set_attr "mode" "SI")
8968 (set_attr "pent_pair" "np")
8969 (set_attr "athlon_decode" "vector")
8970 (set_attr "amdfam10_decode" "vector")
8971 (set_attr "bdver1_decode" "vector")])
8972
8973 (define_expand "x86_shift<mode>_adj_1"
8974 [(set (reg:CCZ FLAGS_REG)
8975 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8976 (match_dup 4))
8977 (const_int 0)))
8978 (set (match_operand:SWI48 0 "register_operand" "")
8979 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8980 (match_operand:SWI48 1 "register_operand" "")
8981 (match_dup 0)))
8982 (set (match_dup 1)
8983 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8984 (match_operand:SWI48 3 "register_operand" "")
8985 (match_dup 1)))]
8986 "TARGET_CMOVE"
8987 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8988
8989 (define_expand "x86_shift<mode>_adj_2"
8990 [(use (match_operand:SWI48 0 "register_operand" ""))
8991 (use (match_operand:SWI48 1 "register_operand" ""))
8992 (use (match_operand:QI 2 "register_operand" ""))]
8993 ""
8994 {
8995 rtx label = gen_label_rtx ();
8996 rtx tmp;
8997
8998 emit_insn (gen_testqi_ccz_1 (operands[2],
8999 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9000
9001 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9002 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9003 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9004 gen_rtx_LABEL_REF (VOIDmode, label),
9005 pc_rtx);
9006 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9007 JUMP_LABEL (tmp) = label;
9008
9009 emit_move_insn (operands[0], operands[1]);
9010 ix86_expand_clear (operands[1]);
9011
9012 emit_label (label);
9013 LABEL_NUSES (label) = 1;
9014
9015 DONE;
9016 })
9017
9018 ;; Avoid useless masking of count operand.
9019 (define_insn_and_split "*ashl<mode>3_mask"
9020 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9021 (ashift:SWI48
9022 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9023 (subreg:QI
9024 (and:SI
9025 (match_operand:SI 2 "nonimmediate_operand" "c")
9026 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9027 (clobber (reg:CC FLAGS_REG))]
9028 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9029 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9030 == GET_MODE_BITSIZE (<MODE>mode)-1"
9031 "#"
9032 "&& 1"
9033 [(parallel [(set (match_dup 0)
9034 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9035 (clobber (reg:CC FLAGS_REG))])]
9036 {
9037 if (can_create_pseudo_p ())
9038 operands [2] = force_reg (SImode, operands[2]);
9039
9040 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9041 }
9042 [(set_attr "type" "ishift")
9043 (set_attr "mode" "<MODE>")])
9044
9045 (define_insn "*bmi2_ashl<mode>3_1"
9046 [(set (match_operand:SWI48 0 "register_operand" "=r")
9047 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9048 (match_operand:SWI48 2 "register_operand" "r")))]
9049 "TARGET_BMI2"
9050 "shlx\t{%2, %1, %0|%0, %1, %2}"
9051 [(set_attr "type" "ishiftx")
9052 (set_attr "mode" "<MODE>")])
9053
9054 (define_insn "*ashl<mode>3_1"
9055 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9056 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9057 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9058 (clobber (reg:CC FLAGS_REG))]
9059 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9060 {
9061 switch (get_attr_type (insn))
9062 {
9063 case TYPE_LEA:
9064 case TYPE_ISHIFTX:
9065 return "#";
9066
9067 case TYPE_ALU:
9068 gcc_assert (operands[2] == const1_rtx);
9069 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9070 return "add{<imodesuffix>}\t%0, %0";
9071
9072 default:
9073 if (operands[2] == const1_rtx
9074 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9075 return "sal{<imodesuffix>}\t%0";
9076 else
9077 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9078 }
9079 }
9080 [(set_attr "isa" "*,*,bmi2")
9081 (set (attr "type")
9082 (cond [(eq_attr "alternative" "1")
9083 (const_string "lea")
9084 (eq_attr "alternative" "2")
9085 (const_string "ishiftx")
9086 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9087 (match_operand 0 "register_operand" ""))
9088 (match_operand 2 "const1_operand" ""))
9089 (const_string "alu")
9090 ]
9091 (const_string "ishift")))
9092 (set (attr "length_immediate")
9093 (if_then_else
9094 (ior (eq_attr "type" "alu")
9095 (and (eq_attr "type" "ishift")
9096 (and (match_operand 2 "const1_operand" "")
9097 (ior (match_test "TARGET_SHIFT1")
9098 (match_test "optimize_function_for_size_p (cfun)")))))
9099 (const_string "0")
9100 (const_string "*")))
9101 (set_attr "mode" "<MODE>")])
9102
9103 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9104 (define_split
9105 [(set (match_operand:SWI48 0 "register_operand" "")
9106 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9107 (match_operand:QI 2 "register_operand" "")))
9108 (clobber (reg:CC FLAGS_REG))]
9109 "TARGET_BMI2 && reload_completed"
9110 [(set (match_dup 0)
9111 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9112 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9113
9114 (define_insn "*bmi2_ashlsi3_1_zext"
9115 [(set (match_operand:DI 0 "register_operand" "=r")
9116 (zero_extend:DI
9117 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9118 (match_operand:SI 2 "register_operand" "r"))))]
9119 "TARGET_64BIT && TARGET_BMI2"
9120 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9121 [(set_attr "type" "ishiftx")
9122 (set_attr "mode" "SI")])
9123
9124 (define_insn "*ashlsi3_1_zext"
9125 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9126 (zero_extend:DI
9127 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9128 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9129 (clobber (reg:CC FLAGS_REG))]
9130 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9131 {
9132 switch (get_attr_type (insn))
9133 {
9134 case TYPE_LEA:
9135 case TYPE_ISHIFTX:
9136 return "#";
9137
9138 case TYPE_ALU:
9139 gcc_assert (operands[2] == const1_rtx);
9140 return "add{l}\t%k0, %k0";
9141
9142 default:
9143 if (operands[2] == const1_rtx
9144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9145 return "sal{l}\t%k0";
9146 else
9147 return "sal{l}\t{%2, %k0|%k0, %2}";
9148 }
9149 }
9150 [(set_attr "isa" "*,*,bmi2")
9151 (set (attr "type")
9152 (cond [(eq_attr "alternative" "1")
9153 (const_string "lea")
9154 (eq_attr "alternative" "2")
9155 (const_string "ishiftx")
9156 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9157 (match_operand 2 "const1_operand" ""))
9158 (const_string "alu")
9159 ]
9160 (const_string "ishift")))
9161 (set (attr "length_immediate")
9162 (if_then_else
9163 (ior (eq_attr "type" "alu")
9164 (and (eq_attr "type" "ishift")
9165 (and (match_operand 2 "const1_operand" "")
9166 (ior (match_test "TARGET_SHIFT1")
9167 (match_test "optimize_function_for_size_p (cfun)")))))
9168 (const_string "0")
9169 (const_string "*")))
9170 (set_attr "mode" "SI")])
9171
9172 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9173 (define_split
9174 [(set (match_operand:DI 0 "register_operand" "")
9175 (zero_extend:DI
9176 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9177 (match_operand:QI 2 "register_operand" ""))))
9178 (clobber (reg:CC FLAGS_REG))]
9179 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9180 [(set (match_dup 0)
9181 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9182 "operands[2] = gen_lowpart (SImode, operands[2]);")
9183
9184 (define_insn "*ashlhi3_1"
9185 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9186 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9187 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9188 (clobber (reg:CC FLAGS_REG))]
9189 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9190 {
9191 switch (get_attr_type (insn))
9192 {
9193 case TYPE_LEA:
9194 return "#";
9195
9196 case TYPE_ALU:
9197 gcc_assert (operands[2] == const1_rtx);
9198 return "add{w}\t%0, %0";
9199
9200 default:
9201 if (operands[2] == const1_rtx
9202 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9203 return "sal{w}\t%0";
9204 else
9205 return "sal{w}\t{%2, %0|%0, %2}";
9206 }
9207 }
9208 [(set (attr "type")
9209 (cond [(eq_attr "alternative" "1")
9210 (const_string "lea")
9211 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9212 (match_operand 0 "register_operand" ""))
9213 (match_operand 2 "const1_operand" ""))
9214 (const_string "alu")
9215 ]
9216 (const_string "ishift")))
9217 (set (attr "length_immediate")
9218 (if_then_else
9219 (ior (eq_attr "type" "alu")
9220 (and (eq_attr "type" "ishift")
9221 (and (match_operand 2 "const1_operand" "")
9222 (ior (match_test "TARGET_SHIFT1")
9223 (match_test "optimize_function_for_size_p (cfun)")))))
9224 (const_string "0")
9225 (const_string "*")))
9226 (set_attr "mode" "HI,SI")])
9227
9228 ;; %%% Potential partial reg stall on alternative 1. What to do?
9229 (define_insn "*ashlqi3_1"
9230 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9231 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9232 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9233 (clobber (reg:CC FLAGS_REG))]
9234 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9235 {
9236 switch (get_attr_type (insn))
9237 {
9238 case TYPE_LEA:
9239 return "#";
9240
9241 case TYPE_ALU:
9242 gcc_assert (operands[2] == const1_rtx);
9243 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9244 return "add{l}\t%k0, %k0";
9245 else
9246 return "add{b}\t%0, %0";
9247
9248 default:
9249 if (operands[2] == const1_rtx
9250 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9251 {
9252 if (get_attr_mode (insn) == MODE_SI)
9253 return "sal{l}\t%k0";
9254 else
9255 return "sal{b}\t%0";
9256 }
9257 else
9258 {
9259 if (get_attr_mode (insn) == MODE_SI)
9260 return "sal{l}\t{%2, %k0|%k0, %2}";
9261 else
9262 return "sal{b}\t{%2, %0|%0, %2}";
9263 }
9264 }
9265 }
9266 [(set (attr "type")
9267 (cond [(eq_attr "alternative" "2")
9268 (const_string "lea")
9269 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9270 (match_operand 0 "register_operand" ""))
9271 (match_operand 2 "const1_operand" ""))
9272 (const_string "alu")
9273 ]
9274 (const_string "ishift")))
9275 (set (attr "length_immediate")
9276 (if_then_else
9277 (ior (eq_attr "type" "alu")
9278 (and (eq_attr "type" "ishift")
9279 (and (match_operand 2 "const1_operand" "")
9280 (ior (match_test "TARGET_SHIFT1")
9281 (match_test "optimize_function_for_size_p (cfun)")))))
9282 (const_string "0")
9283 (const_string "*")))
9284 (set_attr "mode" "QI,SI,SI")])
9285
9286 (define_insn "*ashlqi3_1_slp"
9287 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9288 (ashift:QI (match_dup 0)
9289 (match_operand:QI 1 "nonmemory_operand" "cI")))
9290 (clobber (reg:CC FLAGS_REG))]
9291 "(optimize_function_for_size_p (cfun)
9292 || !TARGET_PARTIAL_FLAG_REG_STALL
9293 || (operands[1] == const1_rtx
9294 && (TARGET_SHIFT1
9295 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9296 {
9297 switch (get_attr_type (insn))
9298 {
9299 case TYPE_ALU:
9300 gcc_assert (operands[1] == const1_rtx);
9301 return "add{b}\t%0, %0";
9302
9303 default:
9304 if (operands[1] == const1_rtx
9305 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9306 return "sal{b}\t%0";
9307 else
9308 return "sal{b}\t{%1, %0|%0, %1}";
9309 }
9310 }
9311 [(set (attr "type")
9312 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9313 (match_operand 0 "register_operand" ""))
9314 (match_operand 1 "const1_operand" ""))
9315 (const_string "alu")
9316 ]
9317 (const_string "ishift1")))
9318 (set (attr "length_immediate")
9319 (if_then_else
9320 (ior (eq_attr "type" "alu")
9321 (and (eq_attr "type" "ishift1")
9322 (and (match_operand 1 "const1_operand" "")
9323 (ior (match_test "TARGET_SHIFT1")
9324 (match_test "optimize_function_for_size_p (cfun)")))))
9325 (const_string "0")
9326 (const_string "*")))
9327 (set_attr "mode" "QI")])
9328
9329 ;; Convert ashift to the lea pattern to avoid flags dependency.
9330 (define_split
9331 [(set (match_operand 0 "register_operand" "")
9332 (ashift (match_operand 1 "index_register_operand" "")
9333 (match_operand:QI 2 "const_int_operand" "")))
9334 (clobber (reg:CC FLAGS_REG))]
9335 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9336 && reload_completed
9337 && true_regnum (operands[0]) != true_regnum (operands[1])"
9338 [(const_int 0)]
9339 {
9340 enum machine_mode mode = GET_MODE (operands[0]);
9341 rtx pat;
9342
9343 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9344 {
9345 mode = SImode;
9346 operands[0] = gen_lowpart (mode, operands[0]);
9347 operands[1] = gen_lowpart (mode, operands[1]);
9348 }
9349
9350 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9351
9352 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9353
9354 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9355 DONE;
9356 })
9357
9358 ;; Convert ashift to the lea pattern to avoid flags dependency.
9359 (define_split
9360 [(set (match_operand:DI 0 "register_operand" "")
9361 (zero_extend:DI
9362 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9363 (match_operand:QI 2 "const_int_operand" ""))))
9364 (clobber (reg:CC FLAGS_REG))]
9365 "TARGET_64BIT && reload_completed
9366 && true_regnum (operands[0]) != true_regnum (operands[1])"
9367 [(set (match_dup 0)
9368 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9369 {
9370 operands[1] = gen_lowpart (DImode, operands[1]);
9371 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9372 })
9373
9374 ;; This pattern can't accept a variable shift count, since shifts by
9375 ;; zero don't affect the flags. We assume that shifts by constant
9376 ;; zero are optimized away.
9377 (define_insn "*ashl<mode>3_cmp"
9378 [(set (reg FLAGS_REG)
9379 (compare
9380 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9381 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9382 (const_int 0)))
9383 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9384 (ashift:SWI (match_dup 1) (match_dup 2)))]
9385 "(optimize_function_for_size_p (cfun)
9386 || !TARGET_PARTIAL_FLAG_REG_STALL
9387 || (operands[2] == const1_rtx
9388 && (TARGET_SHIFT1
9389 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9390 && ix86_match_ccmode (insn, CCGOCmode)
9391 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9392 {
9393 switch (get_attr_type (insn))
9394 {
9395 case TYPE_ALU:
9396 gcc_assert (operands[2] == const1_rtx);
9397 return "add{<imodesuffix>}\t%0, %0";
9398
9399 default:
9400 if (operands[2] == const1_rtx
9401 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9402 return "sal{<imodesuffix>}\t%0";
9403 else
9404 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9405 }
9406 }
9407 [(set (attr "type")
9408 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9409 (match_operand 0 "register_operand" ""))
9410 (match_operand 2 "const1_operand" ""))
9411 (const_string "alu")
9412 ]
9413 (const_string "ishift")))
9414 (set (attr "length_immediate")
9415 (if_then_else
9416 (ior (eq_attr "type" "alu")
9417 (and (eq_attr "type" "ishift")
9418 (and (match_operand 2 "const1_operand" "")
9419 (ior (match_test "TARGET_SHIFT1")
9420 (match_test "optimize_function_for_size_p (cfun)")))))
9421 (const_string "0")
9422 (const_string "*")))
9423 (set_attr "mode" "<MODE>")])
9424
9425 (define_insn "*ashlsi3_cmp_zext"
9426 [(set (reg FLAGS_REG)
9427 (compare
9428 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9429 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9430 (const_int 0)))
9431 (set (match_operand:DI 0 "register_operand" "=r")
9432 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9433 "TARGET_64BIT
9434 && (optimize_function_for_size_p (cfun)
9435 || !TARGET_PARTIAL_FLAG_REG_STALL
9436 || (operands[2] == const1_rtx
9437 && (TARGET_SHIFT1
9438 || TARGET_DOUBLE_WITH_ADD)))
9439 && ix86_match_ccmode (insn, CCGOCmode)
9440 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9441 {
9442 switch (get_attr_type (insn))
9443 {
9444 case TYPE_ALU:
9445 gcc_assert (operands[2] == const1_rtx);
9446 return "add{l}\t%k0, %k0";
9447
9448 default:
9449 if (operands[2] == const1_rtx
9450 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9451 return "sal{l}\t%k0";
9452 else
9453 return "sal{l}\t{%2, %k0|%k0, %2}";
9454 }
9455 }
9456 [(set (attr "type")
9457 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9458 (match_operand 2 "const1_operand" ""))
9459 (const_string "alu")
9460 ]
9461 (const_string "ishift")))
9462 (set (attr "length_immediate")
9463 (if_then_else
9464 (ior (eq_attr "type" "alu")
9465 (and (eq_attr "type" "ishift")
9466 (and (match_operand 2 "const1_operand" "")
9467 (ior (match_test "TARGET_SHIFT1")
9468 (match_test "optimize_function_for_size_p (cfun)")))))
9469 (const_string "0")
9470 (const_string "*")))
9471 (set_attr "mode" "SI")])
9472
9473 (define_insn "*ashl<mode>3_cconly"
9474 [(set (reg FLAGS_REG)
9475 (compare
9476 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9477 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9478 (const_int 0)))
9479 (clobber (match_scratch:SWI 0 "=<r>"))]
9480 "(optimize_function_for_size_p (cfun)
9481 || !TARGET_PARTIAL_FLAG_REG_STALL
9482 || (operands[2] == const1_rtx
9483 && (TARGET_SHIFT1
9484 || TARGET_DOUBLE_WITH_ADD)))
9485 && ix86_match_ccmode (insn, CCGOCmode)"
9486 {
9487 switch (get_attr_type (insn))
9488 {
9489 case TYPE_ALU:
9490 gcc_assert (operands[2] == const1_rtx);
9491 return "add{<imodesuffix>}\t%0, %0";
9492
9493 default:
9494 if (operands[2] == const1_rtx
9495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9496 return "sal{<imodesuffix>}\t%0";
9497 else
9498 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9499 }
9500 }
9501 [(set (attr "type")
9502 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9503 (match_operand 0 "register_operand" ""))
9504 (match_operand 2 "const1_operand" ""))
9505 (const_string "alu")
9506 ]
9507 (const_string "ishift")))
9508 (set (attr "length_immediate")
9509 (if_then_else
9510 (ior (eq_attr "type" "alu")
9511 (and (eq_attr "type" "ishift")
9512 (and (match_operand 2 "const1_operand" "")
9513 (ior (match_test "TARGET_SHIFT1")
9514 (match_test "optimize_function_for_size_p (cfun)")))))
9515 (const_string "0")
9516 (const_string "*")))
9517 (set_attr "mode" "<MODE>")])
9518
9519 ;; See comment above `ashl<mode>3' about how this works.
9520
9521 (define_expand "<shift_insn><mode>3"
9522 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9523 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9524 (match_operand:QI 2 "nonmemory_operand" "")))]
9525 ""
9526 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9527
9528 ;; Avoid useless masking of count operand.
9529 (define_insn_and_split "*<shift_insn><mode>3_mask"
9530 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9531 (any_shiftrt:SWI48
9532 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9533 (subreg:QI
9534 (and:SI
9535 (match_operand:SI 2 "nonimmediate_operand" "c")
9536 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9537 (clobber (reg:CC FLAGS_REG))]
9538 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9539 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9540 == GET_MODE_BITSIZE (<MODE>mode)-1"
9541 "#"
9542 "&& 1"
9543 [(parallel [(set (match_dup 0)
9544 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9545 (clobber (reg:CC FLAGS_REG))])]
9546 {
9547 if (can_create_pseudo_p ())
9548 operands [2] = force_reg (SImode, operands[2]);
9549
9550 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9551 }
9552 [(set_attr "type" "ishift")
9553 (set_attr "mode" "<MODE>")])
9554
9555 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9556 [(set (match_operand:DWI 0 "register_operand" "=r")
9557 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9558 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9559 (clobber (reg:CC FLAGS_REG))]
9560 ""
9561 "#"
9562 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9563 [(const_int 0)]
9564 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9565 [(set_attr "type" "multi")])
9566
9567 ;; By default we don't ask for a scratch register, because when DWImode
9568 ;; values are manipulated, registers are already at a premium. But if
9569 ;; we have one handy, we won't turn it away.
9570
9571 (define_peephole2
9572 [(match_scratch:DWIH 3 "r")
9573 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9574 (any_shiftrt:<DWI>
9575 (match_operand:<DWI> 1 "register_operand" "")
9576 (match_operand:QI 2 "nonmemory_operand" "")))
9577 (clobber (reg:CC FLAGS_REG))])
9578 (match_dup 3)]
9579 "TARGET_CMOVE"
9580 [(const_int 0)]
9581 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9582
9583 (define_insn "x86_64_shrd"
9584 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9585 (ior:DI (ashiftrt:DI (match_dup 0)
9586 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9587 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9588 (minus:QI (const_int 64) (match_dup 2)))))
9589 (clobber (reg:CC FLAGS_REG))]
9590 "TARGET_64BIT"
9591 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9592 [(set_attr "type" "ishift")
9593 (set_attr "prefix_0f" "1")
9594 (set_attr "mode" "DI")
9595 (set_attr "athlon_decode" "vector")
9596 (set_attr "amdfam10_decode" "vector")
9597 (set_attr "bdver1_decode" "vector")])
9598
9599 (define_insn "x86_shrd"
9600 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9601 (ior:SI (ashiftrt:SI (match_dup 0)
9602 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9603 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9604 (minus:QI (const_int 32) (match_dup 2)))))
9605 (clobber (reg:CC FLAGS_REG))]
9606 ""
9607 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9608 [(set_attr "type" "ishift")
9609 (set_attr "prefix_0f" "1")
9610 (set_attr "mode" "SI")
9611 (set_attr "pent_pair" "np")
9612 (set_attr "athlon_decode" "vector")
9613 (set_attr "amdfam10_decode" "vector")
9614 (set_attr "bdver1_decode" "vector")])
9615
9616 (define_insn "ashrdi3_cvt"
9617 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9618 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9619 (match_operand:QI 2 "const_int_operand" "")))
9620 (clobber (reg:CC FLAGS_REG))]
9621 "TARGET_64BIT && INTVAL (operands[2]) == 63
9622 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9623 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9624 "@
9625 {cqto|cqo}
9626 sar{q}\t{%2, %0|%0, %2}"
9627 [(set_attr "type" "imovx,ishift")
9628 (set_attr "prefix_0f" "0,*")
9629 (set_attr "length_immediate" "0,*")
9630 (set_attr "modrm" "0,1")
9631 (set_attr "mode" "DI")])
9632
9633 (define_insn "ashrsi3_cvt"
9634 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9635 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9636 (match_operand:QI 2 "const_int_operand" "")))
9637 (clobber (reg:CC FLAGS_REG))]
9638 "INTVAL (operands[2]) == 31
9639 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9640 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9641 "@
9642 {cltd|cdq}
9643 sar{l}\t{%2, %0|%0, %2}"
9644 [(set_attr "type" "imovx,ishift")
9645 (set_attr "prefix_0f" "0,*")
9646 (set_attr "length_immediate" "0,*")
9647 (set_attr "modrm" "0,1")
9648 (set_attr "mode" "SI")])
9649
9650 (define_insn "*ashrsi3_cvt_zext"
9651 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9652 (zero_extend:DI
9653 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9654 (match_operand:QI 2 "const_int_operand" ""))))
9655 (clobber (reg:CC FLAGS_REG))]
9656 "TARGET_64BIT && INTVAL (operands[2]) == 31
9657 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9658 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9659 "@
9660 {cltd|cdq}
9661 sar{l}\t{%2, %k0|%k0, %2}"
9662 [(set_attr "type" "imovx,ishift")
9663 (set_attr "prefix_0f" "0,*")
9664 (set_attr "length_immediate" "0,*")
9665 (set_attr "modrm" "0,1")
9666 (set_attr "mode" "SI")])
9667
9668 (define_expand "x86_shift<mode>_adj_3"
9669 [(use (match_operand:SWI48 0 "register_operand" ""))
9670 (use (match_operand:SWI48 1 "register_operand" ""))
9671 (use (match_operand:QI 2 "register_operand" ""))]
9672 ""
9673 {
9674 rtx label = gen_label_rtx ();
9675 rtx tmp;
9676
9677 emit_insn (gen_testqi_ccz_1 (operands[2],
9678 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9679
9680 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9681 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9682 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9683 gen_rtx_LABEL_REF (VOIDmode, label),
9684 pc_rtx);
9685 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9686 JUMP_LABEL (tmp) = label;
9687
9688 emit_move_insn (operands[0], operands[1]);
9689 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9690 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9691 emit_label (label);
9692 LABEL_NUSES (label) = 1;
9693
9694 DONE;
9695 })
9696
9697 (define_insn "*bmi2_<shift_insn><mode>3_1"
9698 [(set (match_operand:SWI48 0 "register_operand" "=r")
9699 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9700 (match_operand:SWI48 2 "register_operand" "r")))]
9701 "TARGET_BMI2"
9702 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9703 [(set_attr "type" "ishiftx")
9704 (set_attr "mode" "<MODE>")])
9705
9706 (define_insn "*<shift_insn><mode>3_1"
9707 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9708 (any_shiftrt:SWI48
9709 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9710 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9711 (clobber (reg:CC FLAGS_REG))]
9712 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9713 {
9714 switch (get_attr_type (insn))
9715 {
9716 case TYPE_ISHIFTX:
9717 return "#";
9718
9719 default:
9720 if (operands[2] == const1_rtx
9721 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9722 return "<shift>{<imodesuffix>}\t%0";
9723 else
9724 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9725 }
9726 }
9727 [(set_attr "isa" "*,bmi2")
9728 (set_attr "type" "ishift,ishiftx")
9729 (set (attr "length_immediate")
9730 (if_then_else
9731 (and (match_operand 2 "const1_operand" "")
9732 (ior (match_test "TARGET_SHIFT1")
9733 (match_test "optimize_function_for_size_p (cfun)")))
9734 (const_string "0")
9735 (const_string "*")))
9736 (set_attr "mode" "<MODE>")])
9737
9738 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9739 (define_split
9740 [(set (match_operand:SWI48 0 "register_operand" "")
9741 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9742 (match_operand:QI 2 "register_operand" "")))
9743 (clobber (reg:CC FLAGS_REG))]
9744 "TARGET_BMI2 && reload_completed"
9745 [(set (match_dup 0)
9746 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9747 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9748
9749 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9750 [(set (match_operand:DI 0 "register_operand" "=r")
9751 (zero_extend:DI
9752 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9753 (match_operand:SI 2 "register_operand" "r"))))]
9754 "TARGET_64BIT && TARGET_BMI2"
9755 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9756 [(set_attr "type" "ishiftx")
9757 (set_attr "mode" "SI")])
9758
9759 (define_insn "*<shift_insn>si3_1_zext"
9760 [(set (match_operand:DI 0 "register_operand" "=r,r")
9761 (zero_extend:DI
9762 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9763 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9764 (clobber (reg:CC FLAGS_REG))]
9765 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9766 {
9767 switch (get_attr_type (insn))
9768 {
9769 case TYPE_ISHIFTX:
9770 return "#";
9771
9772 default:
9773 if (operands[2] == const1_rtx
9774 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9775 return "<shift>{l}\t%k0";
9776 else
9777 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9778 }
9779 }
9780 [(set_attr "isa" "*,bmi2")
9781 (set_attr "type" "ishift,ishiftx")
9782 (set (attr "length_immediate")
9783 (if_then_else
9784 (and (match_operand 2 "const1_operand" "")
9785 (ior (match_test "TARGET_SHIFT1")
9786 (match_test "optimize_function_for_size_p (cfun)")))
9787 (const_string "0")
9788 (const_string "*")))
9789 (set_attr "mode" "SI")])
9790
9791 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9792 (define_split
9793 [(set (match_operand:DI 0 "register_operand" "")
9794 (zero_extend:DI
9795 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9796 (match_operand:QI 2 "register_operand" ""))))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9799 [(set (match_dup 0)
9800 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9801 "operands[2] = gen_lowpart (SImode, operands[2]);")
9802
9803 (define_insn "*<shift_insn><mode>3_1"
9804 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9805 (any_shiftrt:SWI12
9806 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9807 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9808 (clobber (reg:CC FLAGS_REG))]
9809 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9810 {
9811 if (operands[2] == const1_rtx
9812 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9813 return "<shift>{<imodesuffix>}\t%0";
9814 else
9815 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9816 }
9817 [(set_attr "type" "ishift")
9818 (set (attr "length_immediate")
9819 (if_then_else
9820 (and (match_operand 2 "const1_operand" "")
9821 (ior (match_test "TARGET_SHIFT1")
9822 (match_test "optimize_function_for_size_p (cfun)")))
9823 (const_string "0")
9824 (const_string "*")))
9825 (set_attr "mode" "<MODE>")])
9826
9827 (define_insn "*<shift_insn>qi3_1_slp"
9828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9829 (any_shiftrt:QI (match_dup 0)
9830 (match_operand:QI 1 "nonmemory_operand" "cI")))
9831 (clobber (reg:CC FLAGS_REG))]
9832 "(optimize_function_for_size_p (cfun)
9833 || !TARGET_PARTIAL_REG_STALL
9834 || (operands[1] == const1_rtx
9835 && TARGET_SHIFT1))"
9836 {
9837 if (operands[1] == const1_rtx
9838 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9839 return "<shift>{b}\t%0";
9840 else
9841 return "<shift>{b}\t{%1, %0|%0, %1}";
9842 }
9843 [(set_attr "type" "ishift1")
9844 (set (attr "length_immediate")
9845 (if_then_else
9846 (and (match_operand 1 "const1_operand" "")
9847 (ior (match_test "TARGET_SHIFT1")
9848 (match_test "optimize_function_for_size_p (cfun)")))
9849 (const_string "0")
9850 (const_string "*")))
9851 (set_attr "mode" "QI")])
9852
9853 ;; This pattern can't accept a variable shift count, since shifts by
9854 ;; zero don't affect the flags. We assume that shifts by constant
9855 ;; zero are optimized away.
9856 (define_insn "*<shift_insn><mode>3_cmp"
9857 [(set (reg FLAGS_REG)
9858 (compare
9859 (any_shiftrt:SWI
9860 (match_operand:SWI 1 "nonimmediate_operand" "0")
9861 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9862 (const_int 0)))
9863 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9864 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9865 "(optimize_function_for_size_p (cfun)
9866 || !TARGET_PARTIAL_FLAG_REG_STALL
9867 || (operands[2] == const1_rtx
9868 && TARGET_SHIFT1))
9869 && ix86_match_ccmode (insn, CCGOCmode)
9870 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9871 {
9872 if (operands[2] == const1_rtx
9873 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9874 return "<shift>{<imodesuffix>}\t%0";
9875 else
9876 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9877 }
9878 [(set_attr "type" "ishift")
9879 (set (attr "length_immediate")
9880 (if_then_else
9881 (and (match_operand 2 "const1_operand" "")
9882 (ior (match_test "TARGET_SHIFT1")
9883 (match_test "optimize_function_for_size_p (cfun)")))
9884 (const_string "0")
9885 (const_string "*")))
9886 (set_attr "mode" "<MODE>")])
9887
9888 (define_insn "*<shift_insn>si3_cmp_zext"
9889 [(set (reg FLAGS_REG)
9890 (compare
9891 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9892 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9893 (const_int 0)))
9894 (set (match_operand:DI 0 "register_operand" "=r")
9895 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9896 "TARGET_64BIT
9897 && (optimize_function_for_size_p (cfun)
9898 || !TARGET_PARTIAL_FLAG_REG_STALL
9899 || (operands[2] == const1_rtx
9900 && TARGET_SHIFT1))
9901 && ix86_match_ccmode (insn, CCGOCmode)
9902 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9903 {
9904 if (operands[2] == const1_rtx
9905 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9906 return "<shift>{l}\t%k0";
9907 else
9908 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9909 }
9910 [(set_attr "type" "ishift")
9911 (set (attr "length_immediate")
9912 (if_then_else
9913 (and (match_operand 2 "const1_operand" "")
9914 (ior (match_test "TARGET_SHIFT1")
9915 (match_test "optimize_function_for_size_p (cfun)")))
9916 (const_string "0")
9917 (const_string "*")))
9918 (set_attr "mode" "SI")])
9919
9920 (define_insn "*<shift_insn><mode>3_cconly"
9921 [(set (reg FLAGS_REG)
9922 (compare
9923 (any_shiftrt:SWI
9924 (match_operand:SWI 1 "register_operand" "0")
9925 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9926 (const_int 0)))
9927 (clobber (match_scratch:SWI 0 "=<r>"))]
9928 "(optimize_function_for_size_p (cfun)
9929 || !TARGET_PARTIAL_FLAG_REG_STALL
9930 || (operands[2] == const1_rtx
9931 && TARGET_SHIFT1))
9932 && ix86_match_ccmode (insn, CCGOCmode)"
9933 {
9934 if (operands[2] == const1_rtx
9935 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9936 return "<shift>{<imodesuffix>}\t%0";
9937 else
9938 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9939 }
9940 [(set_attr "type" "ishift")
9941 (set (attr "length_immediate")
9942 (if_then_else
9943 (and (match_operand 2 "const1_operand" "")
9944 (ior (match_test "TARGET_SHIFT1")
9945 (match_test "optimize_function_for_size_p (cfun)")))
9946 (const_string "0")
9947 (const_string "*")))
9948 (set_attr "mode" "<MODE>")])
9949 \f
9950 ;; Rotate instructions
9951
9952 (define_expand "<rotate_insn>ti3"
9953 [(set (match_operand:TI 0 "register_operand" "")
9954 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9955 (match_operand:QI 2 "nonmemory_operand" "")))]
9956 "TARGET_64BIT"
9957 {
9958 if (const_1_to_63_operand (operands[2], VOIDmode))
9959 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9960 (operands[0], operands[1], operands[2]));
9961 else
9962 FAIL;
9963
9964 DONE;
9965 })
9966
9967 (define_expand "<rotate_insn>di3"
9968 [(set (match_operand:DI 0 "shiftdi_operand" "")
9969 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9970 (match_operand:QI 2 "nonmemory_operand" "")))]
9971 ""
9972 {
9973 if (TARGET_64BIT)
9974 ix86_expand_binary_operator (<CODE>, DImode, operands);
9975 else if (const_1_to_31_operand (operands[2], VOIDmode))
9976 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9977 (operands[0], operands[1], operands[2]));
9978 else
9979 FAIL;
9980
9981 DONE;
9982 })
9983
9984 (define_expand "<rotate_insn><mode>3"
9985 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9986 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9987 (match_operand:QI 2 "nonmemory_operand" "")))]
9988 ""
9989 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9990
9991 ;; Avoid useless masking of count operand.
9992 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9993 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9994 (any_rotate:SWI48
9995 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9996 (subreg:QI
9997 (and:SI
9998 (match_operand:SI 2 "nonimmediate_operand" "c")
9999 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10000 (clobber (reg:CC FLAGS_REG))]
10001 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10002 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10003 == GET_MODE_BITSIZE (<MODE>mode)-1"
10004 "#"
10005 "&& 1"
10006 [(parallel [(set (match_dup 0)
10007 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10008 (clobber (reg:CC FLAGS_REG))])]
10009 {
10010 if (can_create_pseudo_p ())
10011 operands [2] = force_reg (SImode, operands[2]);
10012
10013 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10014 }
10015 [(set_attr "type" "rotate")
10016 (set_attr "mode" "<MODE>")])
10017
10018 ;; Implement rotation using two double-precision
10019 ;; shift instructions and a scratch register.
10020
10021 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10022 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10023 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10024 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10025 (clobber (reg:CC FLAGS_REG))
10026 (clobber (match_scratch:DWIH 3 "=&r"))]
10027 ""
10028 "#"
10029 "reload_completed"
10030 [(set (match_dup 3) (match_dup 4))
10031 (parallel
10032 [(set (match_dup 4)
10033 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10034 (lshiftrt:DWIH (match_dup 5)
10035 (minus:QI (match_dup 6) (match_dup 2)))))
10036 (clobber (reg:CC FLAGS_REG))])
10037 (parallel
10038 [(set (match_dup 5)
10039 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10040 (lshiftrt:DWIH (match_dup 3)
10041 (minus:QI (match_dup 6) (match_dup 2)))))
10042 (clobber (reg:CC FLAGS_REG))])]
10043 {
10044 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10045
10046 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10047 })
10048
10049 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10050 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10051 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10052 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10053 (clobber (reg:CC FLAGS_REG))
10054 (clobber (match_scratch:DWIH 3 "=&r"))]
10055 ""
10056 "#"
10057 "reload_completed"
10058 [(set (match_dup 3) (match_dup 4))
10059 (parallel
10060 [(set (match_dup 4)
10061 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10062 (ashift:DWIH (match_dup 5)
10063 (minus:QI (match_dup 6) (match_dup 2)))))
10064 (clobber (reg:CC FLAGS_REG))])
10065 (parallel
10066 [(set (match_dup 5)
10067 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10068 (ashift:DWIH (match_dup 3)
10069 (minus:QI (match_dup 6) (match_dup 2)))))
10070 (clobber (reg:CC FLAGS_REG))])]
10071 {
10072 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10073
10074 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10075 })
10076
10077 (define_insn "*bmi2_rorx<mode>3_1"
10078 [(set (match_operand:SWI48 0 "register_operand" "=r")
10079 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10080 (match_operand:QI 2 "immediate_operand" "<S>")))]
10081 "TARGET_BMI2"
10082 "rorx\t{%2, %1, %0|%0, %1, %2}"
10083 [(set_attr "type" "rotatex")
10084 (set_attr "mode" "<MODE>")])
10085
10086 (define_insn "*<rotate_insn><mode>3_1"
10087 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10088 (any_rotate:SWI48
10089 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10090 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10091 (clobber (reg:CC FLAGS_REG))]
10092 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10093 {
10094 switch (get_attr_type (insn))
10095 {
10096 case TYPE_ROTATEX:
10097 return "#";
10098
10099 default:
10100 if (operands[2] == const1_rtx
10101 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10102 return "<rotate>{<imodesuffix>}\t%0";
10103 else
10104 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10105 }
10106 }
10107 [(set_attr "isa" "*,bmi2")
10108 (set_attr "type" "rotate,rotatex")
10109 (set (attr "length_immediate")
10110 (if_then_else
10111 (and (eq_attr "type" "rotate")
10112 (and (match_operand 2 "const1_operand" "")
10113 (ior (match_test "TARGET_SHIFT1")
10114 (match_test "optimize_function_for_size_p (cfun)"))))
10115 (const_string "0")
10116 (const_string "*")))
10117 (set_attr "mode" "<MODE>")])
10118
10119 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10120 (define_split
10121 [(set (match_operand:SWI48 0 "register_operand" "")
10122 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10123 (match_operand:QI 2 "immediate_operand" "")))
10124 (clobber (reg:CC FLAGS_REG))]
10125 "TARGET_BMI2 && reload_completed"
10126 [(set (match_dup 0)
10127 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10128 {
10129 operands[2]
10130 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10131 })
10132
10133 (define_split
10134 [(set (match_operand:SWI48 0 "register_operand" "")
10135 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10136 (match_operand:QI 2 "immediate_operand" "")))
10137 (clobber (reg:CC FLAGS_REG))]
10138 "TARGET_BMI2 && reload_completed"
10139 [(set (match_dup 0)
10140 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10141
10142 (define_insn "*bmi2_rorxsi3_1_zext"
10143 [(set (match_operand:DI 0 "register_operand" "=r")
10144 (zero_extend:DI
10145 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10146 (match_operand:QI 2 "immediate_operand" "I"))))]
10147 "TARGET_64BIT && TARGET_BMI2"
10148 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10149 [(set_attr "type" "rotatex")
10150 (set_attr "mode" "SI")])
10151
10152 (define_insn "*<rotate_insn>si3_1_zext"
10153 [(set (match_operand:DI 0 "register_operand" "=r,r")
10154 (zero_extend:DI
10155 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10156 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10157 (clobber (reg:CC FLAGS_REG))]
10158 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10159 {
10160 switch (get_attr_type (insn))
10161 {
10162 case TYPE_ROTATEX:
10163 return "#";
10164
10165 default:
10166 if (operands[2] == const1_rtx
10167 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10168 return "<rotate>{l}\t%k0";
10169 else
10170 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10171 }
10172 }
10173 [(set_attr "isa" "*,bmi2")
10174 (set_attr "type" "rotate,rotatex")
10175 (set (attr "length_immediate")
10176 (if_then_else
10177 (and (eq_attr "type" "rotate")
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" "SI")])
10184
10185 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10186 (define_split
10187 [(set (match_operand:DI 0 "register_operand" "")
10188 (zero_extend:DI
10189 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10190 (match_operand:QI 2 "immediate_operand" ""))))
10191 (clobber (reg:CC FLAGS_REG))]
10192 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10193 [(set (match_dup 0)
10194 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10195 {
10196 operands[2]
10197 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10198 })
10199
10200 (define_split
10201 [(set (match_operand:DI 0 "register_operand" "")
10202 (zero_extend:DI
10203 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10204 (match_operand:QI 2 "immediate_operand" ""))))
10205 (clobber (reg:CC FLAGS_REG))]
10206 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10207 [(set (match_dup 0)
10208 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10209
10210 (define_insn "*<rotate_insn><mode>3_1"
10211 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10212 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10213 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10214 (clobber (reg:CC FLAGS_REG))]
10215 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10216 {
10217 if (operands[2] == const1_rtx
10218 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10219 return "<rotate>{<imodesuffix>}\t%0";
10220 else
10221 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10222 }
10223 [(set_attr "type" "rotate")
10224 (set (attr "length_immediate")
10225 (if_then_else
10226 (and (match_operand 2 "const1_operand" "")
10227 (ior (match_test "TARGET_SHIFT1")
10228 (match_test "optimize_function_for_size_p (cfun)")))
10229 (const_string "0")
10230 (const_string "*")))
10231 (set_attr "mode" "<MODE>")])
10232
10233 (define_insn "*<rotate_insn>qi3_1_slp"
10234 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10235 (any_rotate:QI (match_dup 0)
10236 (match_operand:QI 1 "nonmemory_operand" "cI")))
10237 (clobber (reg:CC FLAGS_REG))]
10238 "(optimize_function_for_size_p (cfun)
10239 || !TARGET_PARTIAL_REG_STALL
10240 || (operands[1] == const1_rtx
10241 && TARGET_SHIFT1))"
10242 {
10243 if (operands[1] == const1_rtx
10244 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10245 return "<rotate>{b}\t%0";
10246 else
10247 return "<rotate>{b}\t{%1, %0|%0, %1}";
10248 }
10249 [(set_attr "type" "rotate1")
10250 (set (attr "length_immediate")
10251 (if_then_else
10252 (and (match_operand 1 "const1_operand" "")
10253 (ior (match_test "TARGET_SHIFT1")
10254 (match_test "optimize_function_for_size_p (cfun)")))
10255 (const_string "0")
10256 (const_string "*")))
10257 (set_attr "mode" "QI")])
10258
10259 (define_split
10260 [(set (match_operand:HI 0 "register_operand" "")
10261 (any_rotate:HI (match_dup 0) (const_int 8)))
10262 (clobber (reg:CC FLAGS_REG))]
10263 "reload_completed
10264 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10265 [(parallel [(set (strict_low_part (match_dup 0))
10266 (bswap:HI (match_dup 0)))
10267 (clobber (reg:CC FLAGS_REG))])])
10268 \f
10269 ;; Bit set / bit test instructions
10270
10271 (define_expand "extv"
10272 [(set (match_operand:SI 0 "register_operand" "")
10273 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10274 (match_operand:SI 2 "const8_operand" "")
10275 (match_operand:SI 3 "const8_operand" "")))]
10276 ""
10277 {
10278 /* Handle extractions from %ah et al. */
10279 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10280 FAIL;
10281
10282 /* From mips.md: extract_bit_field doesn't verify that our source
10283 matches the predicate, so check it again here. */
10284 if (! ext_register_operand (operands[1], VOIDmode))
10285 FAIL;
10286 })
10287
10288 (define_expand "extzv"
10289 [(set (match_operand:SI 0 "register_operand" "")
10290 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10291 (match_operand:SI 2 "const8_operand" "")
10292 (match_operand:SI 3 "const8_operand" "")))]
10293 ""
10294 {
10295 /* Handle extractions from %ah et al. */
10296 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10297 FAIL;
10298
10299 /* From mips.md: extract_bit_field doesn't verify that our source
10300 matches the predicate, so check it again here. */
10301 if (! ext_register_operand (operands[1], VOIDmode))
10302 FAIL;
10303 })
10304
10305 (define_expand "insv"
10306 [(set (zero_extract (match_operand 0 "register_operand" "")
10307 (match_operand 1 "const_int_operand" "")
10308 (match_operand 2 "const_int_operand" ""))
10309 (match_operand 3 "register_operand" ""))]
10310 ""
10311 {
10312 rtx (*gen_mov_insv_1) (rtx, rtx);
10313
10314 if (ix86_expand_pinsr (operands))
10315 DONE;
10316
10317 /* Handle insertions to %ah et al. */
10318 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10319 FAIL;
10320
10321 /* From mips.md: insert_bit_field doesn't verify that our source
10322 matches the predicate, so check it again here. */
10323 if (! ext_register_operand (operands[0], VOIDmode))
10324 FAIL;
10325
10326 gen_mov_insv_1 = (TARGET_64BIT
10327 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10328
10329 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10330 DONE;
10331 })
10332
10333 ;; %%% bts, btr, btc, bt.
10334 ;; In general these instructions are *slow* when applied to memory,
10335 ;; since they enforce atomic operation. When applied to registers,
10336 ;; it depends on the cpu implementation. They're never faster than
10337 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10338 ;; no point. But in 64-bit, we can't hold the relevant immediates
10339 ;; within the instruction itself, so operating on bits in the high
10340 ;; 32-bits of a register becomes easier.
10341 ;;
10342 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10343 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10344 ;; negdf respectively, so they can never be disabled entirely.
10345
10346 (define_insn "*btsq"
10347 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10348 (const_int 1)
10349 (match_operand:DI 1 "const_0_to_63_operand" ""))
10350 (const_int 1))
10351 (clobber (reg:CC FLAGS_REG))]
10352 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10353 "bts{q}\t{%1, %0|%0, %1}"
10354 [(set_attr "type" "alu1")
10355 (set_attr "prefix_0f" "1")
10356 (set_attr "mode" "DI")])
10357
10358 (define_insn "*btrq"
10359 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10360 (const_int 1)
10361 (match_operand:DI 1 "const_0_to_63_operand" ""))
10362 (const_int 0))
10363 (clobber (reg:CC FLAGS_REG))]
10364 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10365 "btr{q}\t{%1, %0|%0, %1}"
10366 [(set_attr "type" "alu1")
10367 (set_attr "prefix_0f" "1")
10368 (set_attr "mode" "DI")])
10369
10370 (define_insn "*btcq"
10371 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10372 (const_int 1)
10373 (match_operand:DI 1 "const_0_to_63_operand" ""))
10374 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10375 (clobber (reg:CC FLAGS_REG))]
10376 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10377 "btc{q}\t{%1, %0|%0, %1}"
10378 [(set_attr "type" "alu1")
10379 (set_attr "prefix_0f" "1")
10380 (set_attr "mode" "DI")])
10381
10382 ;; Allow Nocona to avoid these instructions if a register is available.
10383
10384 (define_peephole2
10385 [(match_scratch:DI 2 "r")
10386 (parallel [(set (zero_extract:DI
10387 (match_operand:DI 0 "register_operand" "")
10388 (const_int 1)
10389 (match_operand:DI 1 "const_0_to_63_operand" ""))
10390 (const_int 1))
10391 (clobber (reg:CC FLAGS_REG))])]
10392 "TARGET_64BIT && !TARGET_USE_BT"
10393 [(const_int 0)]
10394 {
10395 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10396 rtx op1;
10397
10398 if (HOST_BITS_PER_WIDE_INT >= 64)
10399 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10400 else if (i < HOST_BITS_PER_WIDE_INT)
10401 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10402 else
10403 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10404
10405 op1 = immed_double_const (lo, hi, DImode);
10406 if (i >= 31)
10407 {
10408 emit_move_insn (operands[2], op1);
10409 op1 = operands[2];
10410 }
10411
10412 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10413 DONE;
10414 })
10415
10416 (define_peephole2
10417 [(match_scratch:DI 2 "r")
10418 (parallel [(set (zero_extract:DI
10419 (match_operand:DI 0 "register_operand" "")
10420 (const_int 1)
10421 (match_operand:DI 1 "const_0_to_63_operand" ""))
10422 (const_int 0))
10423 (clobber (reg:CC FLAGS_REG))])]
10424 "TARGET_64BIT && !TARGET_USE_BT"
10425 [(const_int 0)]
10426 {
10427 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10428 rtx op1;
10429
10430 if (HOST_BITS_PER_WIDE_INT >= 64)
10431 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10432 else if (i < HOST_BITS_PER_WIDE_INT)
10433 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10434 else
10435 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10436
10437 op1 = immed_double_const (~lo, ~hi, DImode);
10438 if (i >= 32)
10439 {
10440 emit_move_insn (operands[2], op1);
10441 op1 = operands[2];
10442 }
10443
10444 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10445 DONE;
10446 })
10447
10448 (define_peephole2
10449 [(match_scratch:DI 2 "r")
10450 (parallel [(set (zero_extract:DI
10451 (match_operand:DI 0 "register_operand" "")
10452 (const_int 1)
10453 (match_operand:DI 1 "const_0_to_63_operand" ""))
10454 (not:DI (zero_extract:DI
10455 (match_dup 0) (const_int 1) (match_dup 1))))
10456 (clobber (reg:CC FLAGS_REG))])]
10457 "TARGET_64BIT && !TARGET_USE_BT"
10458 [(const_int 0)]
10459 {
10460 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10461 rtx op1;
10462
10463 if (HOST_BITS_PER_WIDE_INT >= 64)
10464 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10465 else if (i < HOST_BITS_PER_WIDE_INT)
10466 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10467 else
10468 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10469
10470 op1 = immed_double_const (lo, hi, DImode);
10471 if (i >= 31)
10472 {
10473 emit_move_insn (operands[2], op1);
10474 op1 = operands[2];
10475 }
10476
10477 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10478 DONE;
10479 })
10480
10481 (define_insn "*bt<mode>"
10482 [(set (reg:CCC FLAGS_REG)
10483 (compare:CCC
10484 (zero_extract:SWI48
10485 (match_operand:SWI48 0 "register_operand" "r")
10486 (const_int 1)
10487 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10488 (const_int 0)))]
10489 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10490 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10491 [(set_attr "type" "alu1")
10492 (set_attr "prefix_0f" "1")
10493 (set_attr "mode" "<MODE>")])
10494 \f
10495 ;; Store-flag instructions.
10496
10497 ;; For all sCOND expanders, also expand the compare or test insn that
10498 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10499
10500 (define_insn_and_split "*setcc_di_1"
10501 [(set (match_operand:DI 0 "register_operand" "=q")
10502 (match_operator:DI 1 "ix86_comparison_operator"
10503 [(reg FLAGS_REG) (const_int 0)]))]
10504 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10505 "#"
10506 "&& reload_completed"
10507 [(set (match_dup 2) (match_dup 1))
10508 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10509 {
10510 PUT_MODE (operands[1], QImode);
10511 operands[2] = gen_lowpart (QImode, operands[0]);
10512 })
10513
10514 (define_insn_and_split "*setcc_si_1_and"
10515 [(set (match_operand:SI 0 "register_operand" "=q")
10516 (match_operator:SI 1 "ix86_comparison_operator"
10517 [(reg FLAGS_REG) (const_int 0)]))
10518 (clobber (reg:CC FLAGS_REG))]
10519 "!TARGET_PARTIAL_REG_STALL
10520 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10521 "#"
10522 "&& reload_completed"
10523 [(set (match_dup 2) (match_dup 1))
10524 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10525 (clobber (reg:CC FLAGS_REG))])]
10526 {
10527 PUT_MODE (operands[1], QImode);
10528 operands[2] = gen_lowpart (QImode, operands[0]);
10529 })
10530
10531 (define_insn_and_split "*setcc_si_1_movzbl"
10532 [(set (match_operand:SI 0 "register_operand" "=q")
10533 (match_operator:SI 1 "ix86_comparison_operator"
10534 [(reg FLAGS_REG) (const_int 0)]))]
10535 "!TARGET_PARTIAL_REG_STALL
10536 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10537 "#"
10538 "&& reload_completed"
10539 [(set (match_dup 2) (match_dup 1))
10540 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10541 {
10542 PUT_MODE (operands[1], QImode);
10543 operands[2] = gen_lowpart (QImode, operands[0]);
10544 })
10545
10546 (define_insn "*setcc_qi"
10547 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10548 (match_operator:QI 1 "ix86_comparison_operator"
10549 [(reg FLAGS_REG) (const_int 0)]))]
10550 ""
10551 "set%C1\t%0"
10552 [(set_attr "type" "setcc")
10553 (set_attr "mode" "QI")])
10554
10555 (define_insn "*setcc_qi_slp"
10556 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10557 (match_operator:QI 1 "ix86_comparison_operator"
10558 [(reg FLAGS_REG) (const_int 0)]))]
10559 ""
10560 "set%C1\t%0"
10561 [(set_attr "type" "setcc")
10562 (set_attr "mode" "QI")])
10563
10564 ;; In general it is not safe to assume too much about CCmode registers,
10565 ;; so simplify-rtx stops when it sees a second one. Under certain
10566 ;; conditions this is safe on x86, so help combine not create
10567 ;;
10568 ;; seta %al
10569 ;; testb %al, %al
10570 ;; sete %al
10571
10572 (define_split
10573 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10574 (ne:QI (match_operator 1 "ix86_comparison_operator"
10575 [(reg FLAGS_REG) (const_int 0)])
10576 (const_int 0)))]
10577 ""
10578 [(set (match_dup 0) (match_dup 1))]
10579 "PUT_MODE (operands[1], QImode);")
10580
10581 (define_split
10582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10583 (ne:QI (match_operator 1 "ix86_comparison_operator"
10584 [(reg FLAGS_REG) (const_int 0)])
10585 (const_int 0)))]
10586 ""
10587 [(set (match_dup 0) (match_dup 1))]
10588 "PUT_MODE (operands[1], QImode);")
10589
10590 (define_split
10591 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10592 (eq:QI (match_operator 1 "ix86_comparison_operator"
10593 [(reg FLAGS_REG) (const_int 0)])
10594 (const_int 0)))]
10595 ""
10596 [(set (match_dup 0) (match_dup 1))]
10597 {
10598 rtx new_op1 = copy_rtx (operands[1]);
10599 operands[1] = new_op1;
10600 PUT_MODE (new_op1, QImode);
10601 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10602 GET_MODE (XEXP (new_op1, 0))));
10603
10604 /* Make sure that (a) the CCmode we have for the flags is strong
10605 enough for the reversed compare or (b) we have a valid FP compare. */
10606 if (! ix86_comparison_operator (new_op1, VOIDmode))
10607 FAIL;
10608 })
10609
10610 (define_split
10611 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10612 (eq:QI (match_operator 1 "ix86_comparison_operator"
10613 [(reg FLAGS_REG) (const_int 0)])
10614 (const_int 0)))]
10615 ""
10616 [(set (match_dup 0) (match_dup 1))]
10617 {
10618 rtx new_op1 = copy_rtx (operands[1]);
10619 operands[1] = new_op1;
10620 PUT_MODE (new_op1, QImode);
10621 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10622 GET_MODE (XEXP (new_op1, 0))));
10623
10624 /* Make sure that (a) the CCmode we have for the flags is strong
10625 enough for the reversed compare or (b) we have a valid FP compare. */
10626 if (! ix86_comparison_operator (new_op1, VOIDmode))
10627 FAIL;
10628 })
10629
10630 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10631 ;; subsequent logical operations are used to imitate conditional moves.
10632 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10633 ;; it directly.
10634
10635 (define_insn "setcc_<mode>_sse"
10636 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10637 (match_operator:MODEF 3 "sse_comparison_operator"
10638 [(match_operand:MODEF 1 "register_operand" "0,x")
10639 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10640 "SSE_FLOAT_MODE_P (<MODE>mode)"
10641 "@
10642 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10643 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10644 [(set_attr "isa" "noavx,avx")
10645 (set_attr "type" "ssecmp")
10646 (set_attr "length_immediate" "1")
10647 (set_attr "prefix" "orig,vex")
10648 (set_attr "mode" "<MODE>")])
10649 \f
10650 ;; Basic conditional jump instructions.
10651 ;; We ignore the overflow flag for signed branch instructions.
10652
10653 (define_insn "*jcc_1"
10654 [(set (pc)
10655 (if_then_else (match_operator 1 "ix86_comparison_operator"
10656 [(reg FLAGS_REG) (const_int 0)])
10657 (label_ref (match_operand 0 "" ""))
10658 (pc)))]
10659 ""
10660 "%+j%C1\t%l0"
10661 [(set_attr "type" "ibr")
10662 (set_attr "modrm" "0")
10663 (set (attr "length")
10664 (if_then_else (and (ge (minus (match_dup 0) (pc))
10665 (const_int -126))
10666 (lt (minus (match_dup 0) (pc))
10667 (const_int 128)))
10668 (const_int 2)
10669 (const_int 6)))])
10670
10671 (define_insn "*jcc_2"
10672 [(set (pc)
10673 (if_then_else (match_operator 1 "ix86_comparison_operator"
10674 [(reg FLAGS_REG) (const_int 0)])
10675 (pc)
10676 (label_ref (match_operand 0 "" ""))))]
10677 ""
10678 "%+j%c1\t%l0"
10679 [(set_attr "type" "ibr")
10680 (set_attr "modrm" "0")
10681 (set (attr "length")
10682 (if_then_else (and (ge (minus (match_dup 0) (pc))
10683 (const_int -126))
10684 (lt (minus (match_dup 0) (pc))
10685 (const_int 128)))
10686 (const_int 2)
10687 (const_int 6)))])
10688
10689 ;; In general it is not safe to assume too much about CCmode registers,
10690 ;; so simplify-rtx stops when it sees a second one. Under certain
10691 ;; conditions this is safe on x86, so help combine not create
10692 ;;
10693 ;; seta %al
10694 ;; testb %al, %al
10695 ;; je Lfoo
10696
10697 (define_split
10698 [(set (pc)
10699 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10700 [(reg FLAGS_REG) (const_int 0)])
10701 (const_int 0))
10702 (label_ref (match_operand 1 "" ""))
10703 (pc)))]
10704 ""
10705 [(set (pc)
10706 (if_then_else (match_dup 0)
10707 (label_ref (match_dup 1))
10708 (pc)))]
10709 "PUT_MODE (operands[0], VOIDmode);")
10710
10711 (define_split
10712 [(set (pc)
10713 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10714 [(reg FLAGS_REG) (const_int 0)])
10715 (const_int 0))
10716 (label_ref (match_operand 1 "" ""))
10717 (pc)))]
10718 ""
10719 [(set (pc)
10720 (if_then_else (match_dup 0)
10721 (label_ref (match_dup 1))
10722 (pc)))]
10723 {
10724 rtx new_op0 = copy_rtx (operands[0]);
10725 operands[0] = new_op0;
10726 PUT_MODE (new_op0, VOIDmode);
10727 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10728 GET_MODE (XEXP (new_op0, 0))));
10729
10730 /* Make sure that (a) the CCmode we have for the flags is strong
10731 enough for the reversed compare or (b) we have a valid FP compare. */
10732 if (! ix86_comparison_operator (new_op0, VOIDmode))
10733 FAIL;
10734 })
10735
10736 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10737 ;; pass generates from shift insn with QImode operand. Actually, the mode
10738 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10739 ;; appropriate modulo of the bit offset value.
10740
10741 (define_insn_and_split "*jcc_bt<mode>"
10742 [(set (pc)
10743 (if_then_else (match_operator 0 "bt_comparison_operator"
10744 [(zero_extract:SWI48
10745 (match_operand:SWI48 1 "register_operand" "r")
10746 (const_int 1)
10747 (zero_extend:SI
10748 (match_operand:QI 2 "register_operand" "r")))
10749 (const_int 0)])
10750 (label_ref (match_operand 3 "" ""))
10751 (pc)))
10752 (clobber (reg:CC FLAGS_REG))]
10753 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10754 "#"
10755 "&& 1"
10756 [(set (reg:CCC FLAGS_REG)
10757 (compare:CCC
10758 (zero_extract:SWI48
10759 (match_dup 1)
10760 (const_int 1)
10761 (match_dup 2))
10762 (const_int 0)))
10763 (set (pc)
10764 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10765 (label_ref (match_dup 3))
10766 (pc)))]
10767 {
10768 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10769
10770 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10771 })
10772
10773 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10774 ;; also for DImode, this is what combine produces.
10775 (define_insn_and_split "*jcc_bt<mode>_mask"
10776 [(set (pc)
10777 (if_then_else (match_operator 0 "bt_comparison_operator"
10778 [(zero_extract:SWI48
10779 (match_operand:SWI48 1 "register_operand" "r")
10780 (const_int 1)
10781 (and:SI
10782 (match_operand:SI 2 "register_operand" "r")
10783 (match_operand:SI 3 "const_int_operand" "n")))])
10784 (label_ref (match_operand 4 "" ""))
10785 (pc)))
10786 (clobber (reg:CC FLAGS_REG))]
10787 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10788 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10789 == GET_MODE_BITSIZE (<MODE>mode)-1"
10790 "#"
10791 "&& 1"
10792 [(set (reg:CCC FLAGS_REG)
10793 (compare:CCC
10794 (zero_extract:SWI48
10795 (match_dup 1)
10796 (const_int 1)
10797 (match_dup 2))
10798 (const_int 0)))
10799 (set (pc)
10800 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10801 (label_ref (match_dup 4))
10802 (pc)))]
10803 {
10804 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10805
10806 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10807 })
10808
10809 (define_insn_and_split "*jcc_btsi_1"
10810 [(set (pc)
10811 (if_then_else (match_operator 0 "bt_comparison_operator"
10812 [(and:SI
10813 (lshiftrt:SI
10814 (match_operand:SI 1 "register_operand" "r")
10815 (match_operand:QI 2 "register_operand" "r"))
10816 (const_int 1))
10817 (const_int 0)])
10818 (label_ref (match_operand 3 "" ""))
10819 (pc)))
10820 (clobber (reg:CC FLAGS_REG))]
10821 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10822 "#"
10823 "&& 1"
10824 [(set (reg:CCC FLAGS_REG)
10825 (compare:CCC
10826 (zero_extract:SI
10827 (match_dup 1)
10828 (const_int 1)
10829 (match_dup 2))
10830 (const_int 0)))
10831 (set (pc)
10832 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10833 (label_ref (match_dup 3))
10834 (pc)))]
10835 {
10836 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10837
10838 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10839 })
10840
10841 ;; avoid useless masking of bit offset operand
10842 (define_insn_and_split "*jcc_btsi_mask_1"
10843 [(set (pc)
10844 (if_then_else
10845 (match_operator 0 "bt_comparison_operator"
10846 [(and:SI
10847 (lshiftrt:SI
10848 (match_operand:SI 1 "register_operand" "r")
10849 (subreg:QI
10850 (and:SI
10851 (match_operand:SI 2 "register_operand" "r")
10852 (match_operand:SI 3 "const_int_operand" "n")) 0))
10853 (const_int 1))
10854 (const_int 0)])
10855 (label_ref (match_operand 4 "" ""))
10856 (pc)))
10857 (clobber (reg:CC FLAGS_REG))]
10858 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10859 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10860 "#"
10861 "&& 1"
10862 [(set (reg:CCC FLAGS_REG)
10863 (compare:CCC
10864 (zero_extract:SI
10865 (match_dup 1)
10866 (const_int 1)
10867 (match_dup 2))
10868 (const_int 0)))
10869 (set (pc)
10870 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10871 (label_ref (match_dup 4))
10872 (pc)))]
10873 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10874
10875 ;; Define combination compare-and-branch fp compare instructions to help
10876 ;; combine.
10877
10878 (define_insn "*fp_jcc_1_387"
10879 [(set (pc)
10880 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10881 [(match_operand 1 "register_operand" "f")
10882 (match_operand 2 "nonimmediate_operand" "fm")])
10883 (label_ref (match_operand 3 "" ""))
10884 (pc)))
10885 (clobber (reg:CCFP FPSR_REG))
10886 (clobber (reg:CCFP FLAGS_REG))
10887 (clobber (match_scratch:HI 4 "=a"))]
10888 "TARGET_80387
10889 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10890 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10891 && SELECT_CC_MODE (GET_CODE (operands[0]),
10892 operands[1], operands[2]) == CCFPmode
10893 && !TARGET_CMOVE"
10894 "#")
10895
10896 (define_insn "*fp_jcc_1r_387"
10897 [(set (pc)
10898 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10899 [(match_operand 1 "register_operand" "f")
10900 (match_operand 2 "nonimmediate_operand" "fm")])
10901 (pc)
10902 (label_ref (match_operand 3 "" ""))))
10903 (clobber (reg:CCFP FPSR_REG))
10904 (clobber (reg:CCFP FLAGS_REG))
10905 (clobber (match_scratch:HI 4 "=a"))]
10906 "TARGET_80387
10907 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10908 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10909 && SELECT_CC_MODE (GET_CODE (operands[0]),
10910 operands[1], operands[2]) == CCFPmode
10911 && !TARGET_CMOVE"
10912 "#")
10913
10914 (define_insn "*fp_jcc_2_387"
10915 [(set (pc)
10916 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10917 [(match_operand 1 "register_operand" "f")
10918 (match_operand 2 "register_operand" "f")])
10919 (label_ref (match_operand 3 "" ""))
10920 (pc)))
10921 (clobber (reg:CCFP FPSR_REG))
10922 (clobber (reg:CCFP FLAGS_REG))
10923 (clobber (match_scratch:HI 4 "=a"))]
10924 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10925 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10926 && !TARGET_CMOVE"
10927 "#")
10928
10929 (define_insn "*fp_jcc_2r_387"
10930 [(set (pc)
10931 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10932 [(match_operand 1 "register_operand" "f")
10933 (match_operand 2 "register_operand" "f")])
10934 (pc)
10935 (label_ref (match_operand 3 "" ""))))
10936 (clobber (reg:CCFP FPSR_REG))
10937 (clobber (reg:CCFP FLAGS_REG))
10938 (clobber (match_scratch:HI 4 "=a"))]
10939 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10940 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10941 && !TARGET_CMOVE"
10942 "#")
10943
10944 (define_insn "*fp_jcc_3_387"
10945 [(set (pc)
10946 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10947 [(match_operand 1 "register_operand" "f")
10948 (match_operand 2 "const0_operand" "")])
10949 (label_ref (match_operand 3 "" ""))
10950 (pc)))
10951 (clobber (reg:CCFP FPSR_REG))
10952 (clobber (reg:CCFP FLAGS_REG))
10953 (clobber (match_scratch:HI 4 "=a"))]
10954 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10955 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10956 && SELECT_CC_MODE (GET_CODE (operands[0]),
10957 operands[1], operands[2]) == CCFPmode
10958 && !TARGET_CMOVE"
10959 "#")
10960
10961 (define_split
10962 [(set (pc)
10963 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10964 [(match_operand 1 "register_operand" "")
10965 (match_operand 2 "nonimmediate_operand" "")])
10966 (match_operand 3 "" "")
10967 (match_operand 4 "" "")))
10968 (clobber (reg:CCFP FPSR_REG))
10969 (clobber (reg:CCFP FLAGS_REG))]
10970 "reload_completed"
10971 [(const_int 0)]
10972 {
10973 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10974 operands[3], operands[4], NULL_RTX, NULL_RTX);
10975 DONE;
10976 })
10977
10978 (define_split
10979 [(set (pc)
10980 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10981 [(match_operand 1 "register_operand" "")
10982 (match_operand 2 "general_operand" "")])
10983 (match_operand 3 "" "")
10984 (match_operand 4 "" "")))
10985 (clobber (reg:CCFP FPSR_REG))
10986 (clobber (reg:CCFP FLAGS_REG))
10987 (clobber (match_scratch:HI 5 "=a"))]
10988 "reload_completed"
10989 [(const_int 0)]
10990 {
10991 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10992 operands[3], operands[4], operands[5], NULL_RTX);
10993 DONE;
10994 })
10995
10996 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10997 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10998 ;; with a precedence over other operators and is always put in the first
10999 ;; place. Swap condition and operands to match ficom instruction.
11000
11001 (define_insn "*fp_jcc_4_<mode>_387"
11002 [(set (pc)
11003 (if_then_else
11004 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11005 [(match_operator 1 "float_operator"
11006 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11007 (match_operand 3 "register_operand" "f,f")])
11008 (label_ref (match_operand 4 "" ""))
11009 (pc)))
11010 (clobber (reg:CCFP FPSR_REG))
11011 (clobber (reg:CCFP FLAGS_REG))
11012 (clobber (match_scratch:HI 5 "=a,a"))]
11013 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11014 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11015 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11016 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11017 && !TARGET_CMOVE"
11018 "#")
11019
11020 (define_split
11021 [(set (pc)
11022 (if_then_else
11023 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11024 [(match_operator 1 "float_operator"
11025 [(match_operand:SWI24 2 "memory_operand" "")])
11026 (match_operand 3 "register_operand" "")])
11027 (match_operand 4 "" "")
11028 (match_operand 5 "" "")))
11029 (clobber (reg:CCFP FPSR_REG))
11030 (clobber (reg:CCFP FLAGS_REG))
11031 (clobber (match_scratch:HI 6 "=a"))]
11032 "reload_completed"
11033 [(const_int 0)]
11034 {
11035 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11036
11037 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11038 operands[3], operands[7],
11039 operands[4], operands[5], operands[6], NULL_RTX);
11040 DONE;
11041 })
11042
11043 ;; %%% Kill this when reload knows how to do it.
11044 (define_split
11045 [(set (pc)
11046 (if_then_else
11047 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11048 [(match_operator 1 "float_operator"
11049 [(match_operand:SWI24 2 "register_operand" "")])
11050 (match_operand 3 "register_operand" "")])
11051 (match_operand 4 "" "")
11052 (match_operand 5 "" "")))
11053 (clobber (reg:CCFP FPSR_REG))
11054 (clobber (reg:CCFP FLAGS_REG))
11055 (clobber (match_scratch:HI 6 "=a"))]
11056 "reload_completed"
11057 [(const_int 0)]
11058 {
11059 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11060 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11061
11062 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11063 operands[3], operands[7],
11064 operands[4], operands[5], operands[6], operands[2]);
11065 DONE;
11066 })
11067 \f
11068 ;; Unconditional and other jump instructions
11069
11070 (define_insn "jump"
11071 [(set (pc)
11072 (label_ref (match_operand 0 "" "")))]
11073 ""
11074 "jmp\t%l0"
11075 [(set_attr "type" "ibr")
11076 (set (attr "length")
11077 (if_then_else (and (ge (minus (match_dup 0) (pc))
11078 (const_int -126))
11079 (lt (minus (match_dup 0) (pc))
11080 (const_int 128)))
11081 (const_int 2)
11082 (const_int 5)))
11083 (set_attr "modrm" "0")])
11084
11085 (define_expand "indirect_jump"
11086 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11087
11088 (define_insn "*indirect_jump"
11089 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11090 ""
11091 "jmp\t%A0"
11092 [(set_attr "type" "ibr")
11093 (set_attr "length_immediate" "0")])
11094
11095 (define_expand "tablejump"
11096 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11097 (use (label_ref (match_operand 1 "" "")))])]
11098 ""
11099 {
11100 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11101 relative. Convert the relative address to an absolute address. */
11102 if (flag_pic)
11103 {
11104 rtx op0, op1;
11105 enum rtx_code code;
11106
11107 /* We can't use @GOTOFF for text labels on VxWorks;
11108 see gotoff_operand. */
11109 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11110 {
11111 code = PLUS;
11112 op0 = operands[0];
11113 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11114 }
11115 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11116 {
11117 code = PLUS;
11118 op0 = operands[0];
11119 op1 = pic_offset_table_rtx;
11120 }
11121 else
11122 {
11123 code = MINUS;
11124 op0 = pic_offset_table_rtx;
11125 op1 = operands[0];
11126 }
11127
11128 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11129 OPTAB_DIRECT);
11130 }
11131 else if (TARGET_X32)
11132 operands[0] = convert_memory_address (Pmode, operands[0]);
11133 })
11134
11135 (define_insn "*tablejump_1"
11136 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11137 (use (label_ref (match_operand 1 "" "")))]
11138 ""
11139 "jmp\t%A0"
11140 [(set_attr "type" "ibr")
11141 (set_attr "length_immediate" "0")])
11142 \f
11143 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11144
11145 (define_peephole2
11146 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11147 (set (match_operand:QI 1 "register_operand" "")
11148 (match_operator:QI 2 "ix86_comparison_operator"
11149 [(reg FLAGS_REG) (const_int 0)]))
11150 (set (match_operand 3 "q_regs_operand" "")
11151 (zero_extend (match_dup 1)))]
11152 "(peep2_reg_dead_p (3, operands[1])
11153 || operands_match_p (operands[1], operands[3]))
11154 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11155 [(set (match_dup 4) (match_dup 0))
11156 (set (strict_low_part (match_dup 5))
11157 (match_dup 2))]
11158 {
11159 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11160 operands[5] = gen_lowpart (QImode, operands[3]);
11161 ix86_expand_clear (operands[3]);
11162 })
11163
11164 ;; Similar, but match zero extend with andsi3.
11165
11166 (define_peephole2
11167 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11168 (set (match_operand:QI 1 "register_operand" "")
11169 (match_operator:QI 2 "ix86_comparison_operator"
11170 [(reg FLAGS_REG) (const_int 0)]))
11171 (parallel [(set (match_operand:SI 3 "q_regs_operand" "")
11172 (and:SI (match_dup 3) (const_int 255)))
11173 (clobber (reg:CC FLAGS_REG))])]
11174 "REGNO (operands[1]) == REGNO (operands[3])
11175 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11176 [(set (match_dup 4) (match_dup 0))
11177 (set (strict_low_part (match_dup 5))
11178 (match_dup 2))]
11179 {
11180 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11181 operands[5] = gen_lowpart (QImode, operands[3]);
11182 ix86_expand_clear (operands[3]);
11183 })
11184 \f
11185 ;; Call instructions.
11186
11187 ;; The predicates normally associated with named expanders are not properly
11188 ;; checked for calls. This is a bug in the generic code, but it isn't that
11189 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11190
11191 ;; P6 processors will jump to the address after the decrement when %esp
11192 ;; is used as a call operand, so they will execute return address as a code.
11193 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11194
11195 ;; Register constraint for call instruction.
11196 (define_mode_attr c [(SI "l") (DI "r")])
11197
11198 ;; Call subroutine returning no value.
11199
11200 (define_expand "call"
11201 [(call (match_operand:QI 0 "" "")
11202 (match_operand 1 "" ""))
11203 (use (match_operand 2 "" ""))]
11204 ""
11205 {
11206 ix86_expand_call (NULL, operands[0], operands[1],
11207 operands[2], NULL, false);
11208 DONE;
11209 })
11210
11211 (define_expand "sibcall"
11212 [(call (match_operand:QI 0 "" "")
11213 (match_operand 1 "" ""))
11214 (use (match_operand 2 "" ""))]
11215 ""
11216 {
11217 ix86_expand_call (NULL, operands[0], operands[1],
11218 operands[2], NULL, true);
11219 DONE;
11220 })
11221
11222 (define_insn_and_split "*call_vzeroupper"
11223 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11224 (match_operand 1 "" ""))
11225 (unspec [(match_operand 2 "const_int_operand" "")]
11226 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11227 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11228 "#"
11229 "&& reload_completed"
11230 [(const_int 0)]
11231 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11232 [(set_attr "type" "call")])
11233
11234 (define_insn "*call"
11235 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11236 (match_operand 1 "" ""))]
11237 "!SIBLING_CALL_P (insn)"
11238 "* return ix86_output_call_insn (insn, operands[0]);"
11239 [(set_attr "type" "call")])
11240
11241 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11242 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11243 (match_operand 1 "" ""))
11244 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11245 (clobber (reg:TI XMM6_REG))
11246 (clobber (reg:TI XMM7_REG))
11247 (clobber (reg:TI XMM8_REG))
11248 (clobber (reg:TI XMM9_REG))
11249 (clobber (reg:TI XMM10_REG))
11250 (clobber (reg:TI XMM11_REG))
11251 (clobber (reg:TI XMM12_REG))
11252 (clobber (reg:TI XMM13_REG))
11253 (clobber (reg:TI XMM14_REG))
11254 (clobber (reg:TI XMM15_REG))
11255 (clobber (reg:DI SI_REG))
11256 (clobber (reg:DI DI_REG))
11257 (unspec [(match_operand 2 "const_int_operand" "")]
11258 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11259 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11260 "#"
11261 "&& reload_completed"
11262 [(const_int 0)]
11263 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11264 [(set_attr "type" "call")])
11265
11266 (define_insn "*call_rex64_ms_sysv"
11267 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11268 (match_operand 1 "" ""))
11269 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11270 (clobber (reg:TI XMM6_REG))
11271 (clobber (reg:TI XMM7_REG))
11272 (clobber (reg:TI XMM8_REG))
11273 (clobber (reg:TI XMM9_REG))
11274 (clobber (reg:TI XMM10_REG))
11275 (clobber (reg:TI XMM11_REG))
11276 (clobber (reg:TI XMM12_REG))
11277 (clobber (reg:TI XMM13_REG))
11278 (clobber (reg:TI XMM14_REG))
11279 (clobber (reg:TI XMM15_REG))
11280 (clobber (reg:DI SI_REG))
11281 (clobber (reg:DI DI_REG))]
11282 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11283 "* return ix86_output_call_insn (insn, operands[0]);"
11284 [(set_attr "type" "call")])
11285
11286 (define_insn_and_split "*sibcall_vzeroupper"
11287 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11288 (match_operand 1 "" ""))
11289 (unspec [(match_operand 2 "const_int_operand" "")]
11290 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11291 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11292 "#"
11293 "&& reload_completed"
11294 [(const_int 0)]
11295 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11296 [(set_attr "type" "call")])
11297
11298 (define_insn "*sibcall"
11299 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11300 (match_operand 1 "" ""))]
11301 "SIBLING_CALL_P (insn)"
11302 "* return ix86_output_call_insn (insn, operands[0]);"
11303 [(set_attr "type" "call")])
11304
11305 (define_expand "call_pop"
11306 [(parallel [(call (match_operand:QI 0 "" "")
11307 (match_operand:SI 1 "" ""))
11308 (set (reg:SI SP_REG)
11309 (plus:SI (reg:SI SP_REG)
11310 (match_operand:SI 3 "" "")))])]
11311 "!TARGET_64BIT"
11312 {
11313 ix86_expand_call (NULL, operands[0], operands[1],
11314 operands[2], operands[3], false);
11315 DONE;
11316 })
11317
11318 (define_insn_and_split "*call_pop_vzeroupper"
11319 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11320 (match_operand:SI 1 "" ""))
11321 (set (reg:SI SP_REG)
11322 (plus:SI (reg:SI SP_REG)
11323 (match_operand:SI 2 "immediate_operand" "i")))
11324 (unspec [(match_operand 3 "const_int_operand" "")]
11325 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11326 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11327 "#"
11328 "&& reload_completed"
11329 [(const_int 0)]
11330 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11331 [(set_attr "type" "call")])
11332
11333 (define_insn "*call_pop"
11334 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11335 (match_operand 1 "" ""))
11336 (set (reg:SI SP_REG)
11337 (plus:SI (reg:SI SP_REG)
11338 (match_operand:SI 2 "immediate_operand" "i")))]
11339 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11340 "* return ix86_output_call_insn (insn, operands[0]);"
11341 [(set_attr "type" "call")])
11342
11343 (define_insn_and_split "*sibcall_pop_vzeroupper"
11344 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11345 (match_operand 1 "" ""))
11346 (set (reg:SI SP_REG)
11347 (plus:SI (reg:SI SP_REG)
11348 (match_operand:SI 2 "immediate_operand" "i")))
11349 (unspec [(match_operand 3 "const_int_operand" "")]
11350 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11351 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11352 "#"
11353 "&& reload_completed"
11354 [(const_int 0)]
11355 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11356 [(set_attr "type" "call")])
11357
11358 (define_insn "*sibcall_pop"
11359 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11360 (match_operand 1 "" ""))
11361 (set (reg:SI SP_REG)
11362 (plus:SI (reg:SI SP_REG)
11363 (match_operand:SI 2 "immediate_operand" "i")))]
11364 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11365 "* return ix86_output_call_insn (insn, operands[0]);"
11366 [(set_attr "type" "call")])
11367
11368 ;; Call subroutine, returning value in operand 0
11369
11370 (define_expand "call_value"
11371 [(set (match_operand 0 "" "")
11372 (call (match_operand:QI 1 "" "")
11373 (match_operand 2 "" "")))
11374 (use (match_operand 3 "" ""))]
11375 ""
11376 {
11377 ix86_expand_call (operands[0], operands[1], operands[2],
11378 operands[3], NULL, false);
11379 DONE;
11380 })
11381
11382 (define_expand "sibcall_value"
11383 [(set (match_operand 0 "" "")
11384 (call (match_operand:QI 1 "" "")
11385 (match_operand 2 "" "")))
11386 (use (match_operand 3 "" ""))]
11387 ""
11388 {
11389 ix86_expand_call (operands[0], operands[1], operands[2],
11390 operands[3], NULL, true);
11391 DONE;
11392 })
11393
11394 (define_insn_and_split "*call_value_vzeroupper"
11395 [(set (match_operand 0 "" "")
11396 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11397 (match_operand 2 "" "")))
11398 (unspec [(match_operand 3 "const_int_operand" "")]
11399 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11400 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11401 "#"
11402 "&& reload_completed"
11403 [(const_int 0)]
11404 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11405 [(set_attr "type" "callv")])
11406
11407 (define_insn "*call_value"
11408 [(set (match_operand 0 "" "")
11409 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11410 (match_operand 2 "" "")))]
11411 "!SIBLING_CALL_P (insn)"
11412 "* return ix86_output_call_insn (insn, operands[1]);"
11413 [(set_attr "type" "callv")])
11414
11415 (define_insn_and_split "*sibcall_value_vzeroupper"
11416 [(set (match_operand 0 "" "")
11417 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11418 (match_operand 2 "" "")))
11419 (unspec [(match_operand 3 "const_int_operand" "")]
11420 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11421 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11422 "#"
11423 "&& reload_completed"
11424 [(const_int 0)]
11425 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11426 [(set_attr "type" "callv")])
11427
11428 (define_insn "*sibcall_value"
11429 [(set (match_operand 0 "" "")
11430 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11431 (match_operand 2 "" "")))]
11432 "SIBLING_CALL_P (insn)"
11433 "* return ix86_output_call_insn (insn, operands[1]);"
11434 [(set_attr "type" "callv")])
11435
11436 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11437 [(set (match_operand 0 "" "")
11438 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11439 (match_operand 2 "" "")))
11440 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11441 (clobber (reg:TI XMM6_REG))
11442 (clobber (reg:TI XMM7_REG))
11443 (clobber (reg:TI XMM8_REG))
11444 (clobber (reg:TI XMM9_REG))
11445 (clobber (reg:TI XMM10_REG))
11446 (clobber (reg:TI XMM11_REG))
11447 (clobber (reg:TI XMM12_REG))
11448 (clobber (reg:TI XMM13_REG))
11449 (clobber (reg:TI XMM14_REG))
11450 (clobber (reg:TI XMM15_REG))
11451 (clobber (reg:DI SI_REG))
11452 (clobber (reg:DI DI_REG))
11453 (unspec [(match_operand 3 "const_int_operand" "")]
11454 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11455 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11456 "#"
11457 "&& reload_completed"
11458 [(const_int 0)]
11459 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11460 [(set_attr "type" "callv")])
11461
11462 (define_insn "*call_value_rex64_ms_sysv"
11463 [(set (match_operand 0 "" "")
11464 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11465 (match_operand 2 "" "")))
11466 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11467 (clobber (reg:TI XMM6_REG))
11468 (clobber (reg:TI XMM7_REG))
11469 (clobber (reg:TI XMM8_REG))
11470 (clobber (reg:TI XMM9_REG))
11471 (clobber (reg:TI XMM10_REG))
11472 (clobber (reg:TI XMM11_REG))
11473 (clobber (reg:TI XMM12_REG))
11474 (clobber (reg:TI XMM13_REG))
11475 (clobber (reg:TI XMM14_REG))
11476 (clobber (reg:TI XMM15_REG))
11477 (clobber (reg:DI SI_REG))
11478 (clobber (reg:DI DI_REG))]
11479 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11480 "* return ix86_output_call_insn (insn, operands[1]);"
11481 [(set_attr "type" "callv")])
11482
11483 (define_expand "call_value_pop"
11484 [(parallel [(set (match_operand 0 "" "")
11485 (call (match_operand:QI 1 "" "")
11486 (match_operand:SI 2 "" "")))
11487 (set (reg:SI SP_REG)
11488 (plus:SI (reg:SI SP_REG)
11489 (match_operand:SI 4 "" "")))])]
11490 "!TARGET_64BIT"
11491 {
11492 ix86_expand_call (operands[0], operands[1], operands[2],
11493 operands[3], operands[4], false);
11494 DONE;
11495 })
11496
11497 (define_insn_and_split "*call_value_pop_vzeroupper"
11498 [(set (match_operand 0 "" "")
11499 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11500 (match_operand 2 "" "")))
11501 (set (reg:SI SP_REG)
11502 (plus:SI (reg:SI SP_REG)
11503 (match_operand:SI 3 "immediate_operand" "i")))
11504 (unspec [(match_operand 4 "const_int_operand" "")]
11505 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11506 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11507 "#"
11508 "&& reload_completed"
11509 [(const_int 0)]
11510 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11511 [(set_attr "type" "callv")])
11512
11513 (define_insn "*call_value_pop"
11514 [(set (match_operand 0 "" "")
11515 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11516 (match_operand 2 "" "")))
11517 (set (reg:SI SP_REG)
11518 (plus:SI (reg:SI SP_REG)
11519 (match_operand:SI 3 "immediate_operand" "i")))]
11520 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11521 "* return ix86_output_call_insn (insn, operands[1]);"
11522 [(set_attr "type" "callv")])
11523
11524 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11525 [(set (match_operand 0 "" "")
11526 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11527 (match_operand 2 "" "")))
11528 (set (reg:SI SP_REG)
11529 (plus:SI (reg:SI SP_REG)
11530 (match_operand:SI 3 "immediate_operand" "i")))
11531 (unspec [(match_operand 4 "const_int_operand" "")]
11532 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11533 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11534 "#"
11535 "&& reload_completed"
11536 [(const_int 0)]
11537 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11538 [(set_attr "type" "callv")])
11539
11540 (define_insn "*sibcall_value_pop"
11541 [(set (match_operand 0 "" "")
11542 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11543 (match_operand 2 "" "")))
11544 (set (reg:SI SP_REG)
11545 (plus:SI (reg:SI SP_REG)
11546 (match_operand:SI 3 "immediate_operand" "i")))]
11547 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11548 "* return ix86_output_call_insn (insn, operands[1]);"
11549 [(set_attr "type" "callv")])
11550
11551 ;; Call subroutine returning any type.
11552
11553 (define_expand "untyped_call"
11554 [(parallel [(call (match_operand 0 "" "")
11555 (const_int 0))
11556 (match_operand 1 "" "")
11557 (match_operand 2 "" "")])]
11558 ""
11559 {
11560 int i;
11561
11562 /* In order to give reg-stack an easier job in validating two
11563 coprocessor registers as containing a possible return value,
11564 simply pretend the untyped call returns a complex long double
11565 value.
11566
11567 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11568 and should have the default ABI. */
11569
11570 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11571 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11572 operands[0], const0_rtx,
11573 GEN_INT ((TARGET_64BIT
11574 ? (ix86_abi == SYSV_ABI
11575 ? X86_64_SSE_REGPARM_MAX
11576 : X86_64_MS_SSE_REGPARM_MAX)
11577 : X86_32_SSE_REGPARM_MAX)
11578 - 1),
11579 NULL, false);
11580
11581 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11582 {
11583 rtx set = XVECEXP (operands[2], 0, i);
11584 emit_move_insn (SET_DEST (set), SET_SRC (set));
11585 }
11586
11587 /* The optimizer does not know that the call sets the function value
11588 registers we stored in the result block. We avoid problems by
11589 claiming that all hard registers are used and clobbered at this
11590 point. */
11591 emit_insn (gen_blockage ());
11592
11593 DONE;
11594 })
11595 \f
11596 ;; Prologue and epilogue instructions
11597
11598 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11599 ;; all of memory. This blocks insns from being moved across this point.
11600
11601 (define_insn "blockage"
11602 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11603 ""
11604 ""
11605 [(set_attr "length" "0")])
11606
11607 ;; Do not schedule instructions accessing memory across this point.
11608
11609 (define_expand "memory_blockage"
11610 [(set (match_dup 0)
11611 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11612 ""
11613 {
11614 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11615 MEM_VOLATILE_P (operands[0]) = 1;
11616 })
11617
11618 (define_insn "*memory_blockage"
11619 [(set (match_operand:BLK 0 "" "")
11620 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11621 ""
11622 ""
11623 [(set_attr "length" "0")])
11624
11625 ;; As USE insns aren't meaningful after reload, this is used instead
11626 ;; to prevent deleting instructions setting registers for PIC code
11627 (define_insn "prologue_use"
11628 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11629 ""
11630 ""
11631 [(set_attr "length" "0")])
11632
11633 ;; Insn emitted into the body of a function to return from a function.
11634 ;; This is only done if the function's epilogue is known to be simple.
11635 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11636
11637 (define_expand "return"
11638 [(simple_return)]
11639 "ix86_can_use_return_insn_p ()"
11640 {
11641 ix86_maybe_emit_epilogue_vzeroupper ();
11642 if (crtl->args.pops_args)
11643 {
11644 rtx popc = GEN_INT (crtl->args.pops_args);
11645 emit_jump_insn (gen_simple_return_pop_internal (popc));
11646 DONE;
11647 }
11648 })
11649
11650 ;; We need to disable this for TARGET_SEH, as otherwise
11651 ;; shrink-wrapped prologue gets enabled too. This might exceed
11652 ;; the maximum size of prologue in unwind information.
11653
11654 (define_expand "simple_return"
11655 [(simple_return)]
11656 "!TARGET_SEH"
11657 {
11658 ix86_maybe_emit_epilogue_vzeroupper ();
11659 if (crtl->args.pops_args)
11660 {
11661 rtx popc = GEN_INT (crtl->args.pops_args);
11662 emit_jump_insn (gen_simple_return_pop_internal (popc));
11663 DONE;
11664 }
11665 })
11666
11667 (define_insn "simple_return_internal"
11668 [(simple_return)]
11669 "reload_completed"
11670 "ret"
11671 [(set_attr "length" "1")
11672 (set_attr "atom_unit" "jeu")
11673 (set_attr "length_immediate" "0")
11674 (set_attr "modrm" "0")])
11675
11676 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11677 ;; instruction Athlon and K8 have.
11678
11679 (define_insn "simple_return_internal_long"
11680 [(simple_return)
11681 (unspec [(const_int 0)] UNSPEC_REP)]
11682 "reload_completed"
11683 "rep\;ret"
11684 [(set_attr "length" "2")
11685 (set_attr "atom_unit" "jeu")
11686 (set_attr "length_immediate" "0")
11687 (set_attr "prefix_rep" "1")
11688 (set_attr "modrm" "0")])
11689
11690 (define_insn "simple_return_pop_internal"
11691 [(simple_return)
11692 (use (match_operand:SI 0 "const_int_operand" ""))]
11693 "reload_completed"
11694 "ret\t%0"
11695 [(set_attr "length" "3")
11696 (set_attr "atom_unit" "jeu")
11697 (set_attr "length_immediate" "2")
11698 (set_attr "modrm" "0")])
11699
11700 (define_insn "simple_return_indirect_internal"
11701 [(simple_return)
11702 (use (match_operand:SI 0 "register_operand" "r"))]
11703 "reload_completed"
11704 "jmp\t%A0"
11705 [(set_attr "type" "ibr")
11706 (set_attr "length_immediate" "0")])
11707
11708 (define_insn "nop"
11709 [(const_int 0)]
11710 ""
11711 "nop"
11712 [(set_attr "length" "1")
11713 (set_attr "length_immediate" "0")
11714 (set_attr "modrm" "0")])
11715
11716 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11717 (define_insn "nops"
11718 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11719 UNSPECV_NOPS)]
11720 "reload_completed"
11721 {
11722 int num = INTVAL (operands[0]);
11723
11724 gcc_assert (num >= 1 && num <= 8);
11725
11726 while (num--)
11727 fputs ("\tnop\n", asm_out_file);
11728
11729 return "";
11730 }
11731 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11732 (set_attr "length_immediate" "0")
11733 (set_attr "modrm" "0")])
11734
11735 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11736 ;; branch prediction penalty for the third jump in a 16-byte
11737 ;; block on K8.
11738
11739 (define_insn "pad"
11740 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11741 ""
11742 {
11743 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11744 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11745 #else
11746 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11747 The align insn is used to avoid 3 jump instructions in the row to improve
11748 branch prediction and the benefits hardly outweigh the cost of extra 8
11749 nops on the average inserted by full alignment pseudo operation. */
11750 #endif
11751 return "";
11752 }
11753 [(set_attr "length" "16")])
11754
11755 (define_expand "prologue"
11756 [(const_int 0)]
11757 ""
11758 "ix86_expand_prologue (); DONE;")
11759
11760 (define_insn "set_got"
11761 [(set (match_operand:SI 0 "register_operand" "=r")
11762 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11763 (clobber (reg:CC FLAGS_REG))]
11764 "!TARGET_64BIT"
11765 "* return output_set_got (operands[0], NULL_RTX);"
11766 [(set_attr "type" "multi")
11767 (set_attr "length" "12")])
11768
11769 (define_insn "set_got_labelled"
11770 [(set (match_operand:SI 0 "register_operand" "=r")
11771 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11772 UNSPEC_SET_GOT))
11773 (clobber (reg:CC FLAGS_REG))]
11774 "!TARGET_64BIT"
11775 "* return output_set_got (operands[0], operands[1]);"
11776 [(set_attr "type" "multi")
11777 (set_attr "length" "12")])
11778
11779 (define_insn "set_got_rex64"
11780 [(set (match_operand:DI 0 "register_operand" "=r")
11781 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11782 "TARGET_64BIT"
11783 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11784 [(set_attr "type" "lea")
11785 (set_attr "length_address" "4")
11786 (set_attr "mode" "DI")])
11787
11788 (define_insn "set_rip_rex64"
11789 [(set (match_operand:DI 0 "register_operand" "=r")
11790 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11791 "TARGET_64BIT"
11792 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11793 [(set_attr "type" "lea")
11794 (set_attr "length_address" "4")
11795 (set_attr "mode" "DI")])
11796
11797 (define_insn "set_got_offset_rex64"
11798 [(set (match_operand:DI 0 "register_operand" "=r")
11799 (unspec:DI
11800 [(label_ref (match_operand 1 "" ""))]
11801 UNSPEC_SET_GOT_OFFSET))]
11802 "TARGET_LP64"
11803 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11804 [(set_attr "type" "imov")
11805 (set_attr "length_immediate" "0")
11806 (set_attr "length_address" "8")
11807 (set_attr "mode" "DI")])
11808
11809 (define_expand "epilogue"
11810 [(const_int 0)]
11811 ""
11812 "ix86_expand_epilogue (1); DONE;")
11813
11814 (define_expand "sibcall_epilogue"
11815 [(const_int 0)]
11816 ""
11817 "ix86_expand_epilogue (0); DONE;")
11818
11819 (define_expand "eh_return"
11820 [(use (match_operand 0 "register_operand" ""))]
11821 ""
11822 {
11823 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11824
11825 /* Tricky bit: we write the address of the handler to which we will
11826 be returning into someone else's stack frame, one word below the
11827 stack address we wish to restore. */
11828 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11829 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11830 tmp = gen_rtx_MEM (Pmode, tmp);
11831 emit_move_insn (tmp, ra);
11832
11833 emit_jump_insn (gen_eh_return_internal ());
11834 emit_barrier ();
11835 DONE;
11836 })
11837
11838 (define_insn_and_split "eh_return_internal"
11839 [(eh_return)]
11840 ""
11841 "#"
11842 "epilogue_completed"
11843 [(const_int 0)]
11844 "ix86_expand_epilogue (2); DONE;")
11845
11846 (define_insn "leave"
11847 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11848 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11849 (clobber (mem:BLK (scratch)))]
11850 "!TARGET_64BIT"
11851 "leave"
11852 [(set_attr "type" "leave")])
11853
11854 (define_insn "leave_rex64"
11855 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11856 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11857 (clobber (mem:BLK (scratch)))]
11858 "TARGET_64BIT"
11859 "leave"
11860 [(set_attr "type" "leave")])
11861 \f
11862 ;; Handle -fsplit-stack.
11863
11864 (define_expand "split_stack_prologue"
11865 [(const_int 0)]
11866 ""
11867 {
11868 ix86_expand_split_stack_prologue ();
11869 DONE;
11870 })
11871
11872 ;; In order to support the call/return predictor, we use a return
11873 ;; instruction which the middle-end doesn't see.
11874 (define_insn "split_stack_return"
11875 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11876 UNSPECV_SPLIT_STACK_RETURN)]
11877 ""
11878 {
11879 if (operands[0] == const0_rtx)
11880 return "ret";
11881 else
11882 return "ret\t%0";
11883 }
11884 [(set_attr "atom_unit" "jeu")
11885 (set_attr "modrm" "0")
11886 (set (attr "length")
11887 (if_then_else (match_operand:SI 0 "const0_operand" "")
11888 (const_int 1)
11889 (const_int 3)))
11890 (set (attr "length_immediate")
11891 (if_then_else (match_operand:SI 0 "const0_operand" "")
11892 (const_int 0)
11893 (const_int 2)))])
11894
11895 ;; If there are operand 0 bytes available on the stack, jump to
11896 ;; operand 1.
11897
11898 (define_expand "split_stack_space_check"
11899 [(set (pc) (if_then_else
11900 (ltu (minus (reg SP_REG)
11901 (match_operand 0 "register_operand" ""))
11902 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11903 (label_ref (match_operand 1 "" ""))
11904 (pc)))]
11905 ""
11906 {
11907 rtx reg, size, limit;
11908
11909 reg = gen_reg_rtx (Pmode);
11910 size = force_reg (Pmode, operands[0]);
11911 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11912 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11913 UNSPEC_STACK_CHECK);
11914 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11915 ix86_expand_branch (GEU, reg, limit, operands[1]);
11916
11917 DONE;
11918 })
11919 \f
11920 ;; Bit manipulation instructions.
11921
11922 (define_expand "ffs<mode>2"
11923 [(set (match_dup 2) (const_int -1))
11924 (parallel [(set (reg:CCZ FLAGS_REG)
11925 (compare:CCZ
11926 (match_operand:SWI48 1 "nonimmediate_operand" "")
11927 (const_int 0)))
11928 (set (match_operand:SWI48 0 "register_operand" "")
11929 (ctz:SWI48 (match_dup 1)))])
11930 (set (match_dup 0) (if_then_else:SWI48
11931 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11932 (match_dup 2)
11933 (match_dup 0)))
11934 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11935 (clobber (reg:CC FLAGS_REG))])]
11936 ""
11937 {
11938 if (<MODE>mode == SImode && !TARGET_CMOVE)
11939 {
11940 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11941 DONE;
11942 }
11943 operands[2] = gen_reg_rtx (<MODE>mode);
11944 })
11945
11946 (define_insn_and_split "ffssi2_no_cmove"
11947 [(set (match_operand:SI 0 "register_operand" "=r")
11948 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11949 (clobber (match_scratch:SI 2 "=&q"))
11950 (clobber (reg:CC FLAGS_REG))]
11951 "!TARGET_CMOVE"
11952 "#"
11953 "&& reload_completed"
11954 [(parallel [(set (reg:CCZ FLAGS_REG)
11955 (compare:CCZ (match_dup 1) (const_int 0)))
11956 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11957 (set (strict_low_part (match_dup 3))
11958 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11959 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11960 (clobber (reg:CC FLAGS_REG))])
11961 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11962 (clobber (reg:CC FLAGS_REG))])
11963 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11964 (clobber (reg:CC FLAGS_REG))])]
11965 {
11966 operands[3] = gen_lowpart (QImode, operands[2]);
11967 ix86_expand_clear (operands[2]);
11968 })
11969
11970 (define_insn "*ffs<mode>_1"
11971 [(set (reg:CCZ FLAGS_REG)
11972 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11973 (const_int 0)))
11974 (set (match_operand:SWI48 0 "register_operand" "=r")
11975 (ctz:SWI48 (match_dup 1)))]
11976 ""
11977 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11978 [(set_attr "type" "alu1")
11979 (set_attr "prefix_0f" "1")
11980 (set_attr "mode" "<MODE>")])
11981
11982 (define_insn "ctz<mode>2"
11983 [(set (match_operand:SWI248 0 "register_operand" "=r")
11984 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11985 (clobber (reg:CC FLAGS_REG))]
11986 ""
11987 {
11988 if (TARGET_BMI)
11989 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11990 else
11991 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11992 }
11993 [(set_attr "type" "alu1")
11994 (set_attr "prefix_0f" "1")
11995 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11996 (set_attr "mode" "<MODE>")])
11997
11998 (define_expand "clz<mode>2"
11999 [(parallel
12000 [(set (match_operand:SWI248 0 "register_operand" "")
12001 (minus:SWI248
12002 (match_dup 2)
12003 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12004 (clobber (reg:CC FLAGS_REG))])
12005 (parallel
12006 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12007 (clobber (reg:CC FLAGS_REG))])]
12008 ""
12009 {
12010 if (TARGET_LZCNT)
12011 {
12012 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12013 DONE;
12014 }
12015 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12016 })
12017
12018 (define_insn "clz<mode>2_lzcnt"
12019 [(set (match_operand:SWI248 0 "register_operand" "=r")
12020 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12021 (clobber (reg:CC FLAGS_REG))]
12022 "TARGET_LZCNT"
12023 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12024 [(set_attr "prefix_rep" "1")
12025 (set_attr "type" "bitmanip")
12026 (set_attr "mode" "<MODE>")])
12027
12028 ;; BMI instructions.
12029 (define_insn "*bmi_andn_<mode>"
12030 [(set (match_operand:SWI48 0 "register_operand" "=r")
12031 (and:SWI48
12032 (not:SWI48
12033 (match_operand:SWI48 1 "register_operand" "r"))
12034 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12035 (clobber (reg:CC FLAGS_REG))]
12036 "TARGET_BMI"
12037 "andn\t{%2, %1, %0|%0, %1, %2}"
12038 [(set_attr "type" "bitmanip")
12039 (set_attr "mode" "<MODE>")])
12040
12041 (define_insn "bmi_bextr_<mode>"
12042 [(set (match_operand:SWI48 0 "register_operand" "=r")
12043 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12044 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12045 UNSPEC_BEXTR))
12046 (clobber (reg:CC FLAGS_REG))]
12047 "TARGET_BMI"
12048 "bextr\t{%2, %1, %0|%0, %1, %2}"
12049 [(set_attr "type" "bitmanip")
12050 (set_attr "mode" "<MODE>")])
12051
12052 (define_insn "*bmi_blsi_<mode>"
12053 [(set (match_operand:SWI48 0 "register_operand" "=r")
12054 (and:SWI48
12055 (neg:SWI48
12056 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12057 (match_dup 1)))
12058 (clobber (reg:CC FLAGS_REG))]
12059 "TARGET_BMI"
12060 "blsi\t{%1, %0|%0, %1}"
12061 [(set_attr "type" "bitmanip")
12062 (set_attr "mode" "<MODE>")])
12063
12064 (define_insn "*bmi_blsmsk_<mode>"
12065 [(set (match_operand:SWI48 0 "register_operand" "=r")
12066 (xor:SWI48
12067 (plus:SWI48
12068 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12069 (const_int -1))
12070 (match_dup 1)))
12071 (clobber (reg:CC FLAGS_REG))]
12072 "TARGET_BMI"
12073 "blsmsk\t{%1, %0|%0, %1}"
12074 [(set_attr "type" "bitmanip")
12075 (set_attr "mode" "<MODE>")])
12076
12077 (define_insn "*bmi_blsr_<mode>"
12078 [(set (match_operand:SWI48 0 "register_operand" "=r")
12079 (and:SWI48
12080 (plus:SWI48
12081 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12082 (const_int -1))
12083 (match_dup 1)))
12084 (clobber (reg:CC FLAGS_REG))]
12085 "TARGET_BMI"
12086 "blsr\t{%1, %0|%0, %1}"
12087 [(set_attr "type" "bitmanip")
12088 (set_attr "mode" "<MODE>")])
12089
12090 ;; BMI2 instructions.
12091 (define_insn "bmi2_bzhi_<mode>3"
12092 [(set (match_operand:SWI48 0 "register_operand" "=r")
12093 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12094 (lshiftrt:SWI48 (const_int -1)
12095 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12096 (clobber (reg:CC FLAGS_REG))]
12097 "TARGET_BMI2"
12098 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12099 [(set_attr "type" "bitmanip")
12100 (set_attr "prefix" "vex")
12101 (set_attr "mode" "<MODE>")])
12102
12103 (define_insn "bmi2_pdep_<mode>3"
12104 [(set (match_operand:SWI48 0 "register_operand" "=r")
12105 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12106 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12107 UNSPEC_PDEP))]
12108 "TARGET_BMI2"
12109 "pdep\t{%2, %1, %0|%0, %1, %2}"
12110 [(set_attr "type" "bitmanip")
12111 (set_attr "prefix" "vex")
12112 (set_attr "mode" "<MODE>")])
12113
12114 (define_insn "bmi2_pext_<mode>3"
12115 [(set (match_operand:SWI48 0 "register_operand" "=r")
12116 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12117 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12118 UNSPEC_PEXT))]
12119 "TARGET_BMI2"
12120 "pext\t{%2, %1, %0|%0, %1, %2}"
12121 [(set_attr "type" "bitmanip")
12122 (set_attr "prefix" "vex")
12123 (set_attr "mode" "<MODE>")])
12124
12125 ;; TBM instructions.
12126 (define_insn "tbm_bextri_<mode>"
12127 [(set (match_operand:SWI48 0 "register_operand" "=r")
12128 (zero_extract:SWI48
12129 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12130 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12131 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12132 (clobber (reg:CC FLAGS_REG))]
12133 "TARGET_TBM"
12134 {
12135 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12136 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12137 }
12138 [(set_attr "type" "bitmanip")
12139 (set_attr "mode" "<MODE>")])
12140
12141 (define_insn "*tbm_blcfill_<mode>"
12142 [(set (match_operand:SWI48 0 "register_operand" "=r")
12143 (and:SWI48
12144 (plus:SWI48
12145 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12146 (const_int 1))
12147 (match_dup 1)))
12148 (clobber (reg:CC FLAGS_REG))]
12149 "TARGET_TBM"
12150 "blcfill\t{%1, %0|%0, %1}"
12151 [(set_attr "type" "bitmanip")
12152 (set_attr "mode" "<MODE>")])
12153
12154 (define_insn "*tbm_blci_<mode>"
12155 [(set (match_operand:SWI48 0 "register_operand" "=r")
12156 (ior:SWI48
12157 (not:SWI48
12158 (plus:SWI48
12159 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12160 (const_int 1)))
12161 (match_dup 1)))
12162 (clobber (reg:CC FLAGS_REG))]
12163 "TARGET_TBM"
12164 "blci\t{%1, %0|%0, %1}"
12165 [(set_attr "type" "bitmanip")
12166 (set_attr "mode" "<MODE>")])
12167
12168 (define_insn "*tbm_blcic_<mode>"
12169 [(set (match_operand:SWI48 0 "register_operand" "=r")
12170 (and:SWI48
12171 (plus:SWI48
12172 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12173 (const_int 1))
12174 (not:SWI48
12175 (match_dup 1))))
12176 (clobber (reg:CC FLAGS_REG))]
12177 "TARGET_TBM"
12178 "blcic\t{%1, %0|%0, %1}"
12179 [(set_attr "type" "bitmanip")
12180 (set_attr "mode" "<MODE>")])
12181
12182 (define_insn "*tbm_blcmsk_<mode>"
12183 [(set (match_operand:SWI48 0 "register_operand" "=r")
12184 (xor:SWI48
12185 (plus:SWI48
12186 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12187 (const_int 1))
12188 (match_dup 1)))
12189 (clobber (reg:CC FLAGS_REG))]
12190 "TARGET_TBM"
12191 "blcmsk\t{%1, %0|%0, %1}"
12192 [(set_attr "type" "bitmanip")
12193 (set_attr "mode" "<MODE>")])
12194
12195 (define_insn "*tbm_blcs_<mode>"
12196 [(set (match_operand:SWI48 0 "register_operand" "=r")
12197 (ior:SWI48
12198 (plus:SWI48
12199 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12200 (const_int 1))
12201 (match_dup 1)))
12202 (clobber (reg:CC FLAGS_REG))]
12203 "TARGET_TBM"
12204 "blcs\t{%1, %0|%0, %1}"
12205 [(set_attr "type" "bitmanip")
12206 (set_attr "mode" "<MODE>")])
12207
12208 (define_insn "*tbm_blsfill_<mode>"
12209 [(set (match_operand:SWI48 0 "register_operand" "=r")
12210 (ior:SWI48
12211 (plus:SWI48
12212 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12213 (const_int -1))
12214 (match_dup 1)))
12215 (clobber (reg:CC FLAGS_REG))]
12216 "TARGET_TBM"
12217 "blsfill\t{%1, %0|%0, %1}"
12218 [(set_attr "type" "bitmanip")
12219 (set_attr "mode" "<MODE>")])
12220
12221 (define_insn "*tbm_blsic_<mode>"
12222 [(set (match_operand:SWI48 0 "register_operand" "=r")
12223 (ior:SWI48
12224 (plus:SWI48
12225 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12226 (const_int -1))
12227 (not:SWI48
12228 (match_dup 1))))
12229 (clobber (reg:CC FLAGS_REG))]
12230 "TARGET_TBM"
12231 "blsic\t{%1, %0|%0, %1}"
12232 [(set_attr "type" "bitmanip")
12233 (set_attr "mode" "<MODE>")])
12234
12235 (define_insn "*tbm_t1mskc_<mode>"
12236 [(set (match_operand:SWI48 0 "register_operand" "=r")
12237 (ior:SWI48
12238 (plus:SWI48
12239 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12240 (const_int 1))
12241 (not:SWI48
12242 (match_dup 1))))
12243 (clobber (reg:CC FLAGS_REG))]
12244 "TARGET_TBM"
12245 "t1mskc\t{%1, %0|%0, %1}"
12246 [(set_attr "type" "bitmanip")
12247 (set_attr "mode" "<MODE>")])
12248
12249 (define_insn "*tbm_tzmsk_<mode>"
12250 [(set (match_operand:SWI48 0 "register_operand" "=r")
12251 (and:SWI48
12252 (plus:SWI48
12253 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12254 (const_int -1))
12255 (not:SWI48
12256 (match_dup 1))))
12257 (clobber (reg:CC FLAGS_REG))]
12258 "TARGET_TBM"
12259 "tzmsk\t{%1, %0|%0, %1}"
12260 [(set_attr "type" "bitmanip")
12261 (set_attr "mode" "<MODE>")])
12262
12263 (define_insn "bsr_rex64"
12264 [(set (match_operand:DI 0 "register_operand" "=r")
12265 (minus:DI (const_int 63)
12266 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12267 (clobber (reg:CC FLAGS_REG))]
12268 "TARGET_64BIT"
12269 "bsr{q}\t{%1, %0|%0, %1}"
12270 [(set_attr "type" "alu1")
12271 (set_attr "prefix_0f" "1")
12272 (set_attr "mode" "DI")])
12273
12274 (define_insn "bsr"
12275 [(set (match_operand:SI 0 "register_operand" "=r")
12276 (minus:SI (const_int 31)
12277 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12278 (clobber (reg:CC FLAGS_REG))]
12279 ""
12280 "bsr{l}\t{%1, %0|%0, %1}"
12281 [(set_attr "type" "alu1")
12282 (set_attr "prefix_0f" "1")
12283 (set_attr "mode" "SI")])
12284
12285 (define_insn "*bsrhi"
12286 [(set (match_operand:HI 0 "register_operand" "=r")
12287 (minus:HI (const_int 15)
12288 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12289 (clobber (reg:CC FLAGS_REG))]
12290 ""
12291 "bsr{w}\t{%1, %0|%0, %1}"
12292 [(set_attr "type" "alu1")
12293 (set_attr "prefix_0f" "1")
12294 (set_attr "mode" "HI")])
12295
12296 (define_insn "popcount<mode>2"
12297 [(set (match_operand:SWI248 0 "register_operand" "=r")
12298 (popcount:SWI248
12299 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12300 (clobber (reg:CC FLAGS_REG))]
12301 "TARGET_POPCNT"
12302 {
12303 #if TARGET_MACHO
12304 return "popcnt\t{%1, %0|%0, %1}";
12305 #else
12306 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12307 #endif
12308 }
12309 [(set_attr "prefix_rep" "1")
12310 (set_attr "type" "bitmanip")
12311 (set_attr "mode" "<MODE>")])
12312
12313 (define_insn "*popcount<mode>2_cmp"
12314 [(set (reg FLAGS_REG)
12315 (compare
12316 (popcount:SWI248
12317 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12318 (const_int 0)))
12319 (set (match_operand:SWI248 0 "register_operand" "=r")
12320 (popcount:SWI248 (match_dup 1)))]
12321 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12322 {
12323 #if TARGET_MACHO
12324 return "popcnt\t{%1, %0|%0, %1}";
12325 #else
12326 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12327 #endif
12328 }
12329 [(set_attr "prefix_rep" "1")
12330 (set_attr "type" "bitmanip")
12331 (set_attr "mode" "<MODE>")])
12332
12333 (define_insn "*popcountsi2_cmp_zext"
12334 [(set (reg FLAGS_REG)
12335 (compare
12336 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12337 (const_int 0)))
12338 (set (match_operand:DI 0 "register_operand" "=r")
12339 (zero_extend:DI(popcount:SI (match_dup 1))))]
12340 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12341 {
12342 #if TARGET_MACHO
12343 return "popcnt\t{%1, %0|%0, %1}";
12344 #else
12345 return "popcnt{l}\t{%1, %0|%0, %1}";
12346 #endif
12347 }
12348 [(set_attr "prefix_rep" "1")
12349 (set_attr "type" "bitmanip")
12350 (set_attr "mode" "SI")])
12351
12352 (define_expand "bswap<mode>2"
12353 [(set (match_operand:SWI48 0 "register_operand" "")
12354 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12355 ""
12356 {
12357 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12358 {
12359 rtx x = operands[0];
12360
12361 emit_move_insn (x, operands[1]);
12362 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12363 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12364 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12365 DONE;
12366 }
12367 })
12368
12369 (define_insn "*bswap<mode>2_movbe"
12370 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12371 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12372 "TARGET_MOVBE
12373 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12374 "@
12375 bswap\t%0
12376 movbe\t{%1, %0|%0, %1}
12377 movbe\t{%1, %0|%0, %1}"
12378 [(set_attr "type" "bitmanip,imov,imov")
12379 (set_attr "modrm" "0,1,1")
12380 (set_attr "prefix_0f" "*,1,1")
12381 (set_attr "prefix_extra" "*,1,1")
12382 (set_attr "mode" "<MODE>")])
12383
12384 (define_insn "*bswap<mode>2_1"
12385 [(set (match_operand:SWI48 0 "register_operand" "=r")
12386 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12387 "TARGET_BSWAP"
12388 "bswap\t%0"
12389 [(set_attr "type" "bitmanip")
12390 (set_attr "modrm" "0")
12391 (set_attr "mode" "<MODE>")])
12392
12393 (define_insn "*bswaphi_lowpart_1"
12394 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12395 (bswap:HI (match_dup 0)))
12396 (clobber (reg:CC FLAGS_REG))]
12397 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12398 "@
12399 xchg{b}\t{%h0, %b0|%b0, %h0}
12400 rol{w}\t{$8, %0|%0, 8}"
12401 [(set_attr "length" "2,4")
12402 (set_attr "mode" "QI,HI")])
12403
12404 (define_insn "bswaphi_lowpart"
12405 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12406 (bswap:HI (match_dup 0)))
12407 (clobber (reg:CC FLAGS_REG))]
12408 ""
12409 "rol{w}\t{$8, %0|%0, 8}"
12410 [(set_attr "length" "4")
12411 (set_attr "mode" "HI")])
12412
12413 (define_expand "paritydi2"
12414 [(set (match_operand:DI 0 "register_operand" "")
12415 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12416 "! TARGET_POPCNT"
12417 {
12418 rtx scratch = gen_reg_rtx (QImode);
12419 rtx cond;
12420
12421 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12422 NULL_RTX, operands[1]));
12423
12424 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12425 gen_rtx_REG (CCmode, FLAGS_REG),
12426 const0_rtx);
12427 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12428
12429 if (TARGET_64BIT)
12430 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12431 else
12432 {
12433 rtx tmp = gen_reg_rtx (SImode);
12434
12435 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12436 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12437 }
12438 DONE;
12439 })
12440
12441 (define_expand "paritysi2"
12442 [(set (match_operand:SI 0 "register_operand" "")
12443 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12444 "! TARGET_POPCNT"
12445 {
12446 rtx scratch = gen_reg_rtx (QImode);
12447 rtx cond;
12448
12449 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12450
12451 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12452 gen_rtx_REG (CCmode, FLAGS_REG),
12453 const0_rtx);
12454 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12455
12456 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12457 DONE;
12458 })
12459
12460 (define_insn_and_split "paritydi2_cmp"
12461 [(set (reg:CC FLAGS_REG)
12462 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12463 UNSPEC_PARITY))
12464 (clobber (match_scratch:DI 0 "=r"))
12465 (clobber (match_scratch:SI 1 "=&r"))
12466 (clobber (match_scratch:HI 2 "=Q"))]
12467 "! TARGET_POPCNT"
12468 "#"
12469 "&& reload_completed"
12470 [(parallel
12471 [(set (match_dup 1)
12472 (xor:SI (match_dup 1) (match_dup 4)))
12473 (clobber (reg:CC FLAGS_REG))])
12474 (parallel
12475 [(set (reg:CC FLAGS_REG)
12476 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12477 (clobber (match_dup 1))
12478 (clobber (match_dup 2))])]
12479 {
12480 operands[4] = gen_lowpart (SImode, operands[3]);
12481
12482 if (TARGET_64BIT)
12483 {
12484 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12485 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12486 }
12487 else
12488 operands[1] = gen_highpart (SImode, operands[3]);
12489 })
12490
12491 (define_insn_and_split "paritysi2_cmp"
12492 [(set (reg:CC FLAGS_REG)
12493 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12494 UNSPEC_PARITY))
12495 (clobber (match_scratch:SI 0 "=r"))
12496 (clobber (match_scratch:HI 1 "=&Q"))]
12497 "! TARGET_POPCNT"
12498 "#"
12499 "&& reload_completed"
12500 [(parallel
12501 [(set (match_dup 1)
12502 (xor:HI (match_dup 1) (match_dup 3)))
12503 (clobber (reg:CC FLAGS_REG))])
12504 (parallel
12505 [(set (reg:CC FLAGS_REG)
12506 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12507 (clobber (match_dup 1))])]
12508 {
12509 operands[3] = gen_lowpart (HImode, operands[2]);
12510
12511 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12512 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12513 })
12514
12515 (define_insn "*parityhi2_cmp"
12516 [(set (reg:CC FLAGS_REG)
12517 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12518 UNSPEC_PARITY))
12519 (clobber (match_scratch:HI 0 "=Q"))]
12520 "! TARGET_POPCNT"
12521 "xor{b}\t{%h0, %b0|%b0, %h0}"
12522 [(set_attr "length" "2")
12523 (set_attr "mode" "HI")])
12524
12525 \f
12526 ;; Thread-local storage patterns for ELF.
12527 ;;
12528 ;; Note that these code sequences must appear exactly as shown
12529 ;; in order to allow linker relaxation.
12530
12531 (define_insn "*tls_global_dynamic_32_gnu"
12532 [(set (match_operand:SI 0 "register_operand" "=a")
12533 (unspec:SI
12534 [(match_operand:SI 1 "register_operand" "b")
12535 (match_operand:SI 2 "tls_symbolic_operand" "")
12536 (match_operand:SI 3 "constant_call_address_operand" "z")]
12537 UNSPEC_TLS_GD))
12538 (clobber (match_scratch:SI 4 "=d"))
12539 (clobber (match_scratch:SI 5 "=c"))
12540 (clobber (reg:CC FLAGS_REG))]
12541 "!TARGET_64BIT && TARGET_GNU_TLS"
12542 {
12543 output_asm_insn
12544 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12545 if (TARGET_SUN_TLS)
12546 #ifdef HAVE_AS_IX86_TLSGDPLT
12547 return "call\t%a2@tlsgdplt";
12548 #else
12549 return "call\t%p3@plt";
12550 #endif
12551 return "call\t%P3";
12552 }
12553 [(set_attr "type" "multi")
12554 (set_attr "length" "12")])
12555
12556 (define_expand "tls_global_dynamic_32"
12557 [(parallel
12558 [(set (match_operand:SI 0 "register_operand" "")
12559 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12560 (match_operand:SI 1 "tls_symbolic_operand" "")
12561 (match_operand:SI 3 "constant_call_address_operand" "")]
12562 UNSPEC_TLS_GD))
12563 (clobber (match_scratch:SI 4 ""))
12564 (clobber (match_scratch:SI 5 ""))
12565 (clobber (reg:CC FLAGS_REG))])])
12566
12567 (define_insn "*tls_global_dynamic_64"
12568 [(set (match_operand:DI 0 "register_operand" "=a")
12569 (call:DI
12570 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12571 (match_operand:DI 3 "" "")))
12572 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12573 UNSPEC_TLS_GD)]
12574 "TARGET_64BIT"
12575 {
12576 if (!TARGET_X32)
12577 fputs (ASM_BYTE "0x66\n", asm_out_file);
12578 output_asm_insn
12579 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12580 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12581 fputs ("\trex64\n", asm_out_file);
12582 if (TARGET_SUN_TLS)
12583 return "call\t%p2@plt";
12584 return "call\t%P2";
12585 }
12586 [(set_attr "type" "multi")
12587 (set (attr "length")
12588 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12589
12590 (define_expand "tls_global_dynamic_64"
12591 [(parallel
12592 [(set (match_operand:DI 0 "register_operand" "")
12593 (call:DI
12594 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12595 (const_int 0)))
12596 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12597 UNSPEC_TLS_GD)])])
12598
12599 (define_insn "*tls_local_dynamic_base_32_gnu"
12600 [(set (match_operand:SI 0 "register_operand" "=a")
12601 (unspec:SI
12602 [(match_operand:SI 1 "register_operand" "b")
12603 (match_operand:SI 2 "constant_call_address_operand" "z")]
12604 UNSPEC_TLS_LD_BASE))
12605 (clobber (match_scratch:SI 3 "=d"))
12606 (clobber (match_scratch:SI 4 "=c"))
12607 (clobber (reg:CC FLAGS_REG))]
12608 "!TARGET_64BIT && TARGET_GNU_TLS"
12609 {
12610 output_asm_insn
12611 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12612 if (TARGET_SUN_TLS)
12613 #ifdef HAVE_AS_IX86_TLSLDMPLT
12614 return "call\t%&@tlsldmplt";
12615 #else
12616 return "call\t%p2@plt";
12617 #endif
12618 return "call\t%P2";
12619 }
12620 [(set_attr "type" "multi")
12621 (set_attr "length" "11")])
12622
12623 (define_expand "tls_local_dynamic_base_32"
12624 [(parallel
12625 [(set (match_operand:SI 0 "register_operand" "")
12626 (unspec:SI
12627 [(match_operand:SI 1 "register_operand" "")
12628 (match_operand:SI 2 "constant_call_address_operand" "")]
12629 UNSPEC_TLS_LD_BASE))
12630 (clobber (match_scratch:SI 3 ""))
12631 (clobber (match_scratch:SI 4 ""))
12632 (clobber (reg:CC FLAGS_REG))])])
12633
12634 (define_insn "*tls_local_dynamic_base_64"
12635 [(set (match_operand:DI 0 "register_operand" "=a")
12636 (call:DI
12637 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12638 (match_operand:DI 2 "" "")))
12639 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12640 "TARGET_64BIT"
12641 {
12642 output_asm_insn
12643 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12644 if (TARGET_SUN_TLS)
12645 return "call\t%p1@plt";
12646 return "call\t%P1";
12647 }
12648 [(set_attr "type" "multi")
12649 (set_attr "length" "12")])
12650
12651 (define_expand "tls_local_dynamic_base_64"
12652 [(parallel
12653 [(set (match_operand:DI 0 "register_operand" "")
12654 (call:DI
12655 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12656 (const_int 0)))
12657 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12658
12659 ;; Local dynamic of a single variable is a lose. Show combine how
12660 ;; to convert that back to global dynamic.
12661
12662 (define_insn_and_split "*tls_local_dynamic_32_once"
12663 [(set (match_operand:SI 0 "register_operand" "=a")
12664 (plus:SI
12665 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12666 (match_operand:SI 2 "constant_call_address_operand" "z")]
12667 UNSPEC_TLS_LD_BASE)
12668 (const:SI (unspec:SI
12669 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12670 UNSPEC_DTPOFF))))
12671 (clobber (match_scratch:SI 4 "=d"))
12672 (clobber (match_scratch:SI 5 "=c"))
12673 (clobber (reg:CC FLAGS_REG))]
12674 ""
12675 "#"
12676 ""
12677 [(parallel
12678 [(set (match_dup 0)
12679 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12680 UNSPEC_TLS_GD))
12681 (clobber (match_dup 4))
12682 (clobber (match_dup 5))
12683 (clobber (reg:CC FLAGS_REG))])])
12684
12685 ;; Segment register for the thread base ptr load
12686 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12687
12688 ;; Load and add the thread base pointer from %<tp_seg>:0.
12689 (define_insn "*load_tp_x32"
12690 [(set (match_operand:SI 0 "register_operand" "=r")
12691 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12692 "TARGET_X32"
12693 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12694 [(set_attr "type" "imov")
12695 (set_attr "modrm" "0")
12696 (set_attr "length" "7")
12697 (set_attr "memory" "load")
12698 (set_attr "imm_disp" "false")])
12699
12700 (define_insn "*load_tp_x32_zext"
12701 [(set (match_operand:DI 0 "register_operand" "=r")
12702 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12703 "TARGET_X32"
12704 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12705 [(set_attr "type" "imov")
12706 (set_attr "modrm" "0")
12707 (set_attr "length" "7")
12708 (set_attr "memory" "load")
12709 (set_attr "imm_disp" "false")])
12710
12711 (define_insn "*load_tp_<mode>"
12712 [(set (match_operand:P 0 "register_operand" "=r")
12713 (unspec:P [(const_int 0)] UNSPEC_TP))]
12714 "!TARGET_X32"
12715 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12716 [(set_attr "type" "imov")
12717 (set_attr "modrm" "0")
12718 (set_attr "length" "7")
12719 (set_attr "memory" "load")
12720 (set_attr "imm_disp" "false")])
12721
12722 (define_insn "*add_tp_x32"
12723 [(set (match_operand:SI 0 "register_operand" "=r")
12724 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12725 (match_operand:SI 1 "register_operand" "0")))
12726 (clobber (reg:CC FLAGS_REG))]
12727 "TARGET_X32"
12728 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12729 [(set_attr "type" "alu")
12730 (set_attr "modrm" "0")
12731 (set_attr "length" "7")
12732 (set_attr "memory" "load")
12733 (set_attr "imm_disp" "false")])
12734
12735 (define_insn "*add_tp_x32_zext"
12736 [(set (match_operand:DI 0 "register_operand" "=r")
12737 (zero_extend:DI
12738 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12739 (match_operand:SI 1 "register_operand" "0"))))
12740 (clobber (reg:CC FLAGS_REG))]
12741 "TARGET_X32"
12742 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12743 [(set_attr "type" "alu")
12744 (set_attr "modrm" "0")
12745 (set_attr "length" "7")
12746 (set_attr "memory" "load")
12747 (set_attr "imm_disp" "false")])
12748
12749 (define_insn "*add_tp_<mode>"
12750 [(set (match_operand:P 0 "register_operand" "=r")
12751 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12752 (match_operand:P 1 "register_operand" "0")))
12753 (clobber (reg:CC FLAGS_REG))]
12754 "!TARGET_X32"
12755 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12756 [(set_attr "type" "alu")
12757 (set_attr "modrm" "0")
12758 (set_attr "length" "7")
12759 (set_attr "memory" "load")
12760 (set_attr "imm_disp" "false")])
12761
12762 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12763 ;; %rax as destination of the initial executable code sequence.
12764 (define_insn "tls_initial_exec_64_sun"
12765 [(set (match_operand:DI 0 "register_operand" "=a")
12766 (unspec:DI
12767 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12768 UNSPEC_TLS_IE_SUN))
12769 (clobber (reg:CC FLAGS_REG))]
12770 "TARGET_64BIT && TARGET_SUN_TLS"
12771 {
12772 output_asm_insn
12773 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12774 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12775 }
12776 [(set_attr "type" "multi")])
12777
12778 ;; GNU2 TLS patterns can be split.
12779
12780 (define_expand "tls_dynamic_gnu2_32"
12781 [(set (match_dup 3)
12782 (plus:SI (match_operand:SI 2 "register_operand" "")
12783 (const:SI
12784 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12785 UNSPEC_TLSDESC))))
12786 (parallel
12787 [(set (match_operand:SI 0 "register_operand" "")
12788 (unspec:SI [(match_dup 1) (match_dup 3)
12789 (match_dup 2) (reg:SI SP_REG)]
12790 UNSPEC_TLSDESC))
12791 (clobber (reg:CC FLAGS_REG))])]
12792 "!TARGET_64BIT && TARGET_GNU2_TLS"
12793 {
12794 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12795 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12796 })
12797
12798 (define_insn "*tls_dynamic_gnu2_lea_32"
12799 [(set (match_operand:SI 0 "register_operand" "=r")
12800 (plus:SI (match_operand:SI 1 "register_operand" "b")
12801 (const:SI
12802 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12803 UNSPEC_TLSDESC))))]
12804 "!TARGET_64BIT && TARGET_GNU2_TLS"
12805 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12806 [(set_attr "type" "lea")
12807 (set_attr "mode" "SI")
12808 (set_attr "length" "6")
12809 (set_attr "length_address" "4")])
12810
12811 (define_insn "*tls_dynamic_gnu2_call_32"
12812 [(set (match_operand:SI 0 "register_operand" "=a")
12813 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12814 (match_operand:SI 2 "register_operand" "0")
12815 ;; we have to make sure %ebx still points to the GOT
12816 (match_operand:SI 3 "register_operand" "b")
12817 (reg:SI SP_REG)]
12818 UNSPEC_TLSDESC))
12819 (clobber (reg:CC FLAGS_REG))]
12820 "!TARGET_64BIT && TARGET_GNU2_TLS"
12821 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12822 [(set_attr "type" "call")
12823 (set_attr "length" "2")
12824 (set_attr "length_address" "0")])
12825
12826 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12827 [(set (match_operand:SI 0 "register_operand" "=&a")
12828 (plus:SI
12829 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12830 (match_operand:SI 4 "" "")
12831 (match_operand:SI 2 "register_operand" "b")
12832 (reg:SI SP_REG)]
12833 UNSPEC_TLSDESC)
12834 (const:SI (unspec:SI
12835 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12836 UNSPEC_DTPOFF))))
12837 (clobber (reg:CC FLAGS_REG))]
12838 "!TARGET_64BIT && TARGET_GNU2_TLS"
12839 "#"
12840 ""
12841 [(set (match_dup 0) (match_dup 5))]
12842 {
12843 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12844 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12845 })
12846
12847 (define_expand "tls_dynamic_gnu2_64"
12848 [(set (match_dup 2)
12849 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12850 UNSPEC_TLSDESC))
12851 (parallel
12852 [(set (match_operand:DI 0 "register_operand" "")
12853 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12854 UNSPEC_TLSDESC))
12855 (clobber (reg:CC FLAGS_REG))])]
12856 "TARGET_64BIT && TARGET_GNU2_TLS"
12857 {
12858 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12859 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12860 })
12861
12862 (define_insn "*tls_dynamic_gnu2_lea_64"
12863 [(set (match_operand:DI 0 "register_operand" "=r")
12864 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12865 UNSPEC_TLSDESC))]
12866 "TARGET_64BIT && TARGET_GNU2_TLS"
12867 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12868 [(set_attr "type" "lea")
12869 (set_attr "mode" "DI")
12870 (set_attr "length" "7")
12871 (set_attr "length_address" "4")])
12872
12873 (define_insn "*tls_dynamic_gnu2_call_64"
12874 [(set (match_operand:DI 0 "register_operand" "=a")
12875 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12876 (match_operand:DI 2 "register_operand" "0")
12877 (reg:DI SP_REG)]
12878 UNSPEC_TLSDESC))
12879 (clobber (reg:CC FLAGS_REG))]
12880 "TARGET_64BIT && TARGET_GNU2_TLS"
12881 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12882 [(set_attr "type" "call")
12883 (set_attr "length" "2")
12884 (set_attr "length_address" "0")])
12885
12886 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12887 [(set (match_operand:DI 0 "register_operand" "=&a")
12888 (plus:DI
12889 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12890 (match_operand:DI 3 "" "")
12891 (reg:DI SP_REG)]
12892 UNSPEC_TLSDESC)
12893 (const:DI (unspec:DI
12894 [(match_operand 1 "tls_symbolic_operand" "")]
12895 UNSPEC_DTPOFF))))
12896 (clobber (reg:CC FLAGS_REG))]
12897 "TARGET_64BIT && TARGET_GNU2_TLS"
12898 "#"
12899 ""
12900 [(set (match_dup 0) (match_dup 4))]
12901 {
12902 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12903 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12904 })
12905 \f
12906 ;; These patterns match the binary 387 instructions for addM3, subM3,
12907 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12908 ;; SFmode. The first is the normal insn, the second the same insn but
12909 ;; with one operand a conversion, and the third the same insn but with
12910 ;; the other operand a conversion. The conversion may be SFmode or
12911 ;; SImode if the target mode DFmode, but only SImode if the target mode
12912 ;; is SFmode.
12913
12914 ;; Gcc is slightly more smart about handling normal two address instructions
12915 ;; so use special patterns for add and mull.
12916
12917 (define_insn "*fop_<mode>_comm_mixed"
12918 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12919 (match_operator:MODEF 3 "binary_fp_operator"
12920 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12921 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12922 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12923 && COMMUTATIVE_ARITH_P (operands[3])
12924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12925 "* return output_387_binary_op (insn, operands);"
12926 [(set (attr "type")
12927 (if_then_else (eq_attr "alternative" "1,2")
12928 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12929 (const_string "ssemul")
12930 (const_string "sseadd"))
12931 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12932 (const_string "fmul")
12933 (const_string "fop"))))
12934 (set_attr "isa" "*,noavx,avx")
12935 (set_attr "prefix" "orig,orig,vex")
12936 (set_attr "mode" "<MODE>")])
12937
12938 (define_insn "*fop_<mode>_comm_sse"
12939 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12940 (match_operator:MODEF 3 "binary_fp_operator"
12941 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12942 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12943 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12944 && COMMUTATIVE_ARITH_P (operands[3])
12945 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12946 "* return output_387_binary_op (insn, operands);"
12947 [(set (attr "type")
12948 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12949 (const_string "ssemul")
12950 (const_string "sseadd")))
12951 (set_attr "isa" "noavx,avx")
12952 (set_attr "prefix" "orig,vex")
12953 (set_attr "mode" "<MODE>")])
12954
12955 (define_insn "*fop_<mode>_comm_i387"
12956 [(set (match_operand:MODEF 0 "register_operand" "=f")
12957 (match_operator:MODEF 3 "binary_fp_operator"
12958 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12959 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12960 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12961 && COMMUTATIVE_ARITH_P (operands[3])
12962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12963 "* return output_387_binary_op (insn, operands);"
12964 [(set (attr "type")
12965 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12966 (const_string "fmul")
12967 (const_string "fop")))
12968 (set_attr "mode" "<MODE>")])
12969
12970 (define_insn "*fop_<mode>_1_mixed"
12971 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12972 (match_operator:MODEF 3 "binary_fp_operator"
12973 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12974 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12975 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12976 && !COMMUTATIVE_ARITH_P (operands[3])
12977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12978 "* return output_387_binary_op (insn, operands);"
12979 [(set (attr "type")
12980 (cond [(and (eq_attr "alternative" "2,3")
12981 (match_operand:MODEF 3 "mult_operator" ""))
12982 (const_string "ssemul")
12983 (and (eq_attr "alternative" "2,3")
12984 (match_operand:MODEF 3 "div_operator" ""))
12985 (const_string "ssediv")
12986 (eq_attr "alternative" "2,3")
12987 (const_string "sseadd")
12988 (match_operand:MODEF 3 "mult_operator" "")
12989 (const_string "fmul")
12990 (match_operand:MODEF 3 "div_operator" "")
12991 (const_string "fdiv")
12992 ]
12993 (const_string "fop")))
12994 (set_attr "isa" "*,*,noavx,avx")
12995 (set_attr "prefix" "orig,orig,orig,vex")
12996 (set_attr "mode" "<MODE>")])
12997
12998 (define_insn "*rcpsf2_sse"
12999 [(set (match_operand:SF 0 "register_operand" "=x")
13000 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13001 UNSPEC_RCP))]
13002 "TARGET_SSE_MATH"
13003 "%vrcpss\t{%1, %d0|%d0, %1}"
13004 [(set_attr "type" "sse")
13005 (set_attr "atom_sse_attr" "rcp")
13006 (set_attr "prefix" "maybe_vex")
13007 (set_attr "mode" "SF")])
13008
13009 (define_insn "*fop_<mode>_1_sse"
13010 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13011 (match_operator:MODEF 3 "binary_fp_operator"
13012 [(match_operand:MODEF 1 "register_operand" "0,x")
13013 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13014 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13015 && !COMMUTATIVE_ARITH_P (operands[3])"
13016 "* return output_387_binary_op (insn, operands);"
13017 [(set (attr "type")
13018 (cond [(match_operand:MODEF 3 "mult_operator" "")
13019 (const_string "ssemul")
13020 (match_operand:MODEF 3 "div_operator" "")
13021 (const_string "ssediv")
13022 ]
13023 (const_string "sseadd")))
13024 (set_attr "isa" "noavx,avx")
13025 (set_attr "prefix" "orig,vex")
13026 (set_attr "mode" "<MODE>")])
13027
13028 ;; This pattern is not fully shadowed by the pattern above.
13029 (define_insn "*fop_<mode>_1_i387"
13030 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13031 (match_operator:MODEF 3 "binary_fp_operator"
13032 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13033 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13034 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13035 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13036 && !COMMUTATIVE_ARITH_P (operands[3])
13037 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13038 "* return output_387_binary_op (insn, operands);"
13039 [(set (attr "type")
13040 (cond [(match_operand:MODEF 3 "mult_operator" "")
13041 (const_string "fmul")
13042 (match_operand:MODEF 3 "div_operator" "")
13043 (const_string "fdiv")
13044 ]
13045 (const_string "fop")))
13046 (set_attr "mode" "<MODE>")])
13047
13048 ;; ??? Add SSE splitters for these!
13049 (define_insn "*fop_<MODEF:mode>_2_i387"
13050 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13051 (match_operator:MODEF 3 "binary_fp_operator"
13052 [(float:MODEF
13053 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13054 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13055 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13056 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13057 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13058 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13059 [(set (attr "type")
13060 (cond [(match_operand:MODEF 3 "mult_operator" "")
13061 (const_string "fmul")
13062 (match_operand:MODEF 3 "div_operator" "")
13063 (const_string "fdiv")
13064 ]
13065 (const_string "fop")))
13066 (set_attr "fp_int_src" "true")
13067 (set_attr "mode" "<SWI24:MODE>")])
13068
13069 (define_insn "*fop_<MODEF:mode>_3_i387"
13070 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13071 (match_operator:MODEF 3 "binary_fp_operator"
13072 [(match_operand:MODEF 1 "register_operand" "0,0")
13073 (float:MODEF
13074 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13075 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13076 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13077 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13078 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13079 [(set (attr "type")
13080 (cond [(match_operand:MODEF 3 "mult_operator" "")
13081 (const_string "fmul")
13082 (match_operand:MODEF 3 "div_operator" "")
13083 (const_string "fdiv")
13084 ]
13085 (const_string "fop")))
13086 (set_attr "fp_int_src" "true")
13087 (set_attr "mode" "<MODE>")])
13088
13089 (define_insn "*fop_df_4_i387"
13090 [(set (match_operand:DF 0 "register_operand" "=f,f")
13091 (match_operator:DF 3 "binary_fp_operator"
13092 [(float_extend:DF
13093 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13094 (match_operand:DF 2 "register_operand" "0,f")]))]
13095 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13096 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13097 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13098 "* return output_387_binary_op (insn, operands);"
13099 [(set (attr "type")
13100 (cond [(match_operand:DF 3 "mult_operator" "")
13101 (const_string "fmul")
13102 (match_operand:DF 3 "div_operator" "")
13103 (const_string "fdiv")
13104 ]
13105 (const_string "fop")))
13106 (set_attr "mode" "SF")])
13107
13108 (define_insn "*fop_df_5_i387"
13109 [(set (match_operand:DF 0 "register_operand" "=f,f")
13110 (match_operator:DF 3 "binary_fp_operator"
13111 [(match_operand:DF 1 "register_operand" "0,f")
13112 (float_extend:DF
13113 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13114 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13115 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13116 "* return output_387_binary_op (insn, operands);"
13117 [(set (attr "type")
13118 (cond [(match_operand:DF 3 "mult_operator" "")
13119 (const_string "fmul")
13120 (match_operand:DF 3 "div_operator" "")
13121 (const_string "fdiv")
13122 ]
13123 (const_string "fop")))
13124 (set_attr "mode" "SF")])
13125
13126 (define_insn "*fop_df_6_i387"
13127 [(set (match_operand:DF 0 "register_operand" "=f,f")
13128 (match_operator:DF 3 "binary_fp_operator"
13129 [(float_extend:DF
13130 (match_operand:SF 1 "register_operand" "0,f"))
13131 (float_extend:DF
13132 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13133 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13134 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13135 "* return output_387_binary_op (insn, operands);"
13136 [(set (attr "type")
13137 (cond [(match_operand:DF 3 "mult_operator" "")
13138 (const_string "fmul")
13139 (match_operand:DF 3 "div_operator" "")
13140 (const_string "fdiv")
13141 ]
13142 (const_string "fop")))
13143 (set_attr "mode" "SF")])
13144
13145 (define_insn "*fop_xf_comm_i387"
13146 [(set (match_operand:XF 0 "register_operand" "=f")
13147 (match_operator:XF 3 "binary_fp_operator"
13148 [(match_operand:XF 1 "register_operand" "%0")
13149 (match_operand:XF 2 "register_operand" "f")]))]
13150 "TARGET_80387
13151 && COMMUTATIVE_ARITH_P (operands[3])"
13152 "* return output_387_binary_op (insn, operands);"
13153 [(set (attr "type")
13154 (if_then_else (match_operand:XF 3 "mult_operator" "")
13155 (const_string "fmul")
13156 (const_string "fop")))
13157 (set_attr "mode" "XF")])
13158
13159 (define_insn "*fop_xf_1_i387"
13160 [(set (match_operand:XF 0 "register_operand" "=f,f")
13161 (match_operator:XF 3 "binary_fp_operator"
13162 [(match_operand:XF 1 "register_operand" "0,f")
13163 (match_operand:XF 2 "register_operand" "f,0")]))]
13164 "TARGET_80387
13165 && !COMMUTATIVE_ARITH_P (operands[3])"
13166 "* return output_387_binary_op (insn, operands);"
13167 [(set (attr "type")
13168 (cond [(match_operand:XF 3 "mult_operator" "")
13169 (const_string "fmul")
13170 (match_operand:XF 3 "div_operator" "")
13171 (const_string "fdiv")
13172 ]
13173 (const_string "fop")))
13174 (set_attr "mode" "XF")])
13175
13176 (define_insn "*fop_xf_2_i387"
13177 [(set (match_operand:XF 0 "register_operand" "=f,f")
13178 (match_operator:XF 3 "binary_fp_operator"
13179 [(float:XF
13180 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13181 (match_operand:XF 2 "register_operand" "0,0")]))]
13182 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13183 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13184 [(set (attr "type")
13185 (cond [(match_operand:XF 3 "mult_operator" "")
13186 (const_string "fmul")
13187 (match_operand:XF 3 "div_operator" "")
13188 (const_string "fdiv")
13189 ]
13190 (const_string "fop")))
13191 (set_attr "fp_int_src" "true")
13192 (set_attr "mode" "<MODE>")])
13193
13194 (define_insn "*fop_xf_3_i387"
13195 [(set (match_operand:XF 0 "register_operand" "=f,f")
13196 (match_operator:XF 3 "binary_fp_operator"
13197 [(match_operand:XF 1 "register_operand" "0,0")
13198 (float:XF
13199 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13200 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13201 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13202 [(set (attr "type")
13203 (cond [(match_operand:XF 3 "mult_operator" "")
13204 (const_string "fmul")
13205 (match_operand:XF 3 "div_operator" "")
13206 (const_string "fdiv")
13207 ]
13208 (const_string "fop")))
13209 (set_attr "fp_int_src" "true")
13210 (set_attr "mode" "<MODE>")])
13211
13212 (define_insn "*fop_xf_4_i387"
13213 [(set (match_operand:XF 0 "register_operand" "=f,f")
13214 (match_operator:XF 3 "binary_fp_operator"
13215 [(float_extend:XF
13216 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13217 (match_operand:XF 2 "register_operand" "0,f")]))]
13218 "TARGET_80387"
13219 "* return output_387_binary_op (insn, operands);"
13220 [(set (attr "type")
13221 (cond [(match_operand:XF 3 "mult_operator" "")
13222 (const_string "fmul")
13223 (match_operand:XF 3 "div_operator" "")
13224 (const_string "fdiv")
13225 ]
13226 (const_string "fop")))
13227 (set_attr "mode" "<MODE>")])
13228
13229 (define_insn "*fop_xf_5_i387"
13230 [(set (match_operand:XF 0 "register_operand" "=f,f")
13231 (match_operator:XF 3 "binary_fp_operator"
13232 [(match_operand:XF 1 "register_operand" "0,f")
13233 (float_extend:XF
13234 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13235 "TARGET_80387"
13236 "* return output_387_binary_op (insn, operands);"
13237 [(set (attr "type")
13238 (cond [(match_operand:XF 3 "mult_operator" "")
13239 (const_string "fmul")
13240 (match_operand:XF 3 "div_operator" "")
13241 (const_string "fdiv")
13242 ]
13243 (const_string "fop")))
13244 (set_attr "mode" "<MODE>")])
13245
13246 (define_insn "*fop_xf_6_i387"
13247 [(set (match_operand:XF 0 "register_operand" "=f,f")
13248 (match_operator:XF 3 "binary_fp_operator"
13249 [(float_extend:XF
13250 (match_operand:MODEF 1 "register_operand" "0,f"))
13251 (float_extend:XF
13252 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13253 "TARGET_80387"
13254 "* return output_387_binary_op (insn, operands);"
13255 [(set (attr "type")
13256 (cond [(match_operand:XF 3 "mult_operator" "")
13257 (const_string "fmul")
13258 (match_operand:XF 3 "div_operator" "")
13259 (const_string "fdiv")
13260 ]
13261 (const_string "fop")))
13262 (set_attr "mode" "<MODE>")])
13263
13264 (define_split
13265 [(set (match_operand 0 "register_operand" "")
13266 (match_operator 3 "binary_fp_operator"
13267 [(float (match_operand:SWI24 1 "register_operand" ""))
13268 (match_operand 2 "register_operand" "")]))]
13269 "reload_completed
13270 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13271 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13272 [(const_int 0)]
13273 {
13274 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13275 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13276 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13277 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13278 GET_MODE (operands[3]),
13279 operands[4],
13280 operands[2])));
13281 ix86_free_from_memory (GET_MODE (operands[1]));
13282 DONE;
13283 })
13284
13285 (define_split
13286 [(set (match_operand 0 "register_operand" "")
13287 (match_operator 3 "binary_fp_operator"
13288 [(match_operand 1 "register_operand" "")
13289 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13290 "reload_completed
13291 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13292 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13293 [(const_int 0)]
13294 {
13295 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13296 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13297 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13298 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13299 GET_MODE (operands[3]),
13300 operands[1],
13301 operands[4])));
13302 ix86_free_from_memory (GET_MODE (operands[2]));
13303 DONE;
13304 })
13305 \f
13306 ;; FPU special functions.
13307
13308 ;; This pattern implements a no-op XFmode truncation for
13309 ;; all fancy i386 XFmode math functions.
13310
13311 (define_insn "truncxf<mode>2_i387_noop_unspec"
13312 [(set (match_operand:MODEF 0 "register_operand" "=f")
13313 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13314 UNSPEC_TRUNC_NOOP))]
13315 "TARGET_USE_FANCY_MATH_387"
13316 "* return output_387_reg_move (insn, operands);"
13317 [(set_attr "type" "fmov")
13318 (set_attr "mode" "<MODE>")])
13319
13320 (define_insn "sqrtxf2"
13321 [(set (match_operand:XF 0 "register_operand" "=f")
13322 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13323 "TARGET_USE_FANCY_MATH_387"
13324 "fsqrt"
13325 [(set_attr "type" "fpspc")
13326 (set_attr "mode" "XF")
13327 (set_attr "athlon_decode" "direct")
13328 (set_attr "amdfam10_decode" "direct")
13329 (set_attr "bdver1_decode" "direct")])
13330
13331 (define_insn "sqrt_extend<mode>xf2_i387"
13332 [(set (match_operand:XF 0 "register_operand" "=f")
13333 (sqrt:XF
13334 (float_extend:XF
13335 (match_operand:MODEF 1 "register_operand" "0"))))]
13336 "TARGET_USE_FANCY_MATH_387"
13337 "fsqrt"
13338 [(set_attr "type" "fpspc")
13339 (set_attr "mode" "XF")
13340 (set_attr "athlon_decode" "direct")
13341 (set_attr "amdfam10_decode" "direct")
13342 (set_attr "bdver1_decode" "direct")])
13343
13344 (define_insn "*rsqrtsf2_sse"
13345 [(set (match_operand:SF 0 "register_operand" "=x")
13346 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13347 UNSPEC_RSQRT))]
13348 "TARGET_SSE_MATH"
13349 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13350 [(set_attr "type" "sse")
13351 (set_attr "atom_sse_attr" "rcp")
13352 (set_attr "prefix" "maybe_vex")
13353 (set_attr "mode" "SF")])
13354
13355 (define_expand "rsqrtsf2"
13356 [(set (match_operand:SF 0 "register_operand" "")
13357 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13358 UNSPEC_RSQRT))]
13359 "TARGET_SSE_MATH"
13360 {
13361 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13362 DONE;
13363 })
13364
13365 (define_insn "*sqrt<mode>2_sse"
13366 [(set (match_operand:MODEF 0 "register_operand" "=x")
13367 (sqrt:MODEF
13368 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13369 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13370 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13371 [(set_attr "type" "sse")
13372 (set_attr "atom_sse_attr" "sqrt")
13373 (set_attr "prefix" "maybe_vex")
13374 (set_attr "mode" "<MODE>")
13375 (set_attr "athlon_decode" "*")
13376 (set_attr "amdfam10_decode" "*")
13377 (set_attr "bdver1_decode" "*")])
13378
13379 (define_expand "sqrt<mode>2"
13380 [(set (match_operand:MODEF 0 "register_operand" "")
13381 (sqrt:MODEF
13382 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13383 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13384 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13385 {
13386 if (<MODE>mode == SFmode
13387 && TARGET_SSE_MATH
13388 && TARGET_RECIP_SQRT
13389 && !optimize_function_for_size_p (cfun)
13390 && flag_finite_math_only && !flag_trapping_math
13391 && flag_unsafe_math_optimizations)
13392 {
13393 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13394 DONE;
13395 }
13396
13397 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13398 {
13399 rtx op0 = gen_reg_rtx (XFmode);
13400 rtx op1 = force_reg (<MODE>mode, operands[1]);
13401
13402 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13403 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13404 DONE;
13405 }
13406 })
13407
13408 (define_insn "fpremxf4_i387"
13409 [(set (match_operand:XF 0 "register_operand" "=f")
13410 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13411 (match_operand:XF 3 "register_operand" "1")]
13412 UNSPEC_FPREM_F))
13413 (set (match_operand:XF 1 "register_operand" "=u")
13414 (unspec:XF [(match_dup 2) (match_dup 3)]
13415 UNSPEC_FPREM_U))
13416 (set (reg:CCFP FPSR_REG)
13417 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13418 UNSPEC_C2_FLAG))]
13419 "TARGET_USE_FANCY_MATH_387"
13420 "fprem"
13421 [(set_attr "type" "fpspc")
13422 (set_attr "mode" "XF")])
13423
13424 (define_expand "fmodxf3"
13425 [(use (match_operand:XF 0 "register_operand" ""))
13426 (use (match_operand:XF 1 "general_operand" ""))
13427 (use (match_operand:XF 2 "general_operand" ""))]
13428 "TARGET_USE_FANCY_MATH_387"
13429 {
13430 rtx label = gen_label_rtx ();
13431
13432 rtx op1 = gen_reg_rtx (XFmode);
13433 rtx op2 = gen_reg_rtx (XFmode);
13434
13435 emit_move_insn (op2, operands[2]);
13436 emit_move_insn (op1, operands[1]);
13437
13438 emit_label (label);
13439 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13440 ix86_emit_fp_unordered_jump (label);
13441 LABEL_NUSES (label) = 1;
13442
13443 emit_move_insn (operands[0], op1);
13444 DONE;
13445 })
13446
13447 (define_expand "fmod<mode>3"
13448 [(use (match_operand:MODEF 0 "register_operand" ""))
13449 (use (match_operand:MODEF 1 "general_operand" ""))
13450 (use (match_operand:MODEF 2 "general_operand" ""))]
13451 "TARGET_USE_FANCY_MATH_387"
13452 {
13453 rtx (*gen_truncxf) (rtx, rtx);
13454
13455 rtx label = gen_label_rtx ();
13456
13457 rtx op1 = gen_reg_rtx (XFmode);
13458 rtx op2 = gen_reg_rtx (XFmode);
13459
13460 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13461 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13462
13463 emit_label (label);
13464 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13465 ix86_emit_fp_unordered_jump (label);
13466 LABEL_NUSES (label) = 1;
13467
13468 /* Truncate the result properly for strict SSE math. */
13469 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13470 && !TARGET_MIX_SSE_I387)
13471 gen_truncxf = gen_truncxf<mode>2;
13472 else
13473 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13474
13475 emit_insn (gen_truncxf (operands[0], op1));
13476 DONE;
13477 })
13478
13479 (define_insn "fprem1xf4_i387"
13480 [(set (match_operand:XF 0 "register_operand" "=f")
13481 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13482 (match_operand:XF 3 "register_operand" "1")]
13483 UNSPEC_FPREM1_F))
13484 (set (match_operand:XF 1 "register_operand" "=u")
13485 (unspec:XF [(match_dup 2) (match_dup 3)]
13486 UNSPEC_FPREM1_U))
13487 (set (reg:CCFP FPSR_REG)
13488 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13489 UNSPEC_C2_FLAG))]
13490 "TARGET_USE_FANCY_MATH_387"
13491 "fprem1"
13492 [(set_attr "type" "fpspc")
13493 (set_attr "mode" "XF")])
13494
13495 (define_expand "remainderxf3"
13496 [(use (match_operand:XF 0 "register_operand" ""))
13497 (use (match_operand:XF 1 "general_operand" ""))
13498 (use (match_operand:XF 2 "general_operand" ""))]
13499 "TARGET_USE_FANCY_MATH_387"
13500 {
13501 rtx label = gen_label_rtx ();
13502
13503 rtx op1 = gen_reg_rtx (XFmode);
13504 rtx op2 = gen_reg_rtx (XFmode);
13505
13506 emit_move_insn (op2, operands[2]);
13507 emit_move_insn (op1, operands[1]);
13508
13509 emit_label (label);
13510 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13511 ix86_emit_fp_unordered_jump (label);
13512 LABEL_NUSES (label) = 1;
13513
13514 emit_move_insn (operands[0], op1);
13515 DONE;
13516 })
13517
13518 (define_expand "remainder<mode>3"
13519 [(use (match_operand:MODEF 0 "register_operand" ""))
13520 (use (match_operand:MODEF 1 "general_operand" ""))
13521 (use (match_operand:MODEF 2 "general_operand" ""))]
13522 "TARGET_USE_FANCY_MATH_387"
13523 {
13524 rtx (*gen_truncxf) (rtx, rtx);
13525
13526 rtx label = gen_label_rtx ();
13527
13528 rtx op1 = gen_reg_rtx (XFmode);
13529 rtx op2 = gen_reg_rtx (XFmode);
13530
13531 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13532 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13533
13534 emit_label (label);
13535
13536 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13537 ix86_emit_fp_unordered_jump (label);
13538 LABEL_NUSES (label) = 1;
13539
13540 /* Truncate the result properly for strict SSE math. */
13541 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13542 && !TARGET_MIX_SSE_I387)
13543 gen_truncxf = gen_truncxf<mode>2;
13544 else
13545 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13546
13547 emit_insn (gen_truncxf (operands[0], op1));
13548 DONE;
13549 })
13550
13551 (define_insn "*sinxf2_i387"
13552 [(set (match_operand:XF 0 "register_operand" "=f")
13553 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13554 "TARGET_USE_FANCY_MATH_387
13555 && flag_unsafe_math_optimizations"
13556 "fsin"
13557 [(set_attr "type" "fpspc")
13558 (set_attr "mode" "XF")])
13559
13560 (define_insn "*sin_extend<mode>xf2_i387"
13561 [(set (match_operand:XF 0 "register_operand" "=f")
13562 (unspec:XF [(float_extend:XF
13563 (match_operand:MODEF 1 "register_operand" "0"))]
13564 UNSPEC_SIN))]
13565 "TARGET_USE_FANCY_MATH_387
13566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13567 || TARGET_MIX_SSE_I387)
13568 && flag_unsafe_math_optimizations"
13569 "fsin"
13570 [(set_attr "type" "fpspc")
13571 (set_attr "mode" "XF")])
13572
13573 (define_insn "*cosxf2_i387"
13574 [(set (match_operand:XF 0 "register_operand" "=f")
13575 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13576 "TARGET_USE_FANCY_MATH_387
13577 && flag_unsafe_math_optimizations"
13578 "fcos"
13579 [(set_attr "type" "fpspc")
13580 (set_attr "mode" "XF")])
13581
13582 (define_insn "*cos_extend<mode>xf2_i387"
13583 [(set (match_operand:XF 0 "register_operand" "=f")
13584 (unspec:XF [(float_extend:XF
13585 (match_operand:MODEF 1 "register_operand" "0"))]
13586 UNSPEC_COS))]
13587 "TARGET_USE_FANCY_MATH_387
13588 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13589 || TARGET_MIX_SSE_I387)
13590 && flag_unsafe_math_optimizations"
13591 "fcos"
13592 [(set_attr "type" "fpspc")
13593 (set_attr "mode" "XF")])
13594
13595 ;; When sincos pattern is defined, sin and cos builtin functions will be
13596 ;; expanded to sincos pattern with one of its outputs left unused.
13597 ;; CSE pass will figure out if two sincos patterns can be combined,
13598 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13599 ;; depending on the unused output.
13600
13601 (define_insn "sincosxf3"
13602 [(set (match_operand:XF 0 "register_operand" "=f")
13603 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13604 UNSPEC_SINCOS_COS))
13605 (set (match_operand:XF 1 "register_operand" "=u")
13606 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13607 "TARGET_USE_FANCY_MATH_387
13608 && flag_unsafe_math_optimizations"
13609 "fsincos"
13610 [(set_attr "type" "fpspc")
13611 (set_attr "mode" "XF")])
13612
13613 (define_split
13614 [(set (match_operand:XF 0 "register_operand" "")
13615 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13616 UNSPEC_SINCOS_COS))
13617 (set (match_operand:XF 1 "register_operand" "")
13618 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13619 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13620 && can_create_pseudo_p ()"
13621 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13622
13623 (define_split
13624 [(set (match_operand:XF 0 "register_operand" "")
13625 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13626 UNSPEC_SINCOS_COS))
13627 (set (match_operand:XF 1 "register_operand" "")
13628 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13629 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13630 && can_create_pseudo_p ()"
13631 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13632
13633 (define_insn "sincos_extend<mode>xf3_i387"
13634 [(set (match_operand:XF 0 "register_operand" "=f")
13635 (unspec:XF [(float_extend:XF
13636 (match_operand:MODEF 2 "register_operand" "0"))]
13637 UNSPEC_SINCOS_COS))
13638 (set (match_operand:XF 1 "register_operand" "=u")
13639 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13640 "TARGET_USE_FANCY_MATH_387
13641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13642 || TARGET_MIX_SSE_I387)
13643 && flag_unsafe_math_optimizations"
13644 "fsincos"
13645 [(set_attr "type" "fpspc")
13646 (set_attr "mode" "XF")])
13647
13648 (define_split
13649 [(set (match_operand:XF 0 "register_operand" "")
13650 (unspec:XF [(float_extend:XF
13651 (match_operand:MODEF 2 "register_operand" ""))]
13652 UNSPEC_SINCOS_COS))
13653 (set (match_operand:XF 1 "register_operand" "")
13654 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13655 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13656 && can_create_pseudo_p ()"
13657 [(set (match_dup 1)
13658 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13659
13660 (define_split
13661 [(set (match_operand:XF 0 "register_operand" "")
13662 (unspec:XF [(float_extend:XF
13663 (match_operand:MODEF 2 "register_operand" ""))]
13664 UNSPEC_SINCOS_COS))
13665 (set (match_operand:XF 1 "register_operand" "")
13666 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13667 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13668 && can_create_pseudo_p ()"
13669 [(set (match_dup 0)
13670 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13671
13672 (define_expand "sincos<mode>3"
13673 [(use (match_operand:MODEF 0 "register_operand" ""))
13674 (use (match_operand:MODEF 1 "register_operand" ""))
13675 (use (match_operand:MODEF 2 "register_operand" ""))]
13676 "TARGET_USE_FANCY_MATH_387
13677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13678 || TARGET_MIX_SSE_I387)
13679 && flag_unsafe_math_optimizations"
13680 {
13681 rtx op0 = gen_reg_rtx (XFmode);
13682 rtx op1 = gen_reg_rtx (XFmode);
13683
13684 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13685 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13686 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13687 DONE;
13688 })
13689
13690 (define_insn "fptanxf4_i387"
13691 [(set (match_operand:XF 0 "register_operand" "=f")
13692 (match_operand:XF 3 "const_double_operand" "F"))
13693 (set (match_operand:XF 1 "register_operand" "=u")
13694 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13695 UNSPEC_TAN))]
13696 "TARGET_USE_FANCY_MATH_387
13697 && flag_unsafe_math_optimizations
13698 && standard_80387_constant_p (operands[3]) == 2"
13699 "fptan"
13700 [(set_attr "type" "fpspc")
13701 (set_attr "mode" "XF")])
13702
13703 (define_insn "fptan_extend<mode>xf4_i387"
13704 [(set (match_operand:MODEF 0 "register_operand" "=f")
13705 (match_operand:MODEF 3 "const_double_operand" "F"))
13706 (set (match_operand:XF 1 "register_operand" "=u")
13707 (unspec:XF [(float_extend:XF
13708 (match_operand:MODEF 2 "register_operand" "0"))]
13709 UNSPEC_TAN))]
13710 "TARGET_USE_FANCY_MATH_387
13711 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13712 || TARGET_MIX_SSE_I387)
13713 && flag_unsafe_math_optimizations
13714 && standard_80387_constant_p (operands[3]) == 2"
13715 "fptan"
13716 [(set_attr "type" "fpspc")
13717 (set_attr "mode" "XF")])
13718
13719 (define_expand "tanxf2"
13720 [(use (match_operand:XF 0 "register_operand" ""))
13721 (use (match_operand:XF 1 "register_operand" ""))]
13722 "TARGET_USE_FANCY_MATH_387
13723 && flag_unsafe_math_optimizations"
13724 {
13725 rtx one = gen_reg_rtx (XFmode);
13726 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13727
13728 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13729 DONE;
13730 })
13731
13732 (define_expand "tan<mode>2"
13733 [(use (match_operand:MODEF 0 "register_operand" ""))
13734 (use (match_operand:MODEF 1 "register_operand" ""))]
13735 "TARGET_USE_FANCY_MATH_387
13736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13737 || TARGET_MIX_SSE_I387)
13738 && flag_unsafe_math_optimizations"
13739 {
13740 rtx op0 = gen_reg_rtx (XFmode);
13741
13742 rtx one = gen_reg_rtx (<MODE>mode);
13743 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13744
13745 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13746 operands[1], op2));
13747 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13748 DONE;
13749 })
13750
13751 (define_insn "*fpatanxf3_i387"
13752 [(set (match_operand:XF 0 "register_operand" "=f")
13753 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13754 (match_operand:XF 2 "register_operand" "u")]
13755 UNSPEC_FPATAN))
13756 (clobber (match_scratch:XF 3 "=2"))]
13757 "TARGET_USE_FANCY_MATH_387
13758 && flag_unsafe_math_optimizations"
13759 "fpatan"
13760 [(set_attr "type" "fpspc")
13761 (set_attr "mode" "XF")])
13762
13763 (define_insn "fpatan_extend<mode>xf3_i387"
13764 [(set (match_operand:XF 0 "register_operand" "=f")
13765 (unspec:XF [(float_extend:XF
13766 (match_operand:MODEF 1 "register_operand" "0"))
13767 (float_extend:XF
13768 (match_operand:MODEF 2 "register_operand" "u"))]
13769 UNSPEC_FPATAN))
13770 (clobber (match_scratch:XF 3 "=2"))]
13771 "TARGET_USE_FANCY_MATH_387
13772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13773 || TARGET_MIX_SSE_I387)
13774 && flag_unsafe_math_optimizations"
13775 "fpatan"
13776 [(set_attr "type" "fpspc")
13777 (set_attr "mode" "XF")])
13778
13779 (define_expand "atan2xf3"
13780 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13781 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13782 (match_operand:XF 1 "register_operand" "")]
13783 UNSPEC_FPATAN))
13784 (clobber (match_scratch:XF 3 ""))])]
13785 "TARGET_USE_FANCY_MATH_387
13786 && flag_unsafe_math_optimizations")
13787
13788 (define_expand "atan2<mode>3"
13789 [(use (match_operand:MODEF 0 "register_operand" ""))
13790 (use (match_operand:MODEF 1 "register_operand" ""))
13791 (use (match_operand:MODEF 2 "register_operand" ""))]
13792 "TARGET_USE_FANCY_MATH_387
13793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13794 || TARGET_MIX_SSE_I387)
13795 && flag_unsafe_math_optimizations"
13796 {
13797 rtx op0 = gen_reg_rtx (XFmode);
13798
13799 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13800 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13801 DONE;
13802 })
13803
13804 (define_expand "atanxf2"
13805 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13806 (unspec:XF [(match_dup 2)
13807 (match_operand:XF 1 "register_operand" "")]
13808 UNSPEC_FPATAN))
13809 (clobber (match_scratch:XF 3 ""))])]
13810 "TARGET_USE_FANCY_MATH_387
13811 && flag_unsafe_math_optimizations"
13812 {
13813 operands[2] = gen_reg_rtx (XFmode);
13814 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13815 })
13816
13817 (define_expand "atan<mode>2"
13818 [(use (match_operand:MODEF 0 "register_operand" ""))
13819 (use (match_operand:MODEF 1 "register_operand" ""))]
13820 "TARGET_USE_FANCY_MATH_387
13821 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13822 || TARGET_MIX_SSE_I387)
13823 && flag_unsafe_math_optimizations"
13824 {
13825 rtx op0 = gen_reg_rtx (XFmode);
13826
13827 rtx op2 = gen_reg_rtx (<MODE>mode);
13828 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13829
13830 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13832 DONE;
13833 })
13834
13835 (define_expand "asinxf2"
13836 [(set (match_dup 2)
13837 (mult:XF (match_operand:XF 1 "register_operand" "")
13838 (match_dup 1)))
13839 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13840 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13841 (parallel [(set (match_operand:XF 0 "register_operand" "")
13842 (unspec:XF [(match_dup 5) (match_dup 1)]
13843 UNSPEC_FPATAN))
13844 (clobber (match_scratch:XF 6 ""))])]
13845 "TARGET_USE_FANCY_MATH_387
13846 && flag_unsafe_math_optimizations"
13847 {
13848 int i;
13849
13850 if (optimize_insn_for_size_p ())
13851 FAIL;
13852
13853 for (i = 2; i < 6; i++)
13854 operands[i] = gen_reg_rtx (XFmode);
13855
13856 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13857 })
13858
13859 (define_expand "asin<mode>2"
13860 [(use (match_operand:MODEF 0 "register_operand" ""))
13861 (use (match_operand:MODEF 1 "general_operand" ""))]
13862 "TARGET_USE_FANCY_MATH_387
13863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13864 || TARGET_MIX_SSE_I387)
13865 && flag_unsafe_math_optimizations"
13866 {
13867 rtx op0 = gen_reg_rtx (XFmode);
13868 rtx op1 = gen_reg_rtx (XFmode);
13869
13870 if (optimize_insn_for_size_p ())
13871 FAIL;
13872
13873 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13874 emit_insn (gen_asinxf2 (op0, op1));
13875 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13876 DONE;
13877 })
13878
13879 (define_expand "acosxf2"
13880 [(set (match_dup 2)
13881 (mult:XF (match_operand:XF 1 "register_operand" "")
13882 (match_dup 1)))
13883 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13884 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13885 (parallel [(set (match_operand:XF 0 "register_operand" "")
13886 (unspec:XF [(match_dup 1) (match_dup 5)]
13887 UNSPEC_FPATAN))
13888 (clobber (match_scratch:XF 6 ""))])]
13889 "TARGET_USE_FANCY_MATH_387
13890 && flag_unsafe_math_optimizations"
13891 {
13892 int i;
13893
13894 if (optimize_insn_for_size_p ())
13895 FAIL;
13896
13897 for (i = 2; i < 6; i++)
13898 operands[i] = gen_reg_rtx (XFmode);
13899
13900 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13901 })
13902
13903 (define_expand "acos<mode>2"
13904 [(use (match_operand:MODEF 0 "register_operand" ""))
13905 (use (match_operand:MODEF 1 "general_operand" ""))]
13906 "TARGET_USE_FANCY_MATH_387
13907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13908 || TARGET_MIX_SSE_I387)
13909 && flag_unsafe_math_optimizations"
13910 {
13911 rtx op0 = gen_reg_rtx (XFmode);
13912 rtx op1 = gen_reg_rtx (XFmode);
13913
13914 if (optimize_insn_for_size_p ())
13915 FAIL;
13916
13917 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13918 emit_insn (gen_acosxf2 (op0, op1));
13919 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13920 DONE;
13921 })
13922
13923 (define_insn "fyl2xxf3_i387"
13924 [(set (match_operand:XF 0 "register_operand" "=f")
13925 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13926 (match_operand:XF 2 "register_operand" "u")]
13927 UNSPEC_FYL2X))
13928 (clobber (match_scratch:XF 3 "=2"))]
13929 "TARGET_USE_FANCY_MATH_387
13930 && flag_unsafe_math_optimizations"
13931 "fyl2x"
13932 [(set_attr "type" "fpspc")
13933 (set_attr "mode" "XF")])
13934
13935 (define_insn "fyl2x_extend<mode>xf3_i387"
13936 [(set (match_operand:XF 0 "register_operand" "=f")
13937 (unspec:XF [(float_extend:XF
13938 (match_operand:MODEF 1 "register_operand" "0"))
13939 (match_operand:XF 2 "register_operand" "u")]
13940 UNSPEC_FYL2X))
13941 (clobber (match_scratch:XF 3 "=2"))]
13942 "TARGET_USE_FANCY_MATH_387
13943 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13944 || TARGET_MIX_SSE_I387)
13945 && flag_unsafe_math_optimizations"
13946 "fyl2x"
13947 [(set_attr "type" "fpspc")
13948 (set_attr "mode" "XF")])
13949
13950 (define_expand "logxf2"
13951 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13952 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13953 (match_dup 2)] UNSPEC_FYL2X))
13954 (clobber (match_scratch:XF 3 ""))])]
13955 "TARGET_USE_FANCY_MATH_387
13956 && flag_unsafe_math_optimizations"
13957 {
13958 operands[2] = gen_reg_rtx (XFmode);
13959 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13960 })
13961
13962 (define_expand "log<mode>2"
13963 [(use (match_operand:MODEF 0 "register_operand" ""))
13964 (use (match_operand:MODEF 1 "register_operand" ""))]
13965 "TARGET_USE_FANCY_MATH_387
13966 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13967 || TARGET_MIX_SSE_I387)
13968 && flag_unsafe_math_optimizations"
13969 {
13970 rtx op0 = gen_reg_rtx (XFmode);
13971
13972 rtx op2 = gen_reg_rtx (XFmode);
13973 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13974
13975 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13976 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13977 DONE;
13978 })
13979
13980 (define_expand "log10xf2"
13981 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13982 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13983 (match_dup 2)] UNSPEC_FYL2X))
13984 (clobber (match_scratch:XF 3 ""))])]
13985 "TARGET_USE_FANCY_MATH_387
13986 && flag_unsafe_math_optimizations"
13987 {
13988 operands[2] = gen_reg_rtx (XFmode);
13989 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13990 })
13991
13992 (define_expand "log10<mode>2"
13993 [(use (match_operand:MODEF 0 "register_operand" ""))
13994 (use (match_operand:MODEF 1 "register_operand" ""))]
13995 "TARGET_USE_FANCY_MATH_387
13996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997 || TARGET_MIX_SSE_I387)
13998 && flag_unsafe_math_optimizations"
13999 {
14000 rtx op0 = gen_reg_rtx (XFmode);
14001
14002 rtx op2 = gen_reg_rtx (XFmode);
14003 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14004
14005 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14006 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14007 DONE;
14008 })
14009
14010 (define_expand "log2xf2"
14011 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14012 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14013 (match_dup 2)] UNSPEC_FYL2X))
14014 (clobber (match_scratch:XF 3 ""))])]
14015 "TARGET_USE_FANCY_MATH_387
14016 && flag_unsafe_math_optimizations"
14017 {
14018 operands[2] = gen_reg_rtx (XFmode);
14019 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14020 })
14021
14022 (define_expand "log2<mode>2"
14023 [(use (match_operand:MODEF 0 "register_operand" ""))
14024 (use (match_operand:MODEF 1 "register_operand" ""))]
14025 "TARGET_USE_FANCY_MATH_387
14026 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14027 || TARGET_MIX_SSE_I387)
14028 && flag_unsafe_math_optimizations"
14029 {
14030 rtx op0 = gen_reg_rtx (XFmode);
14031
14032 rtx op2 = gen_reg_rtx (XFmode);
14033 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14034
14035 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14036 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14037 DONE;
14038 })
14039
14040 (define_insn "fyl2xp1xf3_i387"
14041 [(set (match_operand:XF 0 "register_operand" "=f")
14042 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14043 (match_operand:XF 2 "register_operand" "u")]
14044 UNSPEC_FYL2XP1))
14045 (clobber (match_scratch:XF 3 "=2"))]
14046 "TARGET_USE_FANCY_MATH_387
14047 && flag_unsafe_math_optimizations"
14048 "fyl2xp1"
14049 [(set_attr "type" "fpspc")
14050 (set_attr "mode" "XF")])
14051
14052 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14053 [(set (match_operand:XF 0 "register_operand" "=f")
14054 (unspec:XF [(float_extend:XF
14055 (match_operand:MODEF 1 "register_operand" "0"))
14056 (match_operand:XF 2 "register_operand" "u")]
14057 UNSPEC_FYL2XP1))
14058 (clobber (match_scratch:XF 3 "=2"))]
14059 "TARGET_USE_FANCY_MATH_387
14060 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14061 || TARGET_MIX_SSE_I387)
14062 && flag_unsafe_math_optimizations"
14063 "fyl2xp1"
14064 [(set_attr "type" "fpspc")
14065 (set_attr "mode" "XF")])
14066
14067 (define_expand "log1pxf2"
14068 [(use (match_operand:XF 0 "register_operand" ""))
14069 (use (match_operand:XF 1 "register_operand" ""))]
14070 "TARGET_USE_FANCY_MATH_387
14071 && flag_unsafe_math_optimizations"
14072 {
14073 if (optimize_insn_for_size_p ())
14074 FAIL;
14075
14076 ix86_emit_i387_log1p (operands[0], operands[1]);
14077 DONE;
14078 })
14079
14080 (define_expand "log1p<mode>2"
14081 [(use (match_operand:MODEF 0 "register_operand" ""))
14082 (use (match_operand:MODEF 1 "register_operand" ""))]
14083 "TARGET_USE_FANCY_MATH_387
14084 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14085 || TARGET_MIX_SSE_I387)
14086 && flag_unsafe_math_optimizations"
14087 {
14088 rtx op0;
14089
14090 if (optimize_insn_for_size_p ())
14091 FAIL;
14092
14093 op0 = gen_reg_rtx (XFmode);
14094
14095 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14096
14097 ix86_emit_i387_log1p (op0, operands[1]);
14098 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14099 DONE;
14100 })
14101
14102 (define_insn "fxtractxf3_i387"
14103 [(set (match_operand:XF 0 "register_operand" "=f")
14104 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14105 UNSPEC_XTRACT_FRACT))
14106 (set (match_operand:XF 1 "register_operand" "=u")
14107 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14108 "TARGET_USE_FANCY_MATH_387
14109 && flag_unsafe_math_optimizations"
14110 "fxtract"
14111 [(set_attr "type" "fpspc")
14112 (set_attr "mode" "XF")])
14113
14114 (define_insn "fxtract_extend<mode>xf3_i387"
14115 [(set (match_operand:XF 0 "register_operand" "=f")
14116 (unspec:XF [(float_extend:XF
14117 (match_operand:MODEF 2 "register_operand" "0"))]
14118 UNSPEC_XTRACT_FRACT))
14119 (set (match_operand:XF 1 "register_operand" "=u")
14120 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14121 "TARGET_USE_FANCY_MATH_387
14122 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14123 || TARGET_MIX_SSE_I387)
14124 && flag_unsafe_math_optimizations"
14125 "fxtract"
14126 [(set_attr "type" "fpspc")
14127 (set_attr "mode" "XF")])
14128
14129 (define_expand "logbxf2"
14130 [(parallel [(set (match_dup 2)
14131 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14132 UNSPEC_XTRACT_FRACT))
14133 (set (match_operand:XF 0 "register_operand" "")
14134 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14135 "TARGET_USE_FANCY_MATH_387
14136 && flag_unsafe_math_optimizations"
14137 "operands[2] = gen_reg_rtx (XFmode);")
14138
14139 (define_expand "logb<mode>2"
14140 [(use (match_operand:MODEF 0 "register_operand" ""))
14141 (use (match_operand:MODEF 1 "register_operand" ""))]
14142 "TARGET_USE_FANCY_MATH_387
14143 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14144 || TARGET_MIX_SSE_I387)
14145 && flag_unsafe_math_optimizations"
14146 {
14147 rtx op0 = gen_reg_rtx (XFmode);
14148 rtx op1 = gen_reg_rtx (XFmode);
14149
14150 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14151 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14152 DONE;
14153 })
14154
14155 (define_expand "ilogbxf2"
14156 [(use (match_operand:SI 0 "register_operand" ""))
14157 (use (match_operand:XF 1 "register_operand" ""))]
14158 "TARGET_USE_FANCY_MATH_387
14159 && flag_unsafe_math_optimizations"
14160 {
14161 rtx op0, op1;
14162
14163 if (optimize_insn_for_size_p ())
14164 FAIL;
14165
14166 op0 = gen_reg_rtx (XFmode);
14167 op1 = gen_reg_rtx (XFmode);
14168
14169 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14170 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14171 DONE;
14172 })
14173
14174 (define_expand "ilogb<mode>2"
14175 [(use (match_operand:SI 0 "register_operand" ""))
14176 (use (match_operand:MODEF 1 "register_operand" ""))]
14177 "TARGET_USE_FANCY_MATH_387
14178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179 || TARGET_MIX_SSE_I387)
14180 && flag_unsafe_math_optimizations"
14181 {
14182 rtx op0, op1;
14183
14184 if (optimize_insn_for_size_p ())
14185 FAIL;
14186
14187 op0 = gen_reg_rtx (XFmode);
14188 op1 = gen_reg_rtx (XFmode);
14189
14190 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14191 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14192 DONE;
14193 })
14194
14195 (define_insn "*f2xm1xf2_i387"
14196 [(set (match_operand:XF 0 "register_operand" "=f")
14197 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14198 UNSPEC_F2XM1))]
14199 "TARGET_USE_FANCY_MATH_387
14200 && flag_unsafe_math_optimizations"
14201 "f2xm1"
14202 [(set_attr "type" "fpspc")
14203 (set_attr "mode" "XF")])
14204
14205 (define_insn "*fscalexf4_i387"
14206 [(set (match_operand:XF 0 "register_operand" "=f")
14207 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14208 (match_operand:XF 3 "register_operand" "1")]
14209 UNSPEC_FSCALE_FRACT))
14210 (set (match_operand:XF 1 "register_operand" "=u")
14211 (unspec:XF [(match_dup 2) (match_dup 3)]
14212 UNSPEC_FSCALE_EXP))]
14213 "TARGET_USE_FANCY_MATH_387
14214 && flag_unsafe_math_optimizations"
14215 "fscale"
14216 [(set_attr "type" "fpspc")
14217 (set_attr "mode" "XF")])
14218
14219 (define_expand "expNcorexf3"
14220 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14221 (match_operand:XF 2 "register_operand" "")))
14222 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14223 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14224 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14225 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14226 (parallel [(set (match_operand:XF 0 "register_operand" "")
14227 (unspec:XF [(match_dup 8) (match_dup 4)]
14228 UNSPEC_FSCALE_FRACT))
14229 (set (match_dup 9)
14230 (unspec:XF [(match_dup 8) (match_dup 4)]
14231 UNSPEC_FSCALE_EXP))])]
14232 "TARGET_USE_FANCY_MATH_387
14233 && flag_unsafe_math_optimizations"
14234 {
14235 int i;
14236
14237 if (optimize_insn_for_size_p ())
14238 FAIL;
14239
14240 for (i = 3; i < 10; i++)
14241 operands[i] = gen_reg_rtx (XFmode);
14242
14243 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14244 })
14245
14246 (define_expand "expxf2"
14247 [(use (match_operand:XF 0 "register_operand" ""))
14248 (use (match_operand:XF 1 "register_operand" ""))]
14249 "TARGET_USE_FANCY_MATH_387
14250 && flag_unsafe_math_optimizations"
14251 {
14252 rtx op2;
14253
14254 if (optimize_insn_for_size_p ())
14255 FAIL;
14256
14257 op2 = gen_reg_rtx (XFmode);
14258 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14259
14260 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14261 DONE;
14262 })
14263
14264 (define_expand "exp<mode>2"
14265 [(use (match_operand:MODEF 0 "register_operand" ""))
14266 (use (match_operand:MODEF 1 "general_operand" ""))]
14267 "TARGET_USE_FANCY_MATH_387
14268 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14269 || TARGET_MIX_SSE_I387)
14270 && flag_unsafe_math_optimizations"
14271 {
14272 rtx op0, op1;
14273
14274 if (optimize_insn_for_size_p ())
14275 FAIL;
14276
14277 op0 = gen_reg_rtx (XFmode);
14278 op1 = gen_reg_rtx (XFmode);
14279
14280 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14281 emit_insn (gen_expxf2 (op0, op1));
14282 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14283 DONE;
14284 })
14285
14286 (define_expand "exp10xf2"
14287 [(use (match_operand:XF 0 "register_operand" ""))
14288 (use (match_operand:XF 1 "register_operand" ""))]
14289 "TARGET_USE_FANCY_MATH_387
14290 && flag_unsafe_math_optimizations"
14291 {
14292 rtx op2;
14293
14294 if (optimize_insn_for_size_p ())
14295 FAIL;
14296
14297 op2 = gen_reg_rtx (XFmode);
14298 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14299
14300 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14301 DONE;
14302 })
14303
14304 (define_expand "exp10<mode>2"
14305 [(use (match_operand:MODEF 0 "register_operand" ""))
14306 (use (match_operand:MODEF 1 "general_operand" ""))]
14307 "TARGET_USE_FANCY_MATH_387
14308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14309 || TARGET_MIX_SSE_I387)
14310 && flag_unsafe_math_optimizations"
14311 {
14312 rtx op0, op1;
14313
14314 if (optimize_insn_for_size_p ())
14315 FAIL;
14316
14317 op0 = gen_reg_rtx (XFmode);
14318 op1 = gen_reg_rtx (XFmode);
14319
14320 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14321 emit_insn (gen_exp10xf2 (op0, op1));
14322 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14323 DONE;
14324 })
14325
14326 (define_expand "exp2xf2"
14327 [(use (match_operand:XF 0 "register_operand" ""))
14328 (use (match_operand:XF 1 "register_operand" ""))]
14329 "TARGET_USE_FANCY_MATH_387
14330 && flag_unsafe_math_optimizations"
14331 {
14332 rtx op2;
14333
14334 if (optimize_insn_for_size_p ())
14335 FAIL;
14336
14337 op2 = gen_reg_rtx (XFmode);
14338 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14339
14340 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14341 DONE;
14342 })
14343
14344 (define_expand "exp2<mode>2"
14345 [(use (match_operand:MODEF 0 "register_operand" ""))
14346 (use (match_operand:MODEF 1 "general_operand" ""))]
14347 "TARGET_USE_FANCY_MATH_387
14348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14349 || TARGET_MIX_SSE_I387)
14350 && flag_unsafe_math_optimizations"
14351 {
14352 rtx op0, op1;
14353
14354 if (optimize_insn_for_size_p ())
14355 FAIL;
14356
14357 op0 = gen_reg_rtx (XFmode);
14358 op1 = gen_reg_rtx (XFmode);
14359
14360 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14361 emit_insn (gen_exp2xf2 (op0, op1));
14362 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14363 DONE;
14364 })
14365
14366 (define_expand "expm1xf2"
14367 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14368 (match_dup 2)))
14369 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14370 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14371 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14372 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14373 (parallel [(set (match_dup 7)
14374 (unspec:XF [(match_dup 6) (match_dup 4)]
14375 UNSPEC_FSCALE_FRACT))
14376 (set (match_dup 8)
14377 (unspec:XF [(match_dup 6) (match_dup 4)]
14378 UNSPEC_FSCALE_EXP))])
14379 (parallel [(set (match_dup 10)
14380 (unspec:XF [(match_dup 9) (match_dup 8)]
14381 UNSPEC_FSCALE_FRACT))
14382 (set (match_dup 11)
14383 (unspec:XF [(match_dup 9) (match_dup 8)]
14384 UNSPEC_FSCALE_EXP))])
14385 (set (match_dup 12) (minus:XF (match_dup 10)
14386 (float_extend:XF (match_dup 13))))
14387 (set (match_operand:XF 0 "register_operand" "")
14388 (plus:XF (match_dup 12) (match_dup 7)))]
14389 "TARGET_USE_FANCY_MATH_387
14390 && flag_unsafe_math_optimizations"
14391 {
14392 int i;
14393
14394 if (optimize_insn_for_size_p ())
14395 FAIL;
14396
14397 for (i = 2; i < 13; i++)
14398 operands[i] = gen_reg_rtx (XFmode);
14399
14400 operands[13]
14401 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14402
14403 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14404 })
14405
14406 (define_expand "expm1<mode>2"
14407 [(use (match_operand:MODEF 0 "register_operand" ""))
14408 (use (match_operand:MODEF 1 "general_operand" ""))]
14409 "TARGET_USE_FANCY_MATH_387
14410 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14411 || TARGET_MIX_SSE_I387)
14412 && flag_unsafe_math_optimizations"
14413 {
14414 rtx op0, op1;
14415
14416 if (optimize_insn_for_size_p ())
14417 FAIL;
14418
14419 op0 = gen_reg_rtx (XFmode);
14420 op1 = gen_reg_rtx (XFmode);
14421
14422 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14423 emit_insn (gen_expm1xf2 (op0, op1));
14424 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14425 DONE;
14426 })
14427
14428 (define_expand "ldexpxf3"
14429 [(set (match_dup 3)
14430 (float:XF (match_operand:SI 2 "register_operand" "")))
14431 (parallel [(set (match_operand:XF 0 " register_operand" "")
14432 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14433 (match_dup 3)]
14434 UNSPEC_FSCALE_FRACT))
14435 (set (match_dup 4)
14436 (unspec:XF [(match_dup 1) (match_dup 3)]
14437 UNSPEC_FSCALE_EXP))])]
14438 "TARGET_USE_FANCY_MATH_387
14439 && flag_unsafe_math_optimizations"
14440 {
14441 if (optimize_insn_for_size_p ())
14442 FAIL;
14443
14444 operands[3] = gen_reg_rtx (XFmode);
14445 operands[4] = gen_reg_rtx (XFmode);
14446 })
14447
14448 (define_expand "ldexp<mode>3"
14449 [(use (match_operand:MODEF 0 "register_operand" ""))
14450 (use (match_operand:MODEF 1 "general_operand" ""))
14451 (use (match_operand:SI 2 "register_operand" ""))]
14452 "TARGET_USE_FANCY_MATH_387
14453 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14454 || TARGET_MIX_SSE_I387)
14455 && flag_unsafe_math_optimizations"
14456 {
14457 rtx op0, op1;
14458
14459 if (optimize_insn_for_size_p ())
14460 FAIL;
14461
14462 op0 = gen_reg_rtx (XFmode);
14463 op1 = gen_reg_rtx (XFmode);
14464
14465 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14466 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14467 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14468 DONE;
14469 })
14470
14471 (define_expand "scalbxf3"
14472 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14473 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14474 (match_operand:XF 2 "register_operand" "")]
14475 UNSPEC_FSCALE_FRACT))
14476 (set (match_dup 3)
14477 (unspec:XF [(match_dup 1) (match_dup 2)]
14478 UNSPEC_FSCALE_EXP))])]
14479 "TARGET_USE_FANCY_MATH_387
14480 && flag_unsafe_math_optimizations"
14481 {
14482 if (optimize_insn_for_size_p ())
14483 FAIL;
14484
14485 operands[3] = gen_reg_rtx (XFmode);
14486 })
14487
14488 (define_expand "scalb<mode>3"
14489 [(use (match_operand:MODEF 0 "register_operand" ""))
14490 (use (match_operand:MODEF 1 "general_operand" ""))
14491 (use (match_operand:MODEF 2 "general_operand" ""))]
14492 "TARGET_USE_FANCY_MATH_387
14493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14494 || TARGET_MIX_SSE_I387)
14495 && flag_unsafe_math_optimizations"
14496 {
14497 rtx op0, op1, op2;
14498
14499 if (optimize_insn_for_size_p ())
14500 FAIL;
14501
14502 op0 = gen_reg_rtx (XFmode);
14503 op1 = gen_reg_rtx (XFmode);
14504 op2 = gen_reg_rtx (XFmode);
14505
14506 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14507 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14508 emit_insn (gen_scalbxf3 (op0, op1, op2));
14509 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14510 DONE;
14511 })
14512
14513 (define_expand "significandxf2"
14514 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14515 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14516 UNSPEC_XTRACT_FRACT))
14517 (set (match_dup 2)
14518 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14519 "TARGET_USE_FANCY_MATH_387
14520 && flag_unsafe_math_optimizations"
14521 "operands[2] = gen_reg_rtx (XFmode);")
14522
14523 (define_expand "significand<mode>2"
14524 [(use (match_operand:MODEF 0 "register_operand" ""))
14525 (use (match_operand:MODEF 1 "register_operand" ""))]
14526 "TARGET_USE_FANCY_MATH_387
14527 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14528 || TARGET_MIX_SSE_I387)
14529 && flag_unsafe_math_optimizations"
14530 {
14531 rtx op0 = gen_reg_rtx (XFmode);
14532 rtx op1 = gen_reg_rtx (XFmode);
14533
14534 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14535 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14536 DONE;
14537 })
14538 \f
14539
14540 (define_insn "sse4_1_round<mode>2"
14541 [(set (match_operand:MODEF 0 "register_operand" "=x")
14542 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14543 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14544 UNSPEC_ROUND))]
14545 "TARGET_ROUND"
14546 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14547 [(set_attr "type" "ssecvt")
14548 (set_attr "prefix_extra" "1")
14549 (set_attr "prefix" "maybe_vex")
14550 (set_attr "mode" "<MODE>")])
14551
14552 (define_insn "rintxf2"
14553 [(set (match_operand:XF 0 "register_operand" "=f")
14554 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14555 UNSPEC_FRNDINT))]
14556 "TARGET_USE_FANCY_MATH_387
14557 && flag_unsafe_math_optimizations"
14558 "frndint"
14559 [(set_attr "type" "fpspc")
14560 (set_attr "mode" "XF")])
14561
14562 (define_expand "rint<mode>2"
14563 [(use (match_operand:MODEF 0 "register_operand" ""))
14564 (use (match_operand:MODEF 1 "register_operand" ""))]
14565 "(TARGET_USE_FANCY_MATH_387
14566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14567 || TARGET_MIX_SSE_I387)
14568 && flag_unsafe_math_optimizations)
14569 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14570 && !flag_trapping_math)"
14571 {
14572 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14573 && !flag_trapping_math)
14574 {
14575 if (TARGET_ROUND)
14576 emit_insn (gen_sse4_1_round<mode>2
14577 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14578 else if (optimize_insn_for_size_p ())
14579 FAIL;
14580 else
14581 ix86_expand_rint (operands[0], operands[1]);
14582 }
14583 else
14584 {
14585 rtx op0 = gen_reg_rtx (XFmode);
14586 rtx op1 = gen_reg_rtx (XFmode);
14587
14588 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14589 emit_insn (gen_rintxf2 (op0, op1));
14590
14591 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14592 }
14593 DONE;
14594 })
14595
14596 (define_expand "round<mode>2"
14597 [(match_operand:X87MODEF 0 "register_operand" "")
14598 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14599 "(TARGET_USE_FANCY_MATH_387
14600 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14601 || TARGET_MIX_SSE_I387)
14602 && flag_unsafe_math_optimizations)
14603 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14604 && !flag_trapping_math && !flag_rounding_math)"
14605 {
14606 if (optimize_insn_for_size_p ())
14607 FAIL;
14608
14609 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14610 && !flag_trapping_math && !flag_rounding_math)
14611 {
14612 if (TARGET_ROUND)
14613 {
14614 operands[1] = force_reg (<MODE>mode, operands[1]);
14615 ix86_expand_round_sse4 (operands[0], operands[1]);
14616 }
14617 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14618 ix86_expand_round (operands[0], operands[1]);
14619 else
14620 ix86_expand_rounddf_32 (operands[0], operands[1]);
14621 }
14622 else
14623 {
14624 operands[1] = force_reg (<MODE>mode, operands[1]);
14625 ix86_emit_i387_round (operands[0], operands[1]);
14626 }
14627 DONE;
14628 })
14629
14630 (define_insn_and_split "*fistdi2_1"
14631 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14632 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14633 UNSPEC_FIST))]
14634 "TARGET_USE_FANCY_MATH_387
14635 && can_create_pseudo_p ()"
14636 "#"
14637 "&& 1"
14638 [(const_int 0)]
14639 {
14640 if (memory_operand (operands[0], VOIDmode))
14641 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14642 else
14643 {
14644 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14645 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14646 operands[2]));
14647 }
14648 DONE;
14649 }
14650 [(set_attr "type" "fpspc")
14651 (set_attr "mode" "DI")])
14652
14653 (define_insn "fistdi2"
14654 [(set (match_operand:DI 0 "memory_operand" "=m")
14655 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14656 UNSPEC_FIST))
14657 (clobber (match_scratch:XF 2 "=&1f"))]
14658 "TARGET_USE_FANCY_MATH_387"
14659 "* return output_fix_trunc (insn, operands, false);"
14660 [(set_attr "type" "fpspc")
14661 (set_attr "mode" "DI")])
14662
14663 (define_insn "fistdi2_with_temp"
14664 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14665 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14666 UNSPEC_FIST))
14667 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14668 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14669 "TARGET_USE_FANCY_MATH_387"
14670 "#"
14671 [(set_attr "type" "fpspc")
14672 (set_attr "mode" "DI")])
14673
14674 (define_split
14675 [(set (match_operand:DI 0 "register_operand" "")
14676 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14677 UNSPEC_FIST))
14678 (clobber (match_operand:DI 2 "memory_operand" ""))
14679 (clobber (match_scratch 3 ""))]
14680 "reload_completed"
14681 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14682 (clobber (match_dup 3))])
14683 (set (match_dup 0) (match_dup 2))])
14684
14685 (define_split
14686 [(set (match_operand:DI 0 "memory_operand" "")
14687 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14688 UNSPEC_FIST))
14689 (clobber (match_operand:DI 2 "memory_operand" ""))
14690 (clobber (match_scratch 3 ""))]
14691 "reload_completed"
14692 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14693 (clobber (match_dup 3))])])
14694
14695 (define_insn_and_split "*fist<mode>2_1"
14696 [(set (match_operand:SWI24 0 "register_operand" "")
14697 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14698 UNSPEC_FIST))]
14699 "TARGET_USE_FANCY_MATH_387
14700 && can_create_pseudo_p ()"
14701 "#"
14702 "&& 1"
14703 [(const_int 0)]
14704 {
14705 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14706 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14707 operands[2]));
14708 DONE;
14709 }
14710 [(set_attr "type" "fpspc")
14711 (set_attr "mode" "<MODE>")])
14712
14713 (define_insn "fist<mode>2"
14714 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14715 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14716 UNSPEC_FIST))]
14717 "TARGET_USE_FANCY_MATH_387"
14718 "* return output_fix_trunc (insn, operands, false);"
14719 [(set_attr "type" "fpspc")
14720 (set_attr "mode" "<MODE>")])
14721
14722 (define_insn "fist<mode>2_with_temp"
14723 [(set (match_operand:SWI24 0 "register_operand" "=r")
14724 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14725 UNSPEC_FIST))
14726 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14727 "TARGET_USE_FANCY_MATH_387"
14728 "#"
14729 [(set_attr "type" "fpspc")
14730 (set_attr "mode" "<MODE>")])
14731
14732 (define_split
14733 [(set (match_operand:SWI24 0 "register_operand" "")
14734 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14735 UNSPEC_FIST))
14736 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14737 "reload_completed"
14738 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14739 (set (match_dup 0) (match_dup 2))])
14740
14741 (define_split
14742 [(set (match_operand:SWI24 0 "memory_operand" "")
14743 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14744 UNSPEC_FIST))
14745 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14746 "reload_completed"
14747 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14748
14749 (define_expand "lrintxf<mode>2"
14750 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14751 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14752 UNSPEC_FIST))]
14753 "TARGET_USE_FANCY_MATH_387")
14754
14755 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14756 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14757 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14758 UNSPEC_FIX_NOTRUNC))]
14759 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14760 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14761
14762 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14763 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14764 (match_operand:X87MODEF 1 "register_operand" "")]
14765 "(TARGET_USE_FANCY_MATH_387
14766 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14767 || TARGET_MIX_SSE_I387)
14768 && flag_unsafe_math_optimizations)
14769 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14770 && <SWI248x:MODE>mode != HImode
14771 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14772 && !flag_trapping_math && !flag_rounding_math)"
14773 {
14774 if (optimize_insn_for_size_p ())
14775 FAIL;
14776
14777 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14778 && <SWI248x:MODE>mode != HImode
14779 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14780 && !flag_trapping_math && !flag_rounding_math)
14781 ix86_expand_lround (operands[0], operands[1]);
14782 else
14783 ix86_emit_i387_round (operands[0], operands[1]);
14784 DONE;
14785 })
14786
14787 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14788 (define_insn_and_split "frndintxf2_floor"
14789 [(set (match_operand:XF 0 "register_operand" "")
14790 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14791 UNSPEC_FRNDINT_FLOOR))
14792 (clobber (reg:CC FLAGS_REG))]
14793 "TARGET_USE_FANCY_MATH_387
14794 && flag_unsafe_math_optimizations
14795 && can_create_pseudo_p ()"
14796 "#"
14797 "&& 1"
14798 [(const_int 0)]
14799 {
14800 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14801
14802 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14803 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14804
14805 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14806 operands[2], operands[3]));
14807 DONE;
14808 }
14809 [(set_attr "type" "frndint")
14810 (set_attr "i387_cw" "floor")
14811 (set_attr "mode" "XF")])
14812
14813 (define_insn "frndintxf2_floor_i387"
14814 [(set (match_operand:XF 0 "register_operand" "=f")
14815 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14816 UNSPEC_FRNDINT_FLOOR))
14817 (use (match_operand:HI 2 "memory_operand" "m"))
14818 (use (match_operand:HI 3 "memory_operand" "m"))]
14819 "TARGET_USE_FANCY_MATH_387
14820 && flag_unsafe_math_optimizations"
14821 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14822 [(set_attr "type" "frndint")
14823 (set_attr "i387_cw" "floor")
14824 (set_attr "mode" "XF")])
14825
14826 (define_expand "floorxf2"
14827 [(use (match_operand:XF 0 "register_operand" ""))
14828 (use (match_operand:XF 1 "register_operand" ""))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && flag_unsafe_math_optimizations"
14831 {
14832 if (optimize_insn_for_size_p ())
14833 FAIL;
14834 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14835 DONE;
14836 })
14837
14838 (define_expand "floor<mode>2"
14839 [(use (match_operand:MODEF 0 "register_operand" ""))
14840 (use (match_operand:MODEF 1 "register_operand" ""))]
14841 "(TARGET_USE_FANCY_MATH_387
14842 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14843 || TARGET_MIX_SSE_I387)
14844 && flag_unsafe_math_optimizations)
14845 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14846 && !flag_trapping_math)"
14847 {
14848 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14849 && !flag_trapping_math)
14850 {
14851 if (TARGET_ROUND)
14852 emit_insn (gen_sse4_1_round<mode>2
14853 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14854 else if (optimize_insn_for_size_p ())
14855 FAIL;
14856 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14857 ix86_expand_floorceil (operands[0], operands[1], true);
14858 else
14859 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14860 }
14861 else
14862 {
14863 rtx op0, op1;
14864
14865 if (optimize_insn_for_size_p ())
14866 FAIL;
14867
14868 op0 = gen_reg_rtx (XFmode);
14869 op1 = gen_reg_rtx (XFmode);
14870 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14871 emit_insn (gen_frndintxf2_floor (op0, op1));
14872
14873 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14874 }
14875 DONE;
14876 })
14877
14878 (define_insn_and_split "*fist<mode>2_floor_1"
14879 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14880 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14881 UNSPEC_FIST_FLOOR))
14882 (clobber (reg:CC FLAGS_REG))]
14883 "TARGET_USE_FANCY_MATH_387
14884 && flag_unsafe_math_optimizations
14885 && can_create_pseudo_p ()"
14886 "#"
14887 "&& 1"
14888 [(const_int 0)]
14889 {
14890 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14891
14892 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14893 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14894 if (memory_operand (operands[0], VOIDmode))
14895 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14896 operands[2], operands[3]));
14897 else
14898 {
14899 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14900 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14901 operands[2], operands[3],
14902 operands[4]));
14903 }
14904 DONE;
14905 }
14906 [(set_attr "type" "fistp")
14907 (set_attr "i387_cw" "floor")
14908 (set_attr "mode" "<MODE>")])
14909
14910 (define_insn "fistdi2_floor"
14911 [(set (match_operand:DI 0 "memory_operand" "=m")
14912 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14913 UNSPEC_FIST_FLOOR))
14914 (use (match_operand:HI 2 "memory_operand" "m"))
14915 (use (match_operand:HI 3 "memory_operand" "m"))
14916 (clobber (match_scratch:XF 4 "=&1f"))]
14917 "TARGET_USE_FANCY_MATH_387
14918 && flag_unsafe_math_optimizations"
14919 "* return output_fix_trunc (insn, operands, false);"
14920 [(set_attr "type" "fistp")
14921 (set_attr "i387_cw" "floor")
14922 (set_attr "mode" "DI")])
14923
14924 (define_insn "fistdi2_floor_with_temp"
14925 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14926 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14927 UNSPEC_FIST_FLOOR))
14928 (use (match_operand:HI 2 "memory_operand" "m,m"))
14929 (use (match_operand:HI 3 "memory_operand" "m,m"))
14930 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14931 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14932 "TARGET_USE_FANCY_MATH_387
14933 && flag_unsafe_math_optimizations"
14934 "#"
14935 [(set_attr "type" "fistp")
14936 (set_attr "i387_cw" "floor")
14937 (set_attr "mode" "DI")])
14938
14939 (define_split
14940 [(set (match_operand:DI 0 "register_operand" "")
14941 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14942 UNSPEC_FIST_FLOOR))
14943 (use (match_operand:HI 2 "memory_operand" ""))
14944 (use (match_operand:HI 3 "memory_operand" ""))
14945 (clobber (match_operand:DI 4 "memory_operand" ""))
14946 (clobber (match_scratch 5 ""))]
14947 "reload_completed"
14948 [(parallel [(set (match_dup 4)
14949 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14950 (use (match_dup 2))
14951 (use (match_dup 3))
14952 (clobber (match_dup 5))])
14953 (set (match_dup 0) (match_dup 4))])
14954
14955 (define_split
14956 [(set (match_operand:DI 0 "memory_operand" "")
14957 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14958 UNSPEC_FIST_FLOOR))
14959 (use (match_operand:HI 2 "memory_operand" ""))
14960 (use (match_operand:HI 3 "memory_operand" ""))
14961 (clobber (match_operand:DI 4 "memory_operand" ""))
14962 (clobber (match_scratch 5 ""))]
14963 "reload_completed"
14964 [(parallel [(set (match_dup 0)
14965 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14966 (use (match_dup 2))
14967 (use (match_dup 3))
14968 (clobber (match_dup 5))])])
14969
14970 (define_insn "fist<mode>2_floor"
14971 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14972 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14973 UNSPEC_FIST_FLOOR))
14974 (use (match_operand:HI 2 "memory_operand" "m"))
14975 (use (match_operand:HI 3 "memory_operand" "m"))]
14976 "TARGET_USE_FANCY_MATH_387
14977 && flag_unsafe_math_optimizations"
14978 "* return output_fix_trunc (insn, operands, false);"
14979 [(set_attr "type" "fistp")
14980 (set_attr "i387_cw" "floor")
14981 (set_attr "mode" "<MODE>")])
14982
14983 (define_insn "fist<mode>2_floor_with_temp"
14984 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14985 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14986 UNSPEC_FIST_FLOOR))
14987 (use (match_operand:HI 2 "memory_operand" "m,m"))
14988 (use (match_operand:HI 3 "memory_operand" "m,m"))
14989 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14990 "TARGET_USE_FANCY_MATH_387
14991 && flag_unsafe_math_optimizations"
14992 "#"
14993 [(set_attr "type" "fistp")
14994 (set_attr "i387_cw" "floor")
14995 (set_attr "mode" "<MODE>")])
14996
14997 (define_split
14998 [(set (match_operand:SWI24 0 "register_operand" "")
14999 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15000 UNSPEC_FIST_FLOOR))
15001 (use (match_operand:HI 2 "memory_operand" ""))
15002 (use (match_operand:HI 3 "memory_operand" ""))
15003 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15004 "reload_completed"
15005 [(parallel [(set (match_dup 4)
15006 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15007 (use (match_dup 2))
15008 (use (match_dup 3))])
15009 (set (match_dup 0) (match_dup 4))])
15010
15011 (define_split
15012 [(set (match_operand:SWI24 0 "memory_operand" "")
15013 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15014 UNSPEC_FIST_FLOOR))
15015 (use (match_operand:HI 2 "memory_operand" ""))
15016 (use (match_operand:HI 3 "memory_operand" ""))
15017 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15018 "reload_completed"
15019 [(parallel [(set (match_dup 0)
15020 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15021 (use (match_dup 2))
15022 (use (match_dup 3))])])
15023
15024 (define_expand "lfloorxf<mode>2"
15025 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15026 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15027 UNSPEC_FIST_FLOOR))
15028 (clobber (reg:CC FLAGS_REG))])]
15029 "TARGET_USE_FANCY_MATH_387
15030 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15031 && flag_unsafe_math_optimizations")
15032
15033 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15034 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15035 (match_operand:MODEF 1 "register_operand" "")]
15036 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15037 && !flag_trapping_math"
15038 {
15039 if (TARGET_64BIT && optimize_insn_for_size_p ())
15040 FAIL;
15041 ix86_expand_lfloorceil (operands[0], operands[1], true);
15042 DONE;
15043 })
15044
15045 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15046 (define_insn_and_split "frndintxf2_ceil"
15047 [(set (match_operand:XF 0 "register_operand" "")
15048 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15049 UNSPEC_FRNDINT_CEIL))
15050 (clobber (reg:CC FLAGS_REG))]
15051 "TARGET_USE_FANCY_MATH_387
15052 && flag_unsafe_math_optimizations
15053 && can_create_pseudo_p ()"
15054 "#"
15055 "&& 1"
15056 [(const_int 0)]
15057 {
15058 ix86_optimize_mode_switching[I387_CEIL] = 1;
15059
15060 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15061 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15062
15063 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15064 operands[2], operands[3]));
15065 DONE;
15066 }
15067 [(set_attr "type" "frndint")
15068 (set_attr "i387_cw" "ceil")
15069 (set_attr "mode" "XF")])
15070
15071 (define_insn "frndintxf2_ceil_i387"
15072 [(set (match_operand:XF 0 "register_operand" "=f")
15073 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15074 UNSPEC_FRNDINT_CEIL))
15075 (use (match_operand:HI 2 "memory_operand" "m"))
15076 (use (match_operand:HI 3 "memory_operand" "m"))]
15077 "TARGET_USE_FANCY_MATH_387
15078 && flag_unsafe_math_optimizations"
15079 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15080 [(set_attr "type" "frndint")
15081 (set_attr "i387_cw" "ceil")
15082 (set_attr "mode" "XF")])
15083
15084 (define_expand "ceilxf2"
15085 [(use (match_operand:XF 0 "register_operand" ""))
15086 (use (match_operand:XF 1 "register_operand" ""))]
15087 "TARGET_USE_FANCY_MATH_387
15088 && flag_unsafe_math_optimizations"
15089 {
15090 if (optimize_insn_for_size_p ())
15091 FAIL;
15092 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15093 DONE;
15094 })
15095
15096 (define_expand "ceil<mode>2"
15097 [(use (match_operand:MODEF 0 "register_operand" ""))
15098 (use (match_operand:MODEF 1 "register_operand" ""))]
15099 "(TARGET_USE_FANCY_MATH_387
15100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15101 || TARGET_MIX_SSE_I387)
15102 && flag_unsafe_math_optimizations)
15103 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15104 && !flag_trapping_math)"
15105 {
15106 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15107 && !flag_trapping_math)
15108 {
15109 if (TARGET_ROUND)
15110 emit_insn (gen_sse4_1_round<mode>2
15111 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15112 else if (optimize_insn_for_size_p ())
15113 FAIL;
15114 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15115 ix86_expand_floorceil (operands[0], operands[1], false);
15116 else
15117 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15118 }
15119 else
15120 {
15121 rtx op0, op1;
15122
15123 if (optimize_insn_for_size_p ())
15124 FAIL;
15125
15126 op0 = gen_reg_rtx (XFmode);
15127 op1 = gen_reg_rtx (XFmode);
15128 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15129 emit_insn (gen_frndintxf2_ceil (op0, op1));
15130
15131 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15132 }
15133 DONE;
15134 })
15135
15136 (define_insn_and_split "*fist<mode>2_ceil_1"
15137 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15138 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15139 UNSPEC_FIST_CEIL))
15140 (clobber (reg:CC FLAGS_REG))]
15141 "TARGET_USE_FANCY_MATH_387
15142 && flag_unsafe_math_optimizations
15143 && can_create_pseudo_p ()"
15144 "#"
15145 "&& 1"
15146 [(const_int 0)]
15147 {
15148 ix86_optimize_mode_switching[I387_CEIL] = 1;
15149
15150 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15151 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15152 if (memory_operand (operands[0], VOIDmode))
15153 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15154 operands[2], operands[3]));
15155 else
15156 {
15157 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15158 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15159 operands[2], operands[3],
15160 operands[4]));
15161 }
15162 DONE;
15163 }
15164 [(set_attr "type" "fistp")
15165 (set_attr "i387_cw" "ceil")
15166 (set_attr "mode" "<MODE>")])
15167
15168 (define_insn "fistdi2_ceil"
15169 [(set (match_operand:DI 0 "memory_operand" "=m")
15170 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15171 UNSPEC_FIST_CEIL))
15172 (use (match_operand:HI 2 "memory_operand" "m"))
15173 (use (match_operand:HI 3 "memory_operand" "m"))
15174 (clobber (match_scratch:XF 4 "=&1f"))]
15175 "TARGET_USE_FANCY_MATH_387
15176 && flag_unsafe_math_optimizations"
15177 "* return output_fix_trunc (insn, operands, false);"
15178 [(set_attr "type" "fistp")
15179 (set_attr "i387_cw" "ceil")
15180 (set_attr "mode" "DI")])
15181
15182 (define_insn "fistdi2_ceil_with_temp"
15183 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15184 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15185 UNSPEC_FIST_CEIL))
15186 (use (match_operand:HI 2 "memory_operand" "m,m"))
15187 (use (match_operand:HI 3 "memory_operand" "m,m"))
15188 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15189 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15190 "TARGET_USE_FANCY_MATH_387
15191 && flag_unsafe_math_optimizations"
15192 "#"
15193 [(set_attr "type" "fistp")
15194 (set_attr "i387_cw" "ceil")
15195 (set_attr "mode" "DI")])
15196
15197 (define_split
15198 [(set (match_operand:DI 0 "register_operand" "")
15199 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15200 UNSPEC_FIST_CEIL))
15201 (use (match_operand:HI 2 "memory_operand" ""))
15202 (use (match_operand:HI 3 "memory_operand" ""))
15203 (clobber (match_operand:DI 4 "memory_operand" ""))
15204 (clobber (match_scratch 5 ""))]
15205 "reload_completed"
15206 [(parallel [(set (match_dup 4)
15207 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15208 (use (match_dup 2))
15209 (use (match_dup 3))
15210 (clobber (match_dup 5))])
15211 (set (match_dup 0) (match_dup 4))])
15212
15213 (define_split
15214 [(set (match_operand:DI 0 "memory_operand" "")
15215 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15216 UNSPEC_FIST_CEIL))
15217 (use (match_operand:HI 2 "memory_operand" ""))
15218 (use (match_operand:HI 3 "memory_operand" ""))
15219 (clobber (match_operand:DI 4 "memory_operand" ""))
15220 (clobber (match_scratch 5 ""))]
15221 "reload_completed"
15222 [(parallel [(set (match_dup 0)
15223 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15224 (use (match_dup 2))
15225 (use (match_dup 3))
15226 (clobber (match_dup 5))])])
15227
15228 (define_insn "fist<mode>2_ceil"
15229 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15230 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15231 UNSPEC_FIST_CEIL))
15232 (use (match_operand:HI 2 "memory_operand" "m"))
15233 (use (match_operand:HI 3 "memory_operand" "m"))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && flag_unsafe_math_optimizations"
15236 "* return output_fix_trunc (insn, operands, false);"
15237 [(set_attr "type" "fistp")
15238 (set_attr "i387_cw" "ceil")
15239 (set_attr "mode" "<MODE>")])
15240
15241 (define_insn "fist<mode>2_ceil_with_temp"
15242 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15243 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15244 UNSPEC_FIST_CEIL))
15245 (use (match_operand:HI 2 "memory_operand" "m,m"))
15246 (use (match_operand:HI 3 "memory_operand" "m,m"))
15247 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15248 "TARGET_USE_FANCY_MATH_387
15249 && flag_unsafe_math_optimizations"
15250 "#"
15251 [(set_attr "type" "fistp")
15252 (set_attr "i387_cw" "ceil")
15253 (set_attr "mode" "<MODE>")])
15254
15255 (define_split
15256 [(set (match_operand:SWI24 0 "register_operand" "")
15257 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15258 UNSPEC_FIST_CEIL))
15259 (use (match_operand:HI 2 "memory_operand" ""))
15260 (use (match_operand:HI 3 "memory_operand" ""))
15261 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15262 "reload_completed"
15263 [(parallel [(set (match_dup 4)
15264 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15265 (use (match_dup 2))
15266 (use (match_dup 3))])
15267 (set (match_dup 0) (match_dup 4))])
15268
15269 (define_split
15270 [(set (match_operand:SWI24 0 "memory_operand" "")
15271 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15272 UNSPEC_FIST_CEIL))
15273 (use (match_operand:HI 2 "memory_operand" ""))
15274 (use (match_operand:HI 3 "memory_operand" ""))
15275 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15276 "reload_completed"
15277 [(parallel [(set (match_dup 0)
15278 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15279 (use (match_dup 2))
15280 (use (match_dup 3))])])
15281
15282 (define_expand "lceilxf<mode>2"
15283 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15284 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15285 UNSPEC_FIST_CEIL))
15286 (clobber (reg:CC FLAGS_REG))])]
15287 "TARGET_USE_FANCY_MATH_387
15288 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15289 && flag_unsafe_math_optimizations")
15290
15291 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15292 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15293 (match_operand:MODEF 1 "register_operand" "")]
15294 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15295 && !flag_trapping_math"
15296 {
15297 ix86_expand_lfloorceil (operands[0], operands[1], false);
15298 DONE;
15299 })
15300
15301 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15302 (define_insn_and_split "frndintxf2_trunc"
15303 [(set (match_operand:XF 0 "register_operand" "")
15304 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15305 UNSPEC_FRNDINT_TRUNC))
15306 (clobber (reg:CC FLAGS_REG))]
15307 "TARGET_USE_FANCY_MATH_387
15308 && flag_unsafe_math_optimizations
15309 && can_create_pseudo_p ()"
15310 "#"
15311 "&& 1"
15312 [(const_int 0)]
15313 {
15314 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15315
15316 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15317 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15318
15319 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15320 operands[2], operands[3]));
15321 DONE;
15322 }
15323 [(set_attr "type" "frndint")
15324 (set_attr "i387_cw" "trunc")
15325 (set_attr "mode" "XF")])
15326
15327 (define_insn "frndintxf2_trunc_i387"
15328 [(set (match_operand:XF 0 "register_operand" "=f")
15329 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15330 UNSPEC_FRNDINT_TRUNC))
15331 (use (match_operand:HI 2 "memory_operand" "m"))
15332 (use (match_operand:HI 3 "memory_operand" "m"))]
15333 "TARGET_USE_FANCY_MATH_387
15334 && flag_unsafe_math_optimizations"
15335 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15336 [(set_attr "type" "frndint")
15337 (set_attr "i387_cw" "trunc")
15338 (set_attr "mode" "XF")])
15339
15340 (define_expand "btruncxf2"
15341 [(use (match_operand:XF 0 "register_operand" ""))
15342 (use (match_operand:XF 1 "register_operand" ""))]
15343 "TARGET_USE_FANCY_MATH_387
15344 && flag_unsafe_math_optimizations"
15345 {
15346 if (optimize_insn_for_size_p ())
15347 FAIL;
15348 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15349 DONE;
15350 })
15351
15352 (define_expand "btrunc<mode>2"
15353 [(use (match_operand:MODEF 0 "register_operand" ""))
15354 (use (match_operand:MODEF 1 "register_operand" ""))]
15355 "(TARGET_USE_FANCY_MATH_387
15356 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15357 || TARGET_MIX_SSE_I387)
15358 && flag_unsafe_math_optimizations)
15359 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15360 && !flag_trapping_math)"
15361 {
15362 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15363 && !flag_trapping_math)
15364 {
15365 if (TARGET_ROUND)
15366 emit_insn (gen_sse4_1_round<mode>2
15367 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15368 else if (optimize_insn_for_size_p ())
15369 FAIL;
15370 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15371 ix86_expand_trunc (operands[0], operands[1]);
15372 else
15373 ix86_expand_truncdf_32 (operands[0], operands[1]);
15374 }
15375 else
15376 {
15377 rtx op0, op1;
15378
15379 if (optimize_insn_for_size_p ())
15380 FAIL;
15381
15382 op0 = gen_reg_rtx (XFmode);
15383 op1 = gen_reg_rtx (XFmode);
15384 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15385 emit_insn (gen_frndintxf2_trunc (op0, op1));
15386
15387 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15388 }
15389 DONE;
15390 })
15391
15392 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15393 (define_insn_and_split "frndintxf2_mask_pm"
15394 [(set (match_operand:XF 0 "register_operand" "")
15395 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15396 UNSPEC_FRNDINT_MASK_PM))
15397 (clobber (reg:CC FLAGS_REG))]
15398 "TARGET_USE_FANCY_MATH_387
15399 && flag_unsafe_math_optimizations
15400 && can_create_pseudo_p ()"
15401 "#"
15402 "&& 1"
15403 [(const_int 0)]
15404 {
15405 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15406
15407 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15408 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15409
15410 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15411 operands[2], operands[3]));
15412 DONE;
15413 }
15414 [(set_attr "type" "frndint")
15415 (set_attr "i387_cw" "mask_pm")
15416 (set_attr "mode" "XF")])
15417
15418 (define_insn "frndintxf2_mask_pm_i387"
15419 [(set (match_operand:XF 0 "register_operand" "=f")
15420 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15421 UNSPEC_FRNDINT_MASK_PM))
15422 (use (match_operand:HI 2 "memory_operand" "m"))
15423 (use (match_operand:HI 3 "memory_operand" "m"))]
15424 "TARGET_USE_FANCY_MATH_387
15425 && flag_unsafe_math_optimizations"
15426 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15427 [(set_attr "type" "frndint")
15428 (set_attr "i387_cw" "mask_pm")
15429 (set_attr "mode" "XF")])
15430
15431 (define_expand "nearbyintxf2"
15432 [(use (match_operand:XF 0 "register_operand" ""))
15433 (use (match_operand:XF 1 "register_operand" ""))]
15434 "TARGET_USE_FANCY_MATH_387
15435 && flag_unsafe_math_optimizations"
15436 {
15437 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15438 DONE;
15439 })
15440
15441 (define_expand "nearbyint<mode>2"
15442 [(use (match_operand:MODEF 0 "register_operand" ""))
15443 (use (match_operand:MODEF 1 "register_operand" ""))]
15444 "TARGET_USE_FANCY_MATH_387
15445 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15446 || TARGET_MIX_SSE_I387)
15447 && flag_unsafe_math_optimizations"
15448 {
15449 rtx op0 = gen_reg_rtx (XFmode);
15450 rtx op1 = gen_reg_rtx (XFmode);
15451
15452 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15453 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15454
15455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15456 DONE;
15457 })
15458
15459 (define_insn "fxam<mode>2_i387"
15460 [(set (match_operand:HI 0 "register_operand" "=a")
15461 (unspec:HI
15462 [(match_operand:X87MODEF 1 "register_operand" "f")]
15463 UNSPEC_FXAM))]
15464 "TARGET_USE_FANCY_MATH_387"
15465 "fxam\n\tfnstsw\t%0"
15466 [(set_attr "type" "multi")
15467 (set_attr "length" "4")
15468 (set_attr "unit" "i387")
15469 (set_attr "mode" "<MODE>")])
15470
15471 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15472 [(set (match_operand:HI 0 "register_operand" "")
15473 (unspec:HI
15474 [(match_operand:MODEF 1 "memory_operand" "")]
15475 UNSPEC_FXAM_MEM))]
15476 "TARGET_USE_FANCY_MATH_387
15477 && can_create_pseudo_p ()"
15478 "#"
15479 "&& 1"
15480 [(set (match_dup 2)(match_dup 1))
15481 (set (match_dup 0)
15482 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15483 {
15484 operands[2] = gen_reg_rtx (<MODE>mode);
15485
15486 MEM_VOLATILE_P (operands[1]) = 1;
15487 }
15488 [(set_attr "type" "multi")
15489 (set_attr "unit" "i387")
15490 (set_attr "mode" "<MODE>")])
15491
15492 (define_expand "isinfxf2"
15493 [(use (match_operand:SI 0 "register_operand" ""))
15494 (use (match_operand:XF 1 "register_operand" ""))]
15495 "TARGET_USE_FANCY_MATH_387
15496 && TARGET_C99_FUNCTIONS"
15497 {
15498 rtx mask = GEN_INT (0x45);
15499 rtx val = GEN_INT (0x05);
15500
15501 rtx cond;
15502
15503 rtx scratch = gen_reg_rtx (HImode);
15504 rtx res = gen_reg_rtx (QImode);
15505
15506 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15507
15508 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15509 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15510 cond = gen_rtx_fmt_ee (EQ, QImode,
15511 gen_rtx_REG (CCmode, FLAGS_REG),
15512 const0_rtx);
15513 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15514 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15515 DONE;
15516 })
15517
15518 (define_expand "isinf<mode>2"
15519 [(use (match_operand:SI 0 "register_operand" ""))
15520 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15521 "TARGET_USE_FANCY_MATH_387
15522 && TARGET_C99_FUNCTIONS
15523 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15524 {
15525 rtx mask = GEN_INT (0x45);
15526 rtx val = GEN_INT (0x05);
15527
15528 rtx cond;
15529
15530 rtx scratch = gen_reg_rtx (HImode);
15531 rtx res = gen_reg_rtx (QImode);
15532
15533 /* Remove excess precision by forcing value through memory. */
15534 if (memory_operand (operands[1], VOIDmode))
15535 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15536 else
15537 {
15538 enum ix86_stack_slot slot = (virtuals_instantiated
15539 ? SLOT_TEMP
15540 : SLOT_VIRTUAL);
15541 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15542
15543 emit_move_insn (temp, operands[1]);
15544 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15545 }
15546
15547 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15548 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15549 cond = gen_rtx_fmt_ee (EQ, QImode,
15550 gen_rtx_REG (CCmode, FLAGS_REG),
15551 const0_rtx);
15552 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15553 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15554 DONE;
15555 })
15556
15557 (define_expand "signbitxf2"
15558 [(use (match_operand:SI 0 "register_operand" ""))
15559 (use (match_operand:XF 1 "register_operand" ""))]
15560 "TARGET_USE_FANCY_MATH_387"
15561 {
15562 rtx scratch = gen_reg_rtx (HImode);
15563
15564 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15565 emit_insn (gen_andsi3 (operands[0],
15566 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15567 DONE;
15568 })
15569
15570 (define_insn "movmsk_df"
15571 [(set (match_operand:SI 0 "register_operand" "=r")
15572 (unspec:SI
15573 [(match_operand:DF 1 "register_operand" "x")]
15574 UNSPEC_MOVMSK))]
15575 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15576 "%vmovmskpd\t{%1, %0|%0, %1}"
15577 [(set_attr "type" "ssemov")
15578 (set_attr "prefix" "maybe_vex")
15579 (set_attr "mode" "DF")])
15580
15581 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15582 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15583 (define_expand "signbitdf2"
15584 [(use (match_operand:SI 0 "register_operand" ""))
15585 (use (match_operand:DF 1 "register_operand" ""))]
15586 "TARGET_USE_FANCY_MATH_387
15587 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15588 {
15589 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15590 {
15591 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15592 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15593 }
15594 else
15595 {
15596 rtx scratch = gen_reg_rtx (HImode);
15597
15598 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15599 emit_insn (gen_andsi3 (operands[0],
15600 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15601 }
15602 DONE;
15603 })
15604
15605 (define_expand "signbitsf2"
15606 [(use (match_operand:SI 0 "register_operand" ""))
15607 (use (match_operand:SF 1 "register_operand" ""))]
15608 "TARGET_USE_FANCY_MATH_387
15609 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15610 {
15611 rtx scratch = gen_reg_rtx (HImode);
15612
15613 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15614 emit_insn (gen_andsi3 (operands[0],
15615 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15616 DONE;
15617 })
15618 \f
15619 ;; Block operation instructions
15620
15621 (define_insn "cld"
15622 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15623 ""
15624 "cld"
15625 [(set_attr "length" "1")
15626 (set_attr "length_immediate" "0")
15627 (set_attr "modrm" "0")])
15628
15629 (define_expand "movmem<mode>"
15630 [(use (match_operand:BLK 0 "memory_operand" ""))
15631 (use (match_operand:BLK 1 "memory_operand" ""))
15632 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15633 (use (match_operand:SWI48 3 "const_int_operand" ""))
15634 (use (match_operand:SI 4 "const_int_operand" ""))
15635 (use (match_operand:SI 5 "const_int_operand" ""))]
15636 ""
15637 {
15638 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15639 operands[4], operands[5]))
15640 DONE;
15641 else
15642 FAIL;
15643 })
15644
15645 ;; Most CPUs don't like single string operations
15646 ;; Handle this case here to simplify previous expander.
15647
15648 (define_expand "strmov"
15649 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15650 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15651 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15652 (clobber (reg:CC FLAGS_REG))])
15653 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15654 (clobber (reg:CC FLAGS_REG))])]
15655 ""
15656 {
15657 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15658
15659 /* If .md ever supports :P for Pmode, these can be directly
15660 in the pattern above. */
15661 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15662 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15663
15664 /* Can't use this if the user has appropriated esi or edi. */
15665 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15666 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15667 {
15668 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15669 operands[2], operands[3],
15670 operands[5], operands[6]));
15671 DONE;
15672 }
15673
15674 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15675 })
15676
15677 (define_expand "strmov_singleop"
15678 [(parallel [(set (match_operand 1 "memory_operand" "")
15679 (match_operand 3 "memory_operand" ""))
15680 (set (match_operand 0 "register_operand" "")
15681 (match_operand 4 "" ""))
15682 (set (match_operand 2 "register_operand" "")
15683 (match_operand 5 "" ""))])]
15684 ""
15685 "ix86_current_function_needs_cld = 1;")
15686
15687 (define_insn "*strmovdi_rex_1"
15688 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15689 (mem:DI (match_operand:P 3 "register_operand" "1")))
15690 (set (match_operand:P 0 "register_operand" "=D")
15691 (plus:P (match_dup 2)
15692 (const_int 8)))
15693 (set (match_operand:P 1 "register_operand" "=S")
15694 (plus:P (match_dup 3)
15695 (const_int 8)))]
15696 "TARGET_64BIT
15697 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15698 "%^movsq"
15699 [(set_attr "type" "str")
15700 (set_attr "memory" "both")
15701 (set_attr "mode" "DI")])
15702
15703 (define_insn "*strmovsi_1"
15704 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15705 (mem:SI (match_operand:P 3 "register_operand" "1")))
15706 (set (match_operand:P 0 "register_operand" "=D")
15707 (plus:P (match_dup 2)
15708 (const_int 4)))
15709 (set (match_operand:P 1 "register_operand" "=S")
15710 (plus:P (match_dup 3)
15711 (const_int 4)))]
15712 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15713 "%^movs{l|d}"
15714 [(set_attr "type" "str")
15715 (set_attr "memory" "both")
15716 (set_attr "mode" "SI")])
15717
15718 (define_insn "*strmovhi_1"
15719 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15720 (mem:HI (match_operand:P 3 "register_operand" "1")))
15721 (set (match_operand:P 0 "register_operand" "=D")
15722 (plus:P (match_dup 2)
15723 (const_int 2)))
15724 (set (match_operand:P 1 "register_operand" "=S")
15725 (plus:P (match_dup 3)
15726 (const_int 2)))]
15727 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15728 "%^movsw"
15729 [(set_attr "type" "str")
15730 (set_attr "memory" "both")
15731 (set_attr "mode" "HI")])
15732
15733 (define_insn "*strmovqi_1"
15734 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15735 (mem:QI (match_operand:P 3 "register_operand" "1")))
15736 (set (match_operand:P 0 "register_operand" "=D")
15737 (plus:P (match_dup 2)
15738 (const_int 1)))
15739 (set (match_operand:P 1 "register_operand" "=S")
15740 (plus:P (match_dup 3)
15741 (const_int 1)))]
15742 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15743 "%^movsb"
15744 [(set_attr "type" "str")
15745 (set_attr "memory" "both")
15746 (set (attr "prefix_rex")
15747 (if_then_else
15748 (match_test "<P:MODE>mode == DImode")
15749 (const_string "0")
15750 (const_string "*")))
15751 (set_attr "mode" "QI")])
15752
15753 (define_expand "rep_mov"
15754 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15755 (set (match_operand 0 "register_operand" "")
15756 (match_operand 5 "" ""))
15757 (set (match_operand 2 "register_operand" "")
15758 (match_operand 6 "" ""))
15759 (set (match_operand 1 "memory_operand" "")
15760 (match_operand 3 "memory_operand" ""))
15761 (use (match_dup 4))])]
15762 ""
15763 "ix86_current_function_needs_cld = 1;")
15764
15765 (define_insn "*rep_movdi_rex64"
15766 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15769 (const_int 3))
15770 (match_operand:P 3 "register_operand" "0")))
15771 (set (match_operand:P 1 "register_operand" "=S")
15772 (plus:P (ashift:P (match_dup 5) (const_int 3))
15773 (match_operand:P 4 "register_operand" "1")))
15774 (set (mem:BLK (match_dup 3))
15775 (mem:BLK (match_dup 4)))
15776 (use (match_dup 5))]
15777 "TARGET_64BIT
15778 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15779 "%^rep{%;} movsq"
15780 [(set_attr "type" "str")
15781 (set_attr "prefix_rep" "1")
15782 (set_attr "memory" "both")
15783 (set_attr "mode" "DI")])
15784
15785 (define_insn "*rep_movsi"
15786 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15787 (set (match_operand:P 0 "register_operand" "=D")
15788 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15789 (const_int 2))
15790 (match_operand:P 3 "register_operand" "0")))
15791 (set (match_operand:P 1 "register_operand" "=S")
15792 (plus:P (ashift:P (match_dup 5) (const_int 2))
15793 (match_operand:P 4 "register_operand" "1")))
15794 (set (mem:BLK (match_dup 3))
15795 (mem:BLK (match_dup 4)))
15796 (use (match_dup 5))]
15797 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15798 "%^rep{%;} movs{l|d}"
15799 [(set_attr "type" "str")
15800 (set_attr "prefix_rep" "1")
15801 (set_attr "memory" "both")
15802 (set_attr "mode" "SI")])
15803
15804 (define_insn "*rep_movqi"
15805 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15806 (set (match_operand:P 0 "register_operand" "=D")
15807 (plus:P (match_operand:P 3 "register_operand" "0")
15808 (match_operand:P 5 "register_operand" "2")))
15809 (set (match_operand:P 1 "register_operand" "=S")
15810 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15811 (set (mem:BLK (match_dup 3))
15812 (mem:BLK (match_dup 4)))
15813 (use (match_dup 5))]
15814 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15815 "%^rep{%;} movsb"
15816 [(set_attr "type" "str")
15817 (set_attr "prefix_rep" "1")
15818 (set_attr "memory" "both")
15819 (set_attr "mode" "QI")])
15820
15821 (define_expand "setmem<mode>"
15822 [(use (match_operand:BLK 0 "memory_operand" ""))
15823 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15824 (use (match_operand:QI 2 "nonmemory_operand" ""))
15825 (use (match_operand 3 "const_int_operand" ""))
15826 (use (match_operand:SI 4 "const_int_operand" ""))
15827 (use (match_operand:SI 5 "const_int_operand" ""))]
15828 ""
15829 {
15830 if (ix86_expand_setmem (operands[0], operands[1],
15831 operands[2], operands[3],
15832 operands[4], operands[5]))
15833 DONE;
15834 else
15835 FAIL;
15836 })
15837
15838 ;; Most CPUs don't like single string operations
15839 ;; Handle this case here to simplify previous expander.
15840
15841 (define_expand "strset"
15842 [(set (match_operand 1 "memory_operand" "")
15843 (match_operand 2 "register_operand" ""))
15844 (parallel [(set (match_operand 0 "register_operand" "")
15845 (match_dup 3))
15846 (clobber (reg:CC FLAGS_REG))])]
15847 ""
15848 {
15849 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15850 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15851
15852 /* If .md ever supports :P for Pmode, this can be directly
15853 in the pattern above. */
15854 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15855 GEN_INT (GET_MODE_SIZE (GET_MODE
15856 (operands[2]))));
15857 /* Can't use this if the user has appropriated eax or edi. */
15858 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15859 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15860 {
15861 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15862 operands[3]));
15863 DONE;
15864 }
15865 })
15866
15867 (define_expand "strset_singleop"
15868 [(parallel [(set (match_operand 1 "memory_operand" "")
15869 (match_operand 2 "register_operand" ""))
15870 (set (match_operand 0 "register_operand" "")
15871 (match_operand 3 "" ""))])]
15872 ""
15873 "ix86_current_function_needs_cld = 1;")
15874
15875 (define_insn "*strsetdi_rex_1"
15876 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15877 (match_operand:DI 2 "register_operand" "a"))
15878 (set (match_operand:P 0 "register_operand" "=D")
15879 (plus:P (match_dup 1)
15880 (const_int 8)))]
15881 "TARGET_64BIT
15882 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15883 "%^stosq"
15884 [(set_attr "type" "str")
15885 (set_attr "memory" "store")
15886 (set_attr "mode" "DI")])
15887
15888 (define_insn "*strsetsi_1"
15889 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15890 (match_operand:SI 2 "register_operand" "a"))
15891 (set (match_operand:P 0 "register_operand" "=D")
15892 (plus:P (match_dup 1)
15893 (const_int 4)))]
15894 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15895 "%^stos{l|d}"
15896 [(set_attr "type" "str")
15897 (set_attr "memory" "store")
15898 (set_attr "mode" "SI")])
15899
15900 (define_insn "*strsethi_1"
15901 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15902 (match_operand:HI 2 "register_operand" "a"))
15903 (set (match_operand:P 0 "register_operand" "=D")
15904 (plus:P (match_dup 1)
15905 (const_int 2)))]
15906 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15907 "%^stosw"
15908 [(set_attr "type" "str")
15909 (set_attr "memory" "store")
15910 (set_attr "mode" "HI")])
15911
15912 (define_insn "*strsetqi_1"
15913 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15914 (match_operand:QI 2 "register_operand" "a"))
15915 (set (match_operand:P 0 "register_operand" "=D")
15916 (plus:P (match_dup 1)
15917 (const_int 1)))]
15918 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15919 "%^stosb"
15920 [(set_attr "type" "str")
15921 (set_attr "memory" "store")
15922 (set (attr "prefix_rex")
15923 (if_then_else
15924 (match_test "<P:MODE>mode == DImode")
15925 (const_string "0")
15926 (const_string "*")))
15927 (set_attr "mode" "QI")])
15928
15929 (define_expand "rep_stos"
15930 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15931 (set (match_operand 0 "register_operand" "")
15932 (match_operand 4 "" ""))
15933 (set (match_operand 2 "memory_operand" "") (const_int 0))
15934 (use (match_operand 3 "register_operand" ""))
15935 (use (match_dup 1))])]
15936 ""
15937 "ix86_current_function_needs_cld = 1;")
15938
15939 (define_insn "*rep_stosdi_rex64"
15940 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15941 (set (match_operand:P 0 "register_operand" "=D")
15942 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15943 (const_int 3))
15944 (match_operand:P 3 "register_operand" "0")))
15945 (set (mem:BLK (match_dup 3))
15946 (const_int 0))
15947 (use (match_operand:DI 2 "register_operand" "a"))
15948 (use (match_dup 4))]
15949 "TARGET_64BIT
15950 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15951 "%^rep{%;} stosq"
15952 [(set_attr "type" "str")
15953 (set_attr "prefix_rep" "1")
15954 (set_attr "memory" "store")
15955 (set_attr "mode" "DI")])
15956
15957 (define_insn "*rep_stossi"
15958 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15959 (set (match_operand:P 0 "register_operand" "=D")
15960 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15961 (const_int 2))
15962 (match_operand:P 3 "register_operand" "0")))
15963 (set (mem:BLK (match_dup 3))
15964 (const_int 0))
15965 (use (match_operand:SI 2 "register_operand" "a"))
15966 (use (match_dup 4))]
15967 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15968 "%^rep{%;} stos{l|d}"
15969 [(set_attr "type" "str")
15970 (set_attr "prefix_rep" "1")
15971 (set_attr "memory" "store")
15972 (set_attr "mode" "SI")])
15973
15974 (define_insn "*rep_stosqi"
15975 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15976 (set (match_operand:P 0 "register_operand" "=D")
15977 (plus:P (match_operand:P 3 "register_operand" "0")
15978 (match_operand:P 4 "register_operand" "1")))
15979 (set (mem:BLK (match_dup 3))
15980 (const_int 0))
15981 (use (match_operand:QI 2 "register_operand" "a"))
15982 (use (match_dup 4))]
15983 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15984 "%^rep{%;} stosb"
15985 [(set_attr "type" "str")
15986 (set_attr "prefix_rep" "1")
15987 (set_attr "memory" "store")
15988 (set (attr "prefix_rex")
15989 (if_then_else
15990 (match_test "<P:MODE>mode == DImode")
15991 (const_string "0")
15992 (const_string "*")))
15993 (set_attr "mode" "QI")])
15994
15995 (define_expand "cmpstrnsi"
15996 [(set (match_operand:SI 0 "register_operand" "")
15997 (compare:SI (match_operand:BLK 1 "general_operand" "")
15998 (match_operand:BLK 2 "general_operand" "")))
15999 (use (match_operand 3 "general_operand" ""))
16000 (use (match_operand 4 "immediate_operand" ""))]
16001 ""
16002 {
16003 rtx addr1, addr2, out, outlow, count, countreg, align;
16004
16005 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16006 FAIL;
16007
16008 /* Can't use this if the user has appropriated ecx, esi or edi. */
16009 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16010 FAIL;
16011
16012 out = operands[0];
16013 if (!REG_P (out))
16014 out = gen_reg_rtx (SImode);
16015
16016 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16017 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16018 if (addr1 != XEXP (operands[1], 0))
16019 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16020 if (addr2 != XEXP (operands[2], 0))
16021 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16022
16023 count = operands[3];
16024 countreg = ix86_zero_extend_to_Pmode (count);
16025
16026 /* %%% Iff we are testing strict equality, we can use known alignment
16027 to good advantage. This may be possible with combine, particularly
16028 once cc0 is dead. */
16029 align = operands[4];
16030
16031 if (CONST_INT_P (count))
16032 {
16033 if (INTVAL (count) == 0)
16034 {
16035 emit_move_insn (operands[0], const0_rtx);
16036 DONE;
16037 }
16038 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16039 operands[1], operands[2]));
16040 }
16041 else
16042 {
16043 rtx (*gen_cmp) (rtx, rtx);
16044
16045 gen_cmp = (TARGET_64BIT
16046 ? gen_cmpdi_1 : gen_cmpsi_1);
16047
16048 emit_insn (gen_cmp (countreg, countreg));
16049 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16050 operands[1], operands[2]));
16051 }
16052
16053 outlow = gen_lowpart (QImode, out);
16054 emit_insn (gen_cmpintqi (outlow));
16055 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16056
16057 if (operands[0] != out)
16058 emit_move_insn (operands[0], out);
16059
16060 DONE;
16061 })
16062
16063 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16064
16065 (define_expand "cmpintqi"
16066 [(set (match_dup 1)
16067 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16068 (set (match_dup 2)
16069 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16070 (parallel [(set (match_operand:QI 0 "register_operand" "")
16071 (minus:QI (match_dup 1)
16072 (match_dup 2)))
16073 (clobber (reg:CC FLAGS_REG))])]
16074 ""
16075 {
16076 operands[1] = gen_reg_rtx (QImode);
16077 operands[2] = gen_reg_rtx (QImode);
16078 })
16079
16080 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16081 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16082
16083 (define_expand "cmpstrnqi_nz_1"
16084 [(parallel [(set (reg:CC FLAGS_REG)
16085 (compare:CC (match_operand 4 "memory_operand" "")
16086 (match_operand 5 "memory_operand" "")))
16087 (use (match_operand 2 "register_operand" ""))
16088 (use (match_operand:SI 3 "immediate_operand" ""))
16089 (clobber (match_operand 0 "register_operand" ""))
16090 (clobber (match_operand 1 "register_operand" ""))
16091 (clobber (match_dup 2))])]
16092 ""
16093 "ix86_current_function_needs_cld = 1;")
16094
16095 (define_insn "*cmpstrnqi_nz_1"
16096 [(set (reg:CC FLAGS_REG)
16097 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16098 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16099 (use (match_operand:P 6 "register_operand" "2"))
16100 (use (match_operand:SI 3 "immediate_operand" "i"))
16101 (clobber (match_operand:P 0 "register_operand" "=S"))
16102 (clobber (match_operand:P 1 "register_operand" "=D"))
16103 (clobber (match_operand:P 2 "register_operand" "=c"))]
16104 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16105 "%^repz{%;} cmpsb"
16106 [(set_attr "type" "str")
16107 (set_attr "mode" "QI")
16108 (set (attr "prefix_rex")
16109 (if_then_else
16110 (match_test "<P:MODE>mode == DImode")
16111 (const_string "0")
16112 (const_string "*")))
16113 (set_attr "prefix_rep" "1")])
16114
16115 ;; The same, but the count is not known to not be zero.
16116
16117 (define_expand "cmpstrnqi_1"
16118 [(parallel [(set (reg:CC FLAGS_REG)
16119 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16120 (const_int 0))
16121 (compare:CC (match_operand 4 "memory_operand" "")
16122 (match_operand 5 "memory_operand" ""))
16123 (const_int 0)))
16124 (use (match_operand:SI 3 "immediate_operand" ""))
16125 (use (reg:CC FLAGS_REG))
16126 (clobber (match_operand 0 "register_operand" ""))
16127 (clobber (match_operand 1 "register_operand" ""))
16128 (clobber (match_dup 2))])]
16129 ""
16130 "ix86_current_function_needs_cld = 1;")
16131
16132 (define_insn "*cmpstrnqi_1"
16133 [(set (reg:CC FLAGS_REG)
16134 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16135 (const_int 0))
16136 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16137 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16138 (const_int 0)))
16139 (use (match_operand:SI 3 "immediate_operand" "i"))
16140 (use (reg:CC FLAGS_REG))
16141 (clobber (match_operand:P 0 "register_operand" "=S"))
16142 (clobber (match_operand:P 1 "register_operand" "=D"))
16143 (clobber (match_operand:P 2 "register_operand" "=c"))]
16144 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16145 "%^repz{%;} cmpsb"
16146 [(set_attr "type" "str")
16147 (set_attr "mode" "QI")
16148 (set (attr "prefix_rex")
16149 (if_then_else
16150 (match_test "<P:MODE>mode == DImode")
16151 (const_string "0")
16152 (const_string "*")))
16153 (set_attr "prefix_rep" "1")])
16154
16155 (define_expand "strlen<mode>"
16156 [(set (match_operand:P 0 "register_operand" "")
16157 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16158 (match_operand:QI 2 "immediate_operand" "")
16159 (match_operand 3 "immediate_operand" "")]
16160 UNSPEC_SCAS))]
16161 ""
16162 {
16163 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16164 DONE;
16165 else
16166 FAIL;
16167 })
16168
16169 (define_expand "strlenqi_1"
16170 [(parallel [(set (match_operand 0 "register_operand" "")
16171 (match_operand 2 "" ""))
16172 (clobber (match_operand 1 "register_operand" ""))
16173 (clobber (reg:CC FLAGS_REG))])]
16174 ""
16175 "ix86_current_function_needs_cld = 1;")
16176
16177 (define_insn "*strlenqi_1"
16178 [(set (match_operand:P 0 "register_operand" "=&c")
16179 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16180 (match_operand:QI 2 "register_operand" "a")
16181 (match_operand:P 3 "immediate_operand" "i")
16182 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16183 (clobber (match_operand:P 1 "register_operand" "=D"))
16184 (clobber (reg:CC FLAGS_REG))]
16185 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16186 "%^repnz{%;} scasb"
16187 [(set_attr "type" "str")
16188 (set_attr "mode" "QI")
16189 (set (attr "prefix_rex")
16190 (if_then_else
16191 (match_test "<P:MODE>mode == DImode")
16192 (const_string "0")
16193 (const_string "*")))
16194 (set_attr "prefix_rep" "1")])
16195
16196 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16197 ;; handled in combine, but it is not currently up to the task.
16198 ;; When used for their truth value, the cmpstrn* expanders generate
16199 ;; code like this:
16200 ;;
16201 ;; repz cmpsb
16202 ;; seta %al
16203 ;; setb %dl
16204 ;; cmpb %al, %dl
16205 ;; jcc label
16206 ;;
16207 ;; The intermediate three instructions are unnecessary.
16208
16209 ;; This one handles cmpstrn*_nz_1...
16210 (define_peephole2
16211 [(parallel[
16212 (set (reg:CC FLAGS_REG)
16213 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16214 (mem:BLK (match_operand 5 "register_operand" ""))))
16215 (use (match_operand 6 "register_operand" ""))
16216 (use (match_operand:SI 3 "immediate_operand" ""))
16217 (clobber (match_operand 0 "register_operand" ""))
16218 (clobber (match_operand 1 "register_operand" ""))
16219 (clobber (match_operand 2 "register_operand" ""))])
16220 (set (match_operand:QI 7 "register_operand" "")
16221 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16222 (set (match_operand:QI 8 "register_operand" "")
16223 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16224 (set (reg FLAGS_REG)
16225 (compare (match_dup 7) (match_dup 8)))
16226 ]
16227 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16228 [(parallel[
16229 (set (reg:CC FLAGS_REG)
16230 (compare:CC (mem:BLK (match_dup 4))
16231 (mem:BLK (match_dup 5))))
16232 (use (match_dup 6))
16233 (use (match_dup 3))
16234 (clobber (match_dup 0))
16235 (clobber (match_dup 1))
16236 (clobber (match_dup 2))])])
16237
16238 ;; ...and this one handles cmpstrn*_1.
16239 (define_peephole2
16240 [(parallel[
16241 (set (reg:CC FLAGS_REG)
16242 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16243 (const_int 0))
16244 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16245 (mem:BLK (match_operand 5 "register_operand" "")))
16246 (const_int 0)))
16247 (use (match_operand:SI 3 "immediate_operand" ""))
16248 (use (reg:CC FLAGS_REG))
16249 (clobber (match_operand 0 "register_operand" ""))
16250 (clobber (match_operand 1 "register_operand" ""))
16251 (clobber (match_operand 2 "register_operand" ""))])
16252 (set (match_operand:QI 7 "register_operand" "")
16253 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16254 (set (match_operand:QI 8 "register_operand" "")
16255 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16256 (set (reg FLAGS_REG)
16257 (compare (match_dup 7) (match_dup 8)))
16258 ]
16259 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16260 [(parallel[
16261 (set (reg:CC FLAGS_REG)
16262 (if_then_else:CC (ne (match_dup 6)
16263 (const_int 0))
16264 (compare:CC (mem:BLK (match_dup 4))
16265 (mem:BLK (match_dup 5)))
16266 (const_int 0)))
16267 (use (match_dup 3))
16268 (use (reg:CC FLAGS_REG))
16269 (clobber (match_dup 0))
16270 (clobber (match_dup 1))
16271 (clobber (match_dup 2))])])
16272 \f
16273 ;; Conditional move instructions.
16274
16275 (define_expand "mov<mode>cc"
16276 [(set (match_operand:SWIM 0 "register_operand" "")
16277 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16278 (match_operand:SWIM 2 "<general_operand>" "")
16279 (match_operand:SWIM 3 "<general_operand>" "")))]
16280 ""
16281 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16282
16283 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16284 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16285 ;; So just document what we're doing explicitly.
16286
16287 (define_expand "x86_mov<mode>cc_0_m1"
16288 [(parallel
16289 [(set (match_operand:SWI48 0 "register_operand" "")
16290 (if_then_else:SWI48
16291 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16292 [(match_operand 1 "flags_reg_operand" "")
16293 (const_int 0)])
16294 (const_int -1)
16295 (const_int 0)))
16296 (clobber (reg:CC FLAGS_REG))])])
16297
16298 (define_insn "*x86_mov<mode>cc_0_m1"
16299 [(set (match_operand:SWI48 0 "register_operand" "=r")
16300 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16301 [(reg FLAGS_REG) (const_int 0)])
16302 (const_int -1)
16303 (const_int 0)))
16304 (clobber (reg:CC FLAGS_REG))]
16305 ""
16306 "sbb{<imodesuffix>}\t%0, %0"
16307 ; Since we don't have the proper number of operands for an alu insn,
16308 ; fill in all the blanks.
16309 [(set_attr "type" "alu")
16310 (set_attr "use_carry" "1")
16311 (set_attr "pent_pair" "pu")
16312 (set_attr "memory" "none")
16313 (set_attr "imm_disp" "false")
16314 (set_attr "mode" "<MODE>")
16315 (set_attr "length_immediate" "0")])
16316
16317 (define_insn "*x86_mov<mode>cc_0_m1_se"
16318 [(set (match_operand:SWI48 0 "register_operand" "=r")
16319 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16320 [(reg FLAGS_REG) (const_int 0)])
16321 (const_int 1)
16322 (const_int 0)))
16323 (clobber (reg:CC FLAGS_REG))]
16324 ""
16325 "sbb{<imodesuffix>}\t%0, %0"
16326 [(set_attr "type" "alu")
16327 (set_attr "use_carry" "1")
16328 (set_attr "pent_pair" "pu")
16329 (set_attr "memory" "none")
16330 (set_attr "imm_disp" "false")
16331 (set_attr "mode" "<MODE>")
16332 (set_attr "length_immediate" "0")])
16333
16334 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16335 [(set (match_operand:SWI48 0 "register_operand" "=r")
16336 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16337 [(reg FLAGS_REG) (const_int 0)])))]
16338 ""
16339 "sbb{<imodesuffix>}\t%0, %0"
16340 [(set_attr "type" "alu")
16341 (set_attr "use_carry" "1")
16342 (set_attr "pent_pair" "pu")
16343 (set_attr "memory" "none")
16344 (set_attr "imm_disp" "false")
16345 (set_attr "mode" "<MODE>")
16346 (set_attr "length_immediate" "0")])
16347
16348 (define_insn "*mov<mode>cc_noc"
16349 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16350 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16351 [(reg FLAGS_REG) (const_int 0)])
16352 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16353 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16354 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16355 "@
16356 cmov%O2%C1\t{%2, %0|%0, %2}
16357 cmov%O2%c1\t{%3, %0|%0, %3}"
16358 [(set_attr "type" "icmov")
16359 (set_attr "mode" "<MODE>")])
16360
16361 (define_insn_and_split "*movqicc_noc"
16362 [(set (match_operand:QI 0 "register_operand" "=r,r")
16363 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16364 [(match_operand 4 "flags_reg_operand" "")
16365 (const_int 0)])
16366 (match_operand:QI 2 "register_operand" "r,0")
16367 (match_operand:QI 3 "register_operand" "0,r")))]
16368 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16369 "#"
16370 "&& reload_completed"
16371 [(set (match_dup 0)
16372 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16373 (match_dup 2)
16374 (match_dup 3)))]
16375 "operands[0] = gen_lowpart (SImode, operands[0]);
16376 operands[2] = gen_lowpart (SImode, operands[2]);
16377 operands[3] = gen_lowpart (SImode, operands[3]);"
16378 [(set_attr "type" "icmov")
16379 (set_attr "mode" "SI")])
16380
16381 (define_expand "mov<mode>cc"
16382 [(set (match_operand:X87MODEF 0 "register_operand" "")
16383 (if_then_else:X87MODEF
16384 (match_operand 1 "ix86_fp_comparison_operator" "")
16385 (match_operand:X87MODEF 2 "register_operand" "")
16386 (match_operand:X87MODEF 3 "register_operand" "")))]
16387 "(TARGET_80387 && TARGET_CMOVE)
16388 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16389 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16390
16391 (define_insn "*movxfcc_1"
16392 [(set (match_operand:XF 0 "register_operand" "=f,f")
16393 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16394 [(reg FLAGS_REG) (const_int 0)])
16395 (match_operand:XF 2 "register_operand" "f,0")
16396 (match_operand:XF 3 "register_operand" "0,f")))]
16397 "TARGET_80387 && TARGET_CMOVE"
16398 "@
16399 fcmov%F1\t{%2, %0|%0, %2}
16400 fcmov%f1\t{%3, %0|%0, %3}"
16401 [(set_attr "type" "fcmov")
16402 (set_attr "mode" "XF")])
16403
16404 (define_insn "*movdfcc_1_rex64"
16405 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16406 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16407 [(reg FLAGS_REG) (const_int 0)])
16408 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16409 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16410 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16411 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16412 "@
16413 fcmov%F1\t{%2, %0|%0, %2}
16414 fcmov%f1\t{%3, %0|%0, %3}
16415 cmov%O2%C1\t{%2, %0|%0, %2}
16416 cmov%O2%c1\t{%3, %0|%0, %3}"
16417 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16418 (set_attr "mode" "DF,DF,DI,DI")])
16419
16420 (define_insn "*movdfcc_1"
16421 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16422 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16423 [(reg FLAGS_REG) (const_int 0)])
16424 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16425 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16426 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16427 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16428 "@
16429 fcmov%F1\t{%2, %0|%0, %2}
16430 fcmov%f1\t{%3, %0|%0, %3}
16431 #
16432 #"
16433 [(set_attr "type" "fcmov,fcmov,multi,multi")
16434 (set_attr "mode" "DF,DF,DI,DI")])
16435
16436 (define_split
16437 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16438 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16439 [(match_operand 4 "flags_reg_operand" "")
16440 (const_int 0)])
16441 (match_operand:DF 2 "nonimmediate_operand" "")
16442 (match_operand:DF 3 "nonimmediate_operand" "")))]
16443 "!TARGET_64BIT && reload_completed"
16444 [(set (match_dup 2)
16445 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16446 (match_dup 5)
16447 (match_dup 6)))
16448 (set (match_dup 3)
16449 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16450 (match_dup 7)
16451 (match_dup 8)))]
16452 {
16453 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16454 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16455 })
16456
16457 (define_insn "*movsfcc_1_387"
16458 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16459 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16460 [(reg FLAGS_REG) (const_int 0)])
16461 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16462 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16463 "TARGET_80387 && TARGET_CMOVE
16464 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16465 "@
16466 fcmov%F1\t{%2, %0|%0, %2}
16467 fcmov%f1\t{%3, %0|%0, %3}
16468 cmov%O2%C1\t{%2, %0|%0, %2}
16469 cmov%O2%c1\t{%3, %0|%0, %3}"
16470 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16471 (set_attr "mode" "SF,SF,SI,SI")])
16472
16473 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16474 ;; the scalar versions to have only XMM registers as operands.
16475
16476 ;; XOP conditional move
16477 (define_insn "*xop_pcmov_<mode>"
16478 [(set (match_operand:MODEF 0 "register_operand" "=x")
16479 (if_then_else:MODEF
16480 (match_operand:MODEF 1 "register_operand" "x")
16481 (match_operand:MODEF 2 "register_operand" "x")
16482 (match_operand:MODEF 3 "register_operand" "x")))]
16483 "TARGET_XOP"
16484 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16485 [(set_attr "type" "sse4arg")])
16486
16487 ;; These versions of the min/max patterns are intentionally ignorant of
16488 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16489 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16490 ;; are undefined in this condition, we're certain this is correct.
16491
16492 (define_insn "<code><mode>3"
16493 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16494 (smaxmin:MODEF
16495 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16496 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16497 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16498 "@
16499 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16500 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16501 [(set_attr "isa" "noavx,avx")
16502 (set_attr "prefix" "orig,vex")
16503 (set_attr "type" "sseadd")
16504 (set_attr "mode" "<MODE>")])
16505
16506 ;; These versions of the min/max patterns implement exactly the operations
16507 ;; min = (op1 < op2 ? op1 : op2)
16508 ;; max = (!(op1 < op2) ? op1 : op2)
16509 ;; Their operands are not commutative, and thus they may be used in the
16510 ;; presence of -0.0 and NaN.
16511
16512 (define_insn "*ieee_smin<mode>3"
16513 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16514 (unspec:MODEF
16515 [(match_operand:MODEF 1 "register_operand" "0,x")
16516 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16517 UNSPEC_IEEE_MIN))]
16518 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16519 "@
16520 min<ssemodesuffix>\t{%2, %0|%0, %2}
16521 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16522 [(set_attr "isa" "noavx,avx")
16523 (set_attr "prefix" "orig,vex")
16524 (set_attr "type" "sseadd")
16525 (set_attr "mode" "<MODE>")])
16526
16527 (define_insn "*ieee_smax<mode>3"
16528 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16529 (unspec:MODEF
16530 [(match_operand:MODEF 1 "register_operand" "0,x")
16531 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16532 UNSPEC_IEEE_MAX))]
16533 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16534 "@
16535 max<ssemodesuffix>\t{%2, %0|%0, %2}
16536 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16537 [(set_attr "isa" "noavx,avx")
16538 (set_attr "prefix" "orig,vex")
16539 (set_attr "type" "sseadd")
16540 (set_attr "mode" "<MODE>")])
16541
16542 ;; Make two stack loads independent:
16543 ;; fld aa fld aa
16544 ;; fld %st(0) -> fld bb
16545 ;; fmul bb fmul %st(1), %st
16546 ;;
16547 ;; Actually we only match the last two instructions for simplicity.
16548 (define_peephole2
16549 [(set (match_operand 0 "fp_register_operand" "")
16550 (match_operand 1 "fp_register_operand" ""))
16551 (set (match_dup 0)
16552 (match_operator 2 "binary_fp_operator"
16553 [(match_dup 0)
16554 (match_operand 3 "memory_operand" "")]))]
16555 "REGNO (operands[0]) != REGNO (operands[1])"
16556 [(set (match_dup 0) (match_dup 3))
16557 (set (match_dup 0) (match_dup 4))]
16558
16559 ;; The % modifier is not operational anymore in peephole2's, so we have to
16560 ;; swap the operands manually in the case of addition and multiplication.
16561 {
16562 rtx op0, op1;
16563
16564 if (COMMUTATIVE_ARITH_P (operands[2]))
16565 op0 = operands[0], op1 = operands[1];
16566 else
16567 op0 = operands[1], op1 = operands[0];
16568
16569 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16570 GET_MODE (operands[2]),
16571 op0, op1);
16572 })
16573
16574 ;; Conditional addition patterns
16575 (define_expand "add<mode>cc"
16576 [(match_operand:SWI 0 "register_operand" "")
16577 (match_operand 1 "ordered_comparison_operator" "")
16578 (match_operand:SWI 2 "register_operand" "")
16579 (match_operand:SWI 3 "const_int_operand" "")]
16580 ""
16581 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16582 \f
16583 ;; Misc patterns (?)
16584
16585 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16586 ;; Otherwise there will be nothing to keep
16587 ;;
16588 ;; [(set (reg ebp) (reg esp))]
16589 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16590 ;; (clobber (eflags)]
16591 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16592 ;;
16593 ;; in proper program order.
16594
16595 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16596 [(set (match_operand:P 0 "register_operand" "=r,r")
16597 (plus:P (match_operand:P 1 "register_operand" "0,r")
16598 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16599 (clobber (reg:CC FLAGS_REG))
16600 (clobber (mem:BLK (scratch)))]
16601 ""
16602 {
16603 switch (get_attr_type (insn))
16604 {
16605 case TYPE_IMOV:
16606 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16607
16608 case TYPE_ALU:
16609 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16610 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16611 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16612
16613 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16614
16615 default:
16616 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16617 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16618 }
16619 }
16620 [(set (attr "type")
16621 (cond [(and (eq_attr "alternative" "0")
16622 (not (match_test "TARGET_OPT_AGU")))
16623 (const_string "alu")
16624 (match_operand:<MODE> 2 "const0_operand" "")
16625 (const_string "imov")
16626 ]
16627 (const_string "lea")))
16628 (set (attr "length_immediate")
16629 (cond [(eq_attr "type" "imov")
16630 (const_string "0")
16631 (and (eq_attr "type" "alu")
16632 (match_operand 2 "const128_operand" ""))
16633 (const_string "1")
16634 ]
16635 (const_string "*")))
16636 (set_attr "mode" "<MODE>")])
16637
16638 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16639 [(set (match_operand:P 0 "register_operand" "=r")
16640 (minus:P (match_operand:P 1 "register_operand" "0")
16641 (match_operand:P 2 "register_operand" "r")))
16642 (clobber (reg:CC FLAGS_REG))
16643 (clobber (mem:BLK (scratch)))]
16644 ""
16645 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16646 [(set_attr "type" "alu")
16647 (set_attr "mode" "<MODE>")])
16648
16649 (define_insn "allocate_stack_worker_probe_<mode>"
16650 [(set (match_operand:P 0 "register_operand" "=a")
16651 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16652 UNSPECV_STACK_PROBE))
16653 (clobber (reg:CC FLAGS_REG))]
16654 "ix86_target_stack_probe ()"
16655 "call\t___chkstk_ms"
16656 [(set_attr "type" "multi")
16657 (set_attr "length" "5")])
16658
16659 (define_expand "allocate_stack"
16660 [(match_operand 0 "register_operand" "")
16661 (match_operand 1 "general_operand" "")]
16662 "ix86_target_stack_probe ()"
16663 {
16664 rtx x;
16665
16666 #ifndef CHECK_STACK_LIMIT
16667 #define CHECK_STACK_LIMIT 0
16668 #endif
16669
16670 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16671 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16672 {
16673 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16674 stack_pointer_rtx, 0, OPTAB_DIRECT);
16675 if (x != stack_pointer_rtx)
16676 emit_move_insn (stack_pointer_rtx, x);
16677 }
16678 else
16679 {
16680 x = copy_to_mode_reg (Pmode, operands[1]);
16681 if (TARGET_64BIT)
16682 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16683 else
16684 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16685 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16686 stack_pointer_rtx, 0, OPTAB_DIRECT);
16687 if (x != stack_pointer_rtx)
16688 emit_move_insn (stack_pointer_rtx, x);
16689 }
16690
16691 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16692 DONE;
16693 })
16694
16695 ;; Use IOR for stack probes, this is shorter.
16696 (define_expand "probe_stack"
16697 [(match_operand 0 "memory_operand" "")]
16698 ""
16699 {
16700 rtx (*gen_ior3) (rtx, rtx, rtx);
16701
16702 gen_ior3 = (GET_MODE (operands[0]) == DImode
16703 ? gen_iordi3 : gen_iorsi3);
16704
16705 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16706 DONE;
16707 })
16708
16709 (define_insn "adjust_stack_and_probe<mode>"
16710 [(set (match_operand:P 0 "register_operand" "=r")
16711 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16712 UNSPECV_PROBE_STACK_RANGE))
16713 (set (reg:P SP_REG)
16714 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16715 (clobber (reg:CC FLAGS_REG))
16716 (clobber (mem:BLK (scratch)))]
16717 ""
16718 "* return output_adjust_stack_and_probe (operands[0]);"
16719 [(set_attr "type" "multi")])
16720
16721 (define_insn "probe_stack_range<mode>"
16722 [(set (match_operand:P 0 "register_operand" "=r")
16723 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16724 (match_operand:P 2 "const_int_operand" "n")]
16725 UNSPECV_PROBE_STACK_RANGE))
16726 (clobber (reg:CC FLAGS_REG))]
16727 ""
16728 "* return output_probe_stack_range (operands[0], operands[2]);"
16729 [(set_attr "type" "multi")])
16730
16731 (define_expand "builtin_setjmp_receiver"
16732 [(label_ref (match_operand 0 "" ""))]
16733 "!TARGET_64BIT && flag_pic"
16734 {
16735 #if TARGET_MACHO
16736 if (TARGET_MACHO)
16737 {
16738 rtx xops[3];
16739 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16740 rtx label_rtx = gen_label_rtx ();
16741 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16742 xops[0] = xops[1] = picreg;
16743 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16744 ix86_expand_binary_operator (MINUS, SImode, xops);
16745 }
16746 else
16747 #endif
16748 emit_insn (gen_set_got (pic_offset_table_rtx));
16749 DONE;
16750 })
16751 \f
16752 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16753
16754 (define_split
16755 [(set (match_operand 0 "register_operand" "")
16756 (match_operator 3 "promotable_binary_operator"
16757 [(match_operand 1 "register_operand" "")
16758 (match_operand 2 "aligned_operand" "")]))
16759 (clobber (reg:CC FLAGS_REG))]
16760 "! TARGET_PARTIAL_REG_STALL && reload_completed
16761 && ((GET_MODE (operands[0]) == HImode
16762 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16763 /* ??? next two lines just !satisfies_constraint_K (...) */
16764 || !CONST_INT_P (operands[2])
16765 || satisfies_constraint_K (operands[2])))
16766 || (GET_MODE (operands[0]) == QImode
16767 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16768 [(parallel [(set (match_dup 0)
16769 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16770 (clobber (reg:CC FLAGS_REG))])]
16771 {
16772 operands[0] = gen_lowpart (SImode, operands[0]);
16773 operands[1] = gen_lowpart (SImode, operands[1]);
16774 if (GET_CODE (operands[3]) != ASHIFT)
16775 operands[2] = gen_lowpart (SImode, operands[2]);
16776 PUT_MODE (operands[3], SImode);
16777 })
16778
16779 ; Promote the QImode tests, as i386 has encoding of the AND
16780 ; instruction with 32-bit sign-extended immediate and thus the
16781 ; instruction size is unchanged, except in the %eax case for
16782 ; which it is increased by one byte, hence the ! optimize_size.
16783 (define_split
16784 [(set (match_operand 0 "flags_reg_operand" "")
16785 (match_operator 2 "compare_operator"
16786 [(and (match_operand 3 "aligned_operand" "")
16787 (match_operand 4 "const_int_operand" ""))
16788 (const_int 0)]))
16789 (set (match_operand 1 "register_operand" "")
16790 (and (match_dup 3) (match_dup 4)))]
16791 "! TARGET_PARTIAL_REG_STALL && reload_completed
16792 && optimize_insn_for_speed_p ()
16793 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16794 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16795 /* Ensure that the operand will remain sign-extended immediate. */
16796 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16797 [(parallel [(set (match_dup 0)
16798 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16799 (const_int 0)]))
16800 (set (match_dup 1)
16801 (and:SI (match_dup 3) (match_dup 4)))])]
16802 {
16803 operands[4]
16804 = gen_int_mode (INTVAL (operands[4])
16805 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16806 operands[1] = gen_lowpart (SImode, operands[1]);
16807 operands[3] = gen_lowpart (SImode, operands[3]);
16808 })
16809
16810 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16811 ; the TEST instruction with 32-bit sign-extended immediate and thus
16812 ; the instruction size would at least double, which is not what we
16813 ; want even with ! optimize_size.
16814 (define_split
16815 [(set (match_operand 0 "flags_reg_operand" "")
16816 (match_operator 1 "compare_operator"
16817 [(and (match_operand:HI 2 "aligned_operand" "")
16818 (match_operand:HI 3 "const_int_operand" ""))
16819 (const_int 0)]))]
16820 "! TARGET_PARTIAL_REG_STALL && reload_completed
16821 && ! TARGET_FAST_PREFIX
16822 && optimize_insn_for_speed_p ()
16823 /* Ensure that the operand will remain sign-extended immediate. */
16824 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16825 [(set (match_dup 0)
16826 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16827 (const_int 0)]))]
16828 {
16829 operands[3]
16830 = gen_int_mode (INTVAL (operands[3])
16831 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16832 operands[2] = gen_lowpart (SImode, operands[2]);
16833 })
16834
16835 (define_split
16836 [(set (match_operand 0 "register_operand" "")
16837 (neg (match_operand 1 "register_operand" "")))
16838 (clobber (reg:CC FLAGS_REG))]
16839 "! TARGET_PARTIAL_REG_STALL && reload_completed
16840 && (GET_MODE (operands[0]) == HImode
16841 || (GET_MODE (operands[0]) == QImode
16842 && (TARGET_PROMOTE_QImode
16843 || optimize_insn_for_size_p ())))"
16844 [(parallel [(set (match_dup 0)
16845 (neg:SI (match_dup 1)))
16846 (clobber (reg:CC FLAGS_REG))])]
16847 {
16848 operands[0] = gen_lowpart (SImode, operands[0]);
16849 operands[1] = gen_lowpart (SImode, operands[1]);
16850 })
16851
16852 (define_split
16853 [(set (match_operand 0 "register_operand" "")
16854 (not (match_operand 1 "register_operand" "")))]
16855 "! TARGET_PARTIAL_REG_STALL && reload_completed
16856 && (GET_MODE (operands[0]) == HImode
16857 || (GET_MODE (operands[0]) == QImode
16858 && (TARGET_PROMOTE_QImode
16859 || optimize_insn_for_size_p ())))"
16860 [(set (match_dup 0)
16861 (not:SI (match_dup 1)))]
16862 {
16863 operands[0] = gen_lowpart (SImode, operands[0]);
16864 operands[1] = gen_lowpart (SImode, operands[1]);
16865 })
16866
16867 (define_split
16868 [(set (match_operand 0 "register_operand" "")
16869 (if_then_else (match_operator 1 "ordered_comparison_operator"
16870 [(reg FLAGS_REG) (const_int 0)])
16871 (match_operand 2 "register_operand" "")
16872 (match_operand 3 "register_operand" "")))]
16873 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16874 && (GET_MODE (operands[0]) == HImode
16875 || (GET_MODE (operands[0]) == QImode
16876 && (TARGET_PROMOTE_QImode
16877 || optimize_insn_for_size_p ())))"
16878 [(set (match_dup 0)
16879 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16880 {
16881 operands[0] = gen_lowpart (SImode, operands[0]);
16882 operands[2] = gen_lowpart (SImode, operands[2]);
16883 operands[3] = gen_lowpart (SImode, operands[3]);
16884 })
16885 \f
16886 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16887 ;; transform a complex memory operation into two memory to register operations.
16888
16889 ;; Don't push memory operands
16890 (define_peephole2
16891 [(set (match_operand:SWI 0 "push_operand" "")
16892 (match_operand:SWI 1 "memory_operand" ""))
16893 (match_scratch:SWI 2 "<r>")]
16894 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16895 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16896 [(set (match_dup 2) (match_dup 1))
16897 (set (match_dup 0) (match_dup 2))])
16898
16899 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16900 ;; SImode pushes.
16901 (define_peephole2
16902 [(set (match_operand:SF 0 "push_operand" "")
16903 (match_operand:SF 1 "memory_operand" ""))
16904 (match_scratch:SF 2 "r")]
16905 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16906 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16907 [(set (match_dup 2) (match_dup 1))
16908 (set (match_dup 0) (match_dup 2))])
16909
16910 ;; Don't move an immediate directly to memory when the instruction
16911 ;; gets too big.
16912 (define_peephole2
16913 [(match_scratch:SWI124 1 "<r>")
16914 (set (match_operand:SWI124 0 "memory_operand" "")
16915 (const_int 0))]
16916 "optimize_insn_for_speed_p ()
16917 && !TARGET_USE_MOV0
16918 && TARGET_SPLIT_LONG_MOVES
16919 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16920 && peep2_regno_dead_p (0, FLAGS_REG)"
16921 [(parallel [(set (match_dup 2) (const_int 0))
16922 (clobber (reg:CC FLAGS_REG))])
16923 (set (match_dup 0) (match_dup 1))]
16924 "operands[2] = gen_lowpart (SImode, operands[1]);")
16925
16926 (define_peephole2
16927 [(match_scratch:SWI124 2 "<r>")
16928 (set (match_operand:SWI124 0 "memory_operand" "")
16929 (match_operand:SWI124 1 "immediate_operand" ""))]
16930 "optimize_insn_for_speed_p ()
16931 && TARGET_SPLIT_LONG_MOVES
16932 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16933 [(set (match_dup 2) (match_dup 1))
16934 (set (match_dup 0) (match_dup 2))])
16935
16936 ;; Don't compare memory with zero, load and use a test instead.
16937 (define_peephole2
16938 [(set (match_operand 0 "flags_reg_operand" "")
16939 (match_operator 1 "compare_operator"
16940 [(match_operand:SI 2 "memory_operand" "")
16941 (const_int 0)]))
16942 (match_scratch:SI 3 "r")]
16943 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16944 [(set (match_dup 3) (match_dup 2))
16945 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16946
16947 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16948 ;; Don't split NOTs with a displacement operand, because resulting XOR
16949 ;; will not be pairable anyway.
16950 ;;
16951 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16952 ;; represented using a modRM byte. The XOR replacement is long decoded,
16953 ;; so this split helps here as well.
16954 ;;
16955 ;; Note: Can't do this as a regular split because we can't get proper
16956 ;; lifetime information then.
16957
16958 (define_peephole2
16959 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16960 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16961 "optimize_insn_for_speed_p ()
16962 && ((TARGET_NOT_UNPAIRABLE
16963 && (!MEM_P (operands[0])
16964 || !memory_displacement_operand (operands[0], <MODE>mode)))
16965 || (TARGET_NOT_VECTORMODE
16966 && long_memory_operand (operands[0], <MODE>mode)))
16967 && peep2_regno_dead_p (0, FLAGS_REG)"
16968 [(parallel [(set (match_dup 0)
16969 (xor:SWI124 (match_dup 1) (const_int -1)))
16970 (clobber (reg:CC FLAGS_REG))])])
16971
16972 ;; Non pairable "test imm, reg" instructions can be translated to
16973 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16974 ;; byte opcode instead of two, have a short form for byte operands),
16975 ;; so do it for other CPUs as well. Given that the value was dead,
16976 ;; this should not create any new dependencies. Pass on the sub-word
16977 ;; versions if we're concerned about partial register stalls.
16978
16979 (define_peephole2
16980 [(set (match_operand 0 "flags_reg_operand" "")
16981 (match_operator 1 "compare_operator"
16982 [(and:SI (match_operand:SI 2 "register_operand" "")
16983 (match_operand:SI 3 "immediate_operand" ""))
16984 (const_int 0)]))]
16985 "ix86_match_ccmode (insn, CCNOmode)
16986 && (true_regnum (operands[2]) != AX_REG
16987 || satisfies_constraint_K (operands[3]))
16988 && peep2_reg_dead_p (1, operands[2])"
16989 [(parallel
16990 [(set (match_dup 0)
16991 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16992 (const_int 0)]))
16993 (set (match_dup 2)
16994 (and:SI (match_dup 2) (match_dup 3)))])])
16995
16996 ;; We don't need to handle HImode case, because it will be promoted to SImode
16997 ;; on ! TARGET_PARTIAL_REG_STALL
16998
16999 (define_peephole2
17000 [(set (match_operand 0 "flags_reg_operand" "")
17001 (match_operator 1 "compare_operator"
17002 [(and:QI (match_operand:QI 2 "register_operand" "")
17003 (match_operand:QI 3 "immediate_operand" ""))
17004 (const_int 0)]))]
17005 "! TARGET_PARTIAL_REG_STALL
17006 && ix86_match_ccmode (insn, CCNOmode)
17007 && true_regnum (operands[2]) != AX_REG
17008 && peep2_reg_dead_p (1, operands[2])"
17009 [(parallel
17010 [(set (match_dup 0)
17011 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17012 (const_int 0)]))
17013 (set (match_dup 2)
17014 (and:QI (match_dup 2) (match_dup 3)))])])
17015
17016 (define_peephole2
17017 [(set (match_operand 0 "flags_reg_operand" "")
17018 (match_operator 1 "compare_operator"
17019 [(and:SI
17020 (zero_extract:SI
17021 (match_operand 2 "ext_register_operand" "")
17022 (const_int 8)
17023 (const_int 8))
17024 (match_operand 3 "const_int_operand" ""))
17025 (const_int 0)]))]
17026 "! TARGET_PARTIAL_REG_STALL
17027 && ix86_match_ccmode (insn, CCNOmode)
17028 && true_regnum (operands[2]) != AX_REG
17029 && peep2_reg_dead_p (1, operands[2])"
17030 [(parallel [(set (match_dup 0)
17031 (match_op_dup 1
17032 [(and:SI
17033 (zero_extract:SI
17034 (match_dup 2)
17035 (const_int 8)
17036 (const_int 8))
17037 (match_dup 3))
17038 (const_int 0)]))
17039 (set (zero_extract:SI (match_dup 2)
17040 (const_int 8)
17041 (const_int 8))
17042 (and:SI
17043 (zero_extract:SI
17044 (match_dup 2)
17045 (const_int 8)
17046 (const_int 8))
17047 (match_dup 3)))])])
17048
17049 ;; Don't do logical operations with memory inputs.
17050 (define_peephole2
17051 [(match_scratch:SI 2 "r")
17052 (parallel [(set (match_operand:SI 0 "register_operand" "")
17053 (match_operator:SI 3 "arith_or_logical_operator"
17054 [(match_dup 0)
17055 (match_operand:SI 1 "memory_operand" "")]))
17056 (clobber (reg:CC FLAGS_REG))])]
17057 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17058 [(set (match_dup 2) (match_dup 1))
17059 (parallel [(set (match_dup 0)
17060 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17061 (clobber (reg:CC FLAGS_REG))])])
17062
17063 (define_peephole2
17064 [(match_scratch:SI 2 "r")
17065 (parallel [(set (match_operand:SI 0 "register_operand" "")
17066 (match_operator:SI 3 "arith_or_logical_operator"
17067 [(match_operand:SI 1 "memory_operand" "")
17068 (match_dup 0)]))
17069 (clobber (reg:CC FLAGS_REG))])]
17070 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17071 [(set (match_dup 2) (match_dup 1))
17072 (parallel [(set (match_dup 0)
17073 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17074 (clobber (reg:CC FLAGS_REG))])])
17075
17076 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17077 ;; refers to the destination of the load!
17078
17079 (define_peephole2
17080 [(set (match_operand:SI 0 "register_operand" "")
17081 (match_operand:SI 1 "register_operand" ""))
17082 (parallel [(set (match_dup 0)
17083 (match_operator:SI 3 "commutative_operator"
17084 [(match_dup 0)
17085 (match_operand:SI 2 "memory_operand" "")]))
17086 (clobber (reg:CC FLAGS_REG))])]
17087 "REGNO (operands[0]) != REGNO (operands[1])
17088 && GENERAL_REGNO_P (REGNO (operands[0]))
17089 && GENERAL_REGNO_P (REGNO (operands[1]))"
17090 [(set (match_dup 0) (match_dup 4))
17091 (parallel [(set (match_dup 0)
17092 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17093 (clobber (reg:CC FLAGS_REG))])]
17094 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17095
17096 (define_peephole2
17097 [(set (match_operand 0 "register_operand" "")
17098 (match_operand 1 "register_operand" ""))
17099 (set (match_dup 0)
17100 (match_operator 3 "commutative_operator"
17101 [(match_dup 0)
17102 (match_operand 2 "memory_operand" "")]))]
17103 "REGNO (operands[0]) != REGNO (operands[1])
17104 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17105 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17106 [(set (match_dup 0) (match_dup 2))
17107 (set (match_dup 0)
17108 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17109
17110 ; Don't do logical operations with memory outputs
17111 ;
17112 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17113 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17114 ; the same decoder scheduling characteristics as the original.
17115
17116 (define_peephole2
17117 [(match_scratch:SI 2 "r")
17118 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17119 (match_operator:SI 3 "arith_or_logical_operator"
17120 [(match_dup 0)
17121 (match_operand:SI 1 "nonmemory_operand" "")]))
17122 (clobber (reg:CC FLAGS_REG))])]
17123 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17124 /* Do not split stack checking probes. */
17125 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17126 [(set (match_dup 2) (match_dup 0))
17127 (parallel [(set (match_dup 2)
17128 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17129 (clobber (reg:CC FLAGS_REG))])
17130 (set (match_dup 0) (match_dup 2))])
17131
17132 (define_peephole2
17133 [(match_scratch:SI 2 "r")
17134 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17135 (match_operator:SI 3 "arith_or_logical_operator"
17136 [(match_operand:SI 1 "nonmemory_operand" "")
17137 (match_dup 0)]))
17138 (clobber (reg:CC FLAGS_REG))])]
17139 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17140 /* Do not split stack checking probes. */
17141 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17142 [(set (match_dup 2) (match_dup 0))
17143 (parallel [(set (match_dup 2)
17144 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17145 (clobber (reg:CC FLAGS_REG))])
17146 (set (match_dup 0) (match_dup 2))])
17147
17148 ;; Attempt to use arith or logical operations with memory outputs with
17149 ;; setting of flags.
17150 (define_peephole2
17151 [(set (match_operand:SWI 0 "register_operand" "")
17152 (match_operand:SWI 1 "memory_operand" ""))
17153 (parallel [(set (match_dup 0)
17154 (match_operator:SWI 3 "plusminuslogic_operator"
17155 [(match_dup 0)
17156 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17157 (clobber (reg:CC FLAGS_REG))])
17158 (set (match_dup 1) (match_dup 0))
17159 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17160 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17161 && peep2_reg_dead_p (4, operands[0])
17162 && !reg_overlap_mentioned_p (operands[0], operands[1])
17163 && ix86_match_ccmode (peep2_next_insn (3),
17164 (GET_CODE (operands[3]) == PLUS
17165 || GET_CODE (operands[3]) == MINUS)
17166 ? CCGOCmode : CCNOmode)"
17167 [(parallel [(set (match_dup 4) (match_dup 5))
17168 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17169 (match_dup 2)]))])]
17170 {
17171 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17172 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17173 copy_rtx (operands[1]),
17174 copy_rtx (operands[2]));
17175 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17176 operands[5], const0_rtx);
17177 })
17178
17179 (define_peephole2
17180 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17181 (match_operator:SWI 2 "plusminuslogic_operator"
17182 [(match_dup 0)
17183 (match_operand:SWI 1 "memory_operand" "")]))
17184 (clobber (reg:CC FLAGS_REG))])
17185 (set (match_dup 1) (match_dup 0))
17186 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17187 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17188 && GET_CODE (operands[2]) != MINUS
17189 && peep2_reg_dead_p (3, operands[0])
17190 && !reg_overlap_mentioned_p (operands[0], operands[1])
17191 && ix86_match_ccmode (peep2_next_insn (2),
17192 GET_CODE (operands[2]) == PLUS
17193 ? CCGOCmode : CCNOmode)"
17194 [(parallel [(set (match_dup 3) (match_dup 4))
17195 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17196 (match_dup 0)]))])]
17197 {
17198 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17199 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17200 copy_rtx (operands[1]),
17201 copy_rtx (operands[0]));
17202 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17203 operands[4], const0_rtx);
17204 })
17205
17206 (define_peephole2
17207 [(set (match_operand:SWI12 0 "register_operand" "")
17208 (match_operand:SWI12 1 "memory_operand" ""))
17209 (parallel [(set (match_operand:SI 4 "register_operand" "")
17210 (match_operator:SI 3 "plusminuslogic_operator"
17211 [(match_dup 4)
17212 (match_operand:SI 2 "nonmemory_operand" "")]))
17213 (clobber (reg:CC FLAGS_REG))])
17214 (set (match_dup 1) (match_dup 0))
17215 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17216 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17217 && REG_P (operands[0]) && REG_P (operands[4])
17218 && REGNO (operands[0]) == REGNO (operands[4])
17219 && peep2_reg_dead_p (4, operands[0])
17220 && (<MODE>mode != QImode
17221 || immediate_operand (operands[2], SImode)
17222 || q_regs_operand (operands[2], SImode))
17223 && !reg_overlap_mentioned_p (operands[0], operands[1])
17224 && ix86_match_ccmode (peep2_next_insn (3),
17225 (GET_CODE (operands[3]) == PLUS
17226 || GET_CODE (operands[3]) == MINUS)
17227 ? CCGOCmode : CCNOmode)"
17228 [(parallel [(set (match_dup 4) (match_dup 5))
17229 (set (match_dup 1) (match_dup 6))])]
17230 {
17231 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17232 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17233 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17234 copy_rtx (operands[1]), operands[2]);
17235 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17236 operands[5], const0_rtx);
17237 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17238 copy_rtx (operands[1]),
17239 copy_rtx (operands[2]));
17240 })
17241
17242 ;; Attempt to always use XOR for zeroing registers.
17243 (define_peephole2
17244 [(set (match_operand 0 "register_operand" "")
17245 (match_operand 1 "const0_operand" ""))]
17246 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17247 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17248 && GENERAL_REG_P (operands[0])
17249 && peep2_regno_dead_p (0, FLAGS_REG)"
17250 [(parallel [(set (match_dup 0) (const_int 0))
17251 (clobber (reg:CC FLAGS_REG))])]
17252 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17253
17254 (define_peephole2
17255 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17256 (const_int 0))]
17257 "(GET_MODE (operands[0]) == QImode
17258 || GET_MODE (operands[0]) == HImode)
17259 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17260 && peep2_regno_dead_p (0, FLAGS_REG)"
17261 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17262 (clobber (reg:CC FLAGS_REG))])])
17263
17264 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17265 (define_peephole2
17266 [(set (match_operand:SWI248 0 "register_operand" "")
17267 (const_int -1))]
17268 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17269 && peep2_regno_dead_p (0, FLAGS_REG)"
17270 [(parallel [(set (match_dup 0) (const_int -1))
17271 (clobber (reg:CC FLAGS_REG))])]
17272 {
17273 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17274 operands[0] = gen_lowpart (SImode, operands[0]);
17275 })
17276
17277 ;; Attempt to convert simple lea to add/shift.
17278 ;; These can be created by move expanders.
17279
17280 (define_peephole2
17281 [(set (match_operand:SWI48 0 "register_operand" "")
17282 (plus:SWI48 (match_dup 0)
17283 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17284 "peep2_regno_dead_p (0, FLAGS_REG)"
17285 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17286 (clobber (reg:CC FLAGS_REG))])])
17287
17288 (define_peephole2
17289 [(set (match_operand:SI 0 "register_operand" "")
17290 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17291 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17292 "TARGET_64BIT
17293 && peep2_regno_dead_p (0, FLAGS_REG)
17294 && REGNO (operands[0]) == REGNO (operands[1])"
17295 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17296 (clobber (reg:CC FLAGS_REG))])]
17297 "operands[2] = gen_lowpart (SImode, operands[2]);")
17298
17299 (define_peephole2
17300 [(set (match_operand:SWI48 0 "register_operand" "")
17301 (mult:SWI48 (match_dup 0)
17302 (match_operand:SWI48 1 "const_int_operand" "")))]
17303 "exact_log2 (INTVAL (operands[1])) >= 0
17304 && peep2_regno_dead_p (0, FLAGS_REG)"
17305 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17306 (clobber (reg:CC FLAGS_REG))])]
17307 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17308
17309 (define_peephole2
17310 [(set (match_operand:SI 0 "register_operand" "")
17311 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17312 (match_operand:DI 2 "const_int_operand" "")) 0))]
17313 "TARGET_64BIT
17314 && exact_log2 (INTVAL (operands[2])) >= 0
17315 && REGNO (operands[0]) == REGNO (operands[1])
17316 && peep2_regno_dead_p (0, FLAGS_REG)"
17317 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17318 (clobber (reg:CC FLAGS_REG))])]
17319 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17320
17321 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17322 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17323 ;; On many CPUs it is also faster, since special hardware to avoid esp
17324 ;; dependencies is present.
17325
17326 ;; While some of these conversions may be done using splitters, we use
17327 ;; peepholes in order to allow combine_stack_adjustments pass to see
17328 ;; nonobfuscated RTL.
17329
17330 ;; Convert prologue esp subtractions to push.
17331 ;; We need register to push. In order to keep verify_flow_info happy we have
17332 ;; two choices
17333 ;; - use scratch and clobber it in order to avoid dependencies
17334 ;; - use already live register
17335 ;; We can't use the second way right now, since there is no reliable way how to
17336 ;; verify that given register is live. First choice will also most likely in
17337 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17338 ;; call clobbered registers are dead. We may want to use base pointer as an
17339 ;; alternative when no register is available later.
17340
17341 (define_peephole2
17342 [(match_scratch:W 1 "r")
17343 (parallel [(set (reg:P SP_REG)
17344 (plus:P (reg:P SP_REG)
17345 (match_operand:P 0 "const_int_operand" "")))
17346 (clobber (reg:CC FLAGS_REG))
17347 (clobber (mem:BLK (scratch)))])]
17348 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17349 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17350 [(clobber (match_dup 1))
17351 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17352 (clobber (mem:BLK (scratch)))])])
17353
17354 (define_peephole2
17355 [(match_scratch:W 1 "r")
17356 (parallel [(set (reg:P SP_REG)
17357 (plus:P (reg:P SP_REG)
17358 (match_operand:P 0 "const_int_operand" "")))
17359 (clobber (reg:CC FLAGS_REG))
17360 (clobber (mem:BLK (scratch)))])]
17361 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17362 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17363 [(clobber (match_dup 1))
17364 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17365 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17366 (clobber (mem:BLK (scratch)))])])
17367
17368 ;; Convert esp subtractions to push.
17369 (define_peephole2
17370 [(match_scratch:W 1 "r")
17371 (parallel [(set (reg:P SP_REG)
17372 (plus:P (reg:P SP_REG)
17373 (match_operand:P 0 "const_int_operand" "")))
17374 (clobber (reg:CC FLAGS_REG))])]
17375 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17376 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17377 [(clobber (match_dup 1))
17378 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17379
17380 (define_peephole2
17381 [(match_scratch:W 1 "r")
17382 (parallel [(set (reg:P SP_REG)
17383 (plus:P (reg:P SP_REG)
17384 (match_operand:P 0 "const_int_operand" "")))
17385 (clobber (reg:CC FLAGS_REG))])]
17386 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17387 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17388 [(clobber (match_dup 1))
17389 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17390 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17391
17392 ;; Convert epilogue deallocator to pop.
17393 (define_peephole2
17394 [(match_scratch:W 1 "r")
17395 (parallel [(set (reg:P SP_REG)
17396 (plus:P (reg:P SP_REG)
17397 (match_operand:P 0 "const_int_operand" "")))
17398 (clobber (reg:CC FLAGS_REG))
17399 (clobber (mem:BLK (scratch)))])]
17400 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17401 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17402 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17403 (clobber (mem:BLK (scratch)))])])
17404
17405 ;; Two pops case is tricky, since pop causes dependency
17406 ;; on destination register. We use two registers if available.
17407 (define_peephole2
17408 [(match_scratch:W 1 "r")
17409 (match_scratch:W 2 "r")
17410 (parallel [(set (reg:P SP_REG)
17411 (plus:P (reg:P SP_REG)
17412 (match_operand:P 0 "const_int_operand" "")))
17413 (clobber (reg:CC FLAGS_REG))
17414 (clobber (mem:BLK (scratch)))])]
17415 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17416 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17417 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17418 (clobber (mem:BLK (scratch)))])
17419 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17420
17421 (define_peephole2
17422 [(match_scratch:W 1 "r")
17423 (parallel [(set (reg:P SP_REG)
17424 (plus:P (reg:P SP_REG)
17425 (match_operand:P 0 "const_int_operand" "")))
17426 (clobber (reg:CC FLAGS_REG))
17427 (clobber (mem:BLK (scratch)))])]
17428 "optimize_insn_for_size_p ()
17429 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17430 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17431 (clobber (mem:BLK (scratch)))])
17432 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17433
17434 ;; Convert esp additions to pop.
17435 (define_peephole2
17436 [(match_scratch:W 1 "r")
17437 (parallel [(set (reg:P SP_REG)
17438 (plus:P (reg:P SP_REG)
17439 (match_operand:P 0 "const_int_operand" "")))
17440 (clobber (reg:CC FLAGS_REG))])]
17441 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17442 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17443
17444 ;; Two pops case is tricky, since pop causes dependency
17445 ;; on destination register. We use two registers if available.
17446 (define_peephole2
17447 [(match_scratch:W 1 "r")
17448 (match_scratch:W 2 "r")
17449 (parallel [(set (reg:P SP_REG)
17450 (plus:P (reg:P SP_REG)
17451 (match_operand:P 0 "const_int_operand" "")))
17452 (clobber (reg:CC FLAGS_REG))])]
17453 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17454 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17455 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17456
17457 (define_peephole2
17458 [(match_scratch:W 1 "r")
17459 (parallel [(set (reg:P SP_REG)
17460 (plus:P (reg:P SP_REG)
17461 (match_operand:P 0 "const_int_operand" "")))
17462 (clobber (reg:CC FLAGS_REG))])]
17463 "optimize_insn_for_size_p ()
17464 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17465 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17466 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17467 \f
17468 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17469 ;; required and register dies. Similarly for 128 to -128.
17470 (define_peephole2
17471 [(set (match_operand 0 "flags_reg_operand" "")
17472 (match_operator 1 "compare_operator"
17473 [(match_operand 2 "register_operand" "")
17474 (match_operand 3 "const_int_operand" "")]))]
17475 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17476 && incdec_operand (operands[3], GET_MODE (operands[3])))
17477 || (!TARGET_FUSE_CMP_AND_BRANCH
17478 && INTVAL (operands[3]) == 128))
17479 && ix86_match_ccmode (insn, CCGCmode)
17480 && peep2_reg_dead_p (1, operands[2])"
17481 [(parallel [(set (match_dup 0)
17482 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17483 (clobber (match_dup 2))])])
17484 \f
17485 ;; Convert imul by three, five and nine into lea
17486 (define_peephole2
17487 [(parallel
17488 [(set (match_operand:SWI48 0 "register_operand" "")
17489 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17490 (match_operand:SWI48 2 "const359_operand" "")))
17491 (clobber (reg:CC FLAGS_REG))])]
17492 "!TARGET_PARTIAL_REG_STALL
17493 || <MODE>mode == SImode
17494 || optimize_function_for_size_p (cfun)"
17495 [(set (match_dup 0)
17496 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17497 (match_dup 1)))]
17498 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17499
17500 (define_peephole2
17501 [(parallel
17502 [(set (match_operand:SWI48 0 "register_operand" "")
17503 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17504 (match_operand:SWI48 2 "const359_operand" "")))
17505 (clobber (reg:CC FLAGS_REG))])]
17506 "optimize_insn_for_speed_p ()
17507 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17508 [(set (match_dup 0) (match_dup 1))
17509 (set (match_dup 0)
17510 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17511 (match_dup 0)))]
17512 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17513
17514 ;; imul $32bit_imm, mem, reg is vector decoded, while
17515 ;; imul $32bit_imm, reg, reg is direct decoded.
17516 (define_peephole2
17517 [(match_scratch:SWI48 3 "r")
17518 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17519 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17520 (match_operand:SWI48 2 "immediate_operand" "")))
17521 (clobber (reg:CC FLAGS_REG))])]
17522 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17523 && !satisfies_constraint_K (operands[2])"
17524 [(set (match_dup 3) (match_dup 1))
17525 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17526 (clobber (reg:CC FLAGS_REG))])])
17527
17528 (define_peephole2
17529 [(match_scratch:SI 3 "r")
17530 (parallel [(set (match_operand:DI 0 "register_operand" "")
17531 (zero_extend:DI
17532 (mult:SI (match_operand:SI 1 "memory_operand" "")
17533 (match_operand:SI 2 "immediate_operand" ""))))
17534 (clobber (reg:CC FLAGS_REG))])]
17535 "TARGET_64BIT
17536 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17537 && !satisfies_constraint_K (operands[2])"
17538 [(set (match_dup 3) (match_dup 1))
17539 (parallel [(set (match_dup 0)
17540 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17541 (clobber (reg:CC FLAGS_REG))])])
17542
17543 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17544 ;; Convert it into imul reg, reg
17545 ;; It would be better to force assembler to encode instruction using long
17546 ;; immediate, but there is apparently no way to do so.
17547 (define_peephole2
17548 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17549 (mult:SWI248
17550 (match_operand:SWI248 1 "nonimmediate_operand" "")
17551 (match_operand:SWI248 2 "const_int_operand" "")))
17552 (clobber (reg:CC FLAGS_REG))])
17553 (match_scratch:SWI248 3 "r")]
17554 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17555 && satisfies_constraint_K (operands[2])"
17556 [(set (match_dup 3) (match_dup 2))
17557 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17558 (clobber (reg:CC FLAGS_REG))])]
17559 {
17560 if (!rtx_equal_p (operands[0], operands[1]))
17561 emit_move_insn (operands[0], operands[1]);
17562 })
17563
17564 ;; After splitting up read-modify operations, array accesses with memory
17565 ;; operands might end up in form:
17566 ;; sall $2, %eax
17567 ;; movl 4(%esp), %edx
17568 ;; addl %edx, %eax
17569 ;; instead of pre-splitting:
17570 ;; sall $2, %eax
17571 ;; addl 4(%esp), %eax
17572 ;; Turn it into:
17573 ;; movl 4(%esp), %edx
17574 ;; leal (%edx,%eax,4), %eax
17575
17576 (define_peephole2
17577 [(match_scratch:W 5 "r")
17578 (parallel [(set (match_operand 0 "register_operand" "")
17579 (ashift (match_operand 1 "register_operand" "")
17580 (match_operand 2 "const_int_operand" "")))
17581 (clobber (reg:CC FLAGS_REG))])
17582 (parallel [(set (match_operand 3 "register_operand" "")
17583 (plus (match_dup 0)
17584 (match_operand 4 "x86_64_general_operand" "")))
17585 (clobber (reg:CC FLAGS_REG))])]
17586 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17587 /* Validate MODE for lea. */
17588 && ((!TARGET_PARTIAL_REG_STALL
17589 && (GET_MODE (operands[0]) == QImode
17590 || GET_MODE (operands[0]) == HImode))
17591 || GET_MODE (operands[0]) == SImode
17592 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17593 && (rtx_equal_p (operands[0], operands[3])
17594 || peep2_reg_dead_p (2, operands[0]))
17595 /* We reorder load and the shift. */
17596 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17597 [(set (match_dup 5) (match_dup 4))
17598 (set (match_dup 0) (match_dup 1))]
17599 {
17600 enum machine_mode op1mode = GET_MODE (operands[1]);
17601 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17602 int scale = 1 << INTVAL (operands[2]);
17603 rtx index = gen_lowpart (word_mode, operands[1]);
17604 rtx base = gen_lowpart (word_mode, operands[5]);
17605 rtx dest = gen_lowpart (mode, operands[3]);
17606
17607 operands[1] = gen_rtx_PLUS (word_mode, base,
17608 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17609 operands[5] = base;
17610 if (mode != word_mode)
17611 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17612 if (op1mode != word_mode)
17613 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17614 operands[0] = dest;
17615 })
17616 \f
17617 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17618 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17619 ;; caught for use by garbage collectors and the like. Using an insn that
17620 ;; maps to SIGILL makes it more likely the program will rightfully die.
17621 ;; Keeping with tradition, "6" is in honor of #UD.
17622 (define_insn "trap"
17623 [(trap_if (const_int 1) (const_int 6))]
17624 ""
17625 { return ASM_SHORT "0x0b0f"; }
17626 [(set_attr "length" "2")])
17627
17628 (define_expand "prefetch"
17629 [(prefetch (match_operand 0 "address_operand" "")
17630 (match_operand:SI 1 "const_int_operand" "")
17631 (match_operand:SI 2 "const_int_operand" ""))]
17632 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17633 {
17634 int rw = INTVAL (operands[1]);
17635 int locality = INTVAL (operands[2]);
17636
17637 gcc_assert (rw == 0 || rw == 1);
17638 gcc_assert (locality >= 0 && locality <= 3);
17639 gcc_assert (GET_MODE (operands[0]) == Pmode
17640 || GET_MODE (operands[0]) == VOIDmode);
17641
17642 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17643 supported by SSE counterpart or the SSE prefetch is not available
17644 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17645 of locality. */
17646 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17647 operands[2] = GEN_INT (3);
17648 else
17649 operands[1] = const0_rtx;
17650 })
17651
17652 (define_insn "*prefetch_sse_<mode>"
17653 [(prefetch (match_operand:P 0 "address_operand" "p")
17654 (const_int 0)
17655 (match_operand:SI 1 "const_int_operand" ""))]
17656 "TARGET_PREFETCH_SSE"
17657 {
17658 static const char * const patterns[4] = {
17659 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17660 };
17661
17662 int locality = INTVAL (operands[1]);
17663 gcc_assert (locality >= 0 && locality <= 3);
17664
17665 return patterns[locality];
17666 }
17667 [(set_attr "type" "sse")
17668 (set_attr "atom_sse_attr" "prefetch")
17669 (set (attr "length_address")
17670 (symbol_ref "memory_address_length (operands[0])"))
17671 (set_attr "memory" "none")])
17672
17673 (define_insn "*prefetch_3dnow_<mode>"
17674 [(prefetch (match_operand:P 0 "address_operand" "p")
17675 (match_operand:SI 1 "const_int_operand" "n")
17676 (const_int 3))]
17677 "TARGET_3DNOW"
17678 {
17679 if (INTVAL (operands[1]) == 0)
17680 return "prefetch\t%a0";
17681 else
17682 return "prefetchw\t%a0";
17683 }
17684 [(set_attr "type" "mmx")
17685 (set (attr "length_address")
17686 (symbol_ref "memory_address_length (operands[0])"))
17687 (set_attr "memory" "none")])
17688
17689 (define_expand "stack_protect_set"
17690 [(match_operand 0 "memory_operand" "")
17691 (match_operand 1 "memory_operand" "")]
17692 ""
17693 {
17694 rtx (*insn)(rtx, rtx);
17695
17696 #ifdef TARGET_THREAD_SSP_OFFSET
17697 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17698 insn = (TARGET_LP64
17699 ? gen_stack_tls_protect_set_di
17700 : gen_stack_tls_protect_set_si);
17701 #else
17702 insn = (TARGET_LP64
17703 ? gen_stack_protect_set_di
17704 : gen_stack_protect_set_si);
17705 #endif
17706
17707 emit_insn (insn (operands[0], operands[1]));
17708 DONE;
17709 })
17710
17711 (define_insn "stack_protect_set_<mode>"
17712 [(set (match_operand:PTR 0 "memory_operand" "=m")
17713 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17714 UNSPEC_SP_SET))
17715 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17716 (clobber (reg:CC FLAGS_REG))]
17717 ""
17718 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17719 [(set_attr "type" "multi")])
17720
17721 (define_insn "stack_tls_protect_set_<mode>"
17722 [(set (match_operand:PTR 0 "memory_operand" "=m")
17723 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17724 UNSPEC_SP_TLS_SET))
17725 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17726 (clobber (reg:CC FLAGS_REG))]
17727 ""
17728 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17729 [(set_attr "type" "multi")])
17730
17731 (define_expand "stack_protect_test"
17732 [(match_operand 0 "memory_operand" "")
17733 (match_operand 1 "memory_operand" "")
17734 (match_operand 2 "" "")]
17735 ""
17736 {
17737 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17738
17739 rtx (*insn)(rtx, rtx, rtx);
17740
17741 #ifdef TARGET_THREAD_SSP_OFFSET
17742 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17743 insn = (TARGET_LP64
17744 ? gen_stack_tls_protect_test_di
17745 : gen_stack_tls_protect_test_si);
17746 #else
17747 insn = (TARGET_LP64
17748 ? gen_stack_protect_test_di
17749 : gen_stack_protect_test_si);
17750 #endif
17751
17752 emit_insn (insn (flags, operands[0], operands[1]));
17753
17754 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17755 flags, const0_rtx, operands[2]));
17756 DONE;
17757 })
17758
17759 (define_insn "stack_protect_test_<mode>"
17760 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17761 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17762 (match_operand:PTR 2 "memory_operand" "m")]
17763 UNSPEC_SP_TEST))
17764 (clobber (match_scratch:PTR 3 "=&r"))]
17765 ""
17766 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17767 [(set_attr "type" "multi")])
17768
17769 (define_insn "stack_tls_protect_test_<mode>"
17770 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17771 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17772 (match_operand:PTR 2 "const_int_operand" "i")]
17773 UNSPEC_SP_TLS_TEST))
17774 (clobber (match_scratch:PTR 3 "=r"))]
17775 ""
17776 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17777 [(set_attr "type" "multi")])
17778
17779 (define_insn "sse4_2_crc32<mode>"
17780 [(set (match_operand:SI 0 "register_operand" "=r")
17781 (unspec:SI
17782 [(match_operand:SI 1 "register_operand" "0")
17783 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17784 UNSPEC_CRC32))]
17785 "TARGET_SSE4_2 || TARGET_CRC32"
17786 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17787 [(set_attr "type" "sselog1")
17788 (set_attr "prefix_rep" "1")
17789 (set_attr "prefix_extra" "1")
17790 (set (attr "prefix_data16")
17791 (if_then_else (match_operand:HI 2 "" "")
17792 (const_string "1")
17793 (const_string "*")))
17794 (set (attr "prefix_rex")
17795 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17796 (const_string "1")
17797 (const_string "*")))
17798 (set_attr "mode" "SI")])
17799
17800 (define_insn "sse4_2_crc32di"
17801 [(set (match_operand:DI 0 "register_operand" "=r")
17802 (unspec:DI
17803 [(match_operand:DI 1 "register_operand" "0")
17804 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17805 UNSPEC_CRC32))]
17806 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17807 "crc32{q}\t{%2, %0|%0, %2}"
17808 [(set_attr "type" "sselog1")
17809 (set_attr "prefix_rep" "1")
17810 (set_attr "prefix_extra" "1")
17811 (set_attr "mode" "DI")])
17812
17813 (define_expand "rdpmc"
17814 [(match_operand:DI 0 "register_operand" "")
17815 (match_operand:SI 1 "register_operand" "")]
17816 ""
17817 {
17818 rtx reg = gen_reg_rtx (DImode);
17819 rtx si;
17820
17821 /* Force operand 1 into ECX. */
17822 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17823 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17824 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17825 UNSPECV_RDPMC);
17826
17827 if (TARGET_64BIT)
17828 {
17829 rtvec vec = rtvec_alloc (2);
17830 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17831 rtx upper = gen_reg_rtx (DImode);
17832 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17833 gen_rtvec (1, const0_rtx),
17834 UNSPECV_RDPMC);
17835 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17836 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17837 emit_insn (load);
17838 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17839 NULL, 1, OPTAB_DIRECT);
17840 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17841 OPTAB_DIRECT);
17842 }
17843 else
17844 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17845 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17846 DONE;
17847 })
17848
17849 (define_insn "*rdpmc"
17850 [(set (match_operand:DI 0 "register_operand" "=A")
17851 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17852 UNSPECV_RDPMC))]
17853 "!TARGET_64BIT"
17854 "rdpmc"
17855 [(set_attr "type" "other")
17856 (set_attr "length" "2")])
17857
17858 (define_insn "*rdpmc_rex64"
17859 [(set (match_operand:DI 0 "register_operand" "=a")
17860 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17861 UNSPECV_RDPMC))
17862 (set (match_operand:DI 1 "register_operand" "=d")
17863 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17864 "TARGET_64BIT"
17865 "rdpmc"
17866 [(set_attr "type" "other")
17867 (set_attr "length" "2")])
17868
17869 (define_expand "rdtsc"
17870 [(set (match_operand:DI 0 "register_operand" "")
17871 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17872 ""
17873 {
17874 if (TARGET_64BIT)
17875 {
17876 rtvec vec = rtvec_alloc (2);
17877 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17878 rtx upper = gen_reg_rtx (DImode);
17879 rtx lower = gen_reg_rtx (DImode);
17880 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17881 gen_rtvec (1, const0_rtx),
17882 UNSPECV_RDTSC);
17883 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17884 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17885 emit_insn (load);
17886 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17887 NULL, 1, OPTAB_DIRECT);
17888 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17889 OPTAB_DIRECT);
17890 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17891 DONE;
17892 }
17893 })
17894
17895 (define_insn "*rdtsc"
17896 [(set (match_operand:DI 0 "register_operand" "=A")
17897 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17898 "!TARGET_64BIT"
17899 "rdtsc"
17900 [(set_attr "type" "other")
17901 (set_attr "length" "2")])
17902
17903 (define_insn "*rdtsc_rex64"
17904 [(set (match_operand:DI 0 "register_operand" "=a")
17905 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17906 (set (match_operand:DI 1 "register_operand" "=d")
17907 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17908 "TARGET_64BIT"
17909 "rdtsc"
17910 [(set_attr "type" "other")
17911 (set_attr "length" "2")])
17912
17913 (define_expand "rdtscp"
17914 [(match_operand:DI 0 "register_operand" "")
17915 (match_operand:SI 1 "memory_operand" "")]
17916 ""
17917 {
17918 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17919 gen_rtvec (1, const0_rtx),
17920 UNSPECV_RDTSCP);
17921 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17922 gen_rtvec (1, const0_rtx),
17923 UNSPECV_RDTSCP);
17924 rtx reg = gen_reg_rtx (DImode);
17925 rtx tmp = gen_reg_rtx (SImode);
17926
17927 if (TARGET_64BIT)
17928 {
17929 rtvec vec = rtvec_alloc (3);
17930 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17931 rtx upper = gen_reg_rtx (DImode);
17932 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17933 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17934 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17935 emit_insn (load);
17936 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17937 NULL, 1, OPTAB_DIRECT);
17938 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17939 OPTAB_DIRECT);
17940 }
17941 else
17942 {
17943 rtvec vec = rtvec_alloc (2);
17944 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17945 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17946 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17947 emit_insn (load);
17948 }
17949 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17950 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17951 DONE;
17952 })
17953
17954 (define_insn "*rdtscp"
17955 [(set (match_operand:DI 0 "register_operand" "=A")
17956 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17957 (set (match_operand:SI 1 "register_operand" "=c")
17958 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17959 "!TARGET_64BIT"
17960 "rdtscp"
17961 [(set_attr "type" "other")
17962 (set_attr "length" "3")])
17963
17964 (define_insn "*rdtscp_rex64"
17965 [(set (match_operand:DI 0 "register_operand" "=a")
17966 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17967 (set (match_operand:DI 1 "register_operand" "=d")
17968 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17969 (set (match_operand:SI 2 "register_operand" "=c")
17970 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17971 "TARGET_64BIT"
17972 "rdtscp"
17973 [(set_attr "type" "other")
17974 (set_attr "length" "3")])
17975
17976 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17977 ;;
17978 ;; LWP instructions
17979 ;;
17980 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17981
17982 (define_expand "lwp_llwpcb"
17983 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17984 UNSPECV_LLWP_INTRINSIC)]
17985 "TARGET_LWP")
17986
17987 (define_insn "*lwp_llwpcb<mode>1"
17988 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17989 UNSPECV_LLWP_INTRINSIC)]
17990 "TARGET_LWP"
17991 "llwpcb\t%0"
17992 [(set_attr "type" "lwp")
17993 (set_attr "mode" "<MODE>")
17994 (set_attr "length" "5")])
17995
17996 (define_expand "lwp_slwpcb"
17997 [(set (match_operand 0 "register_operand" "=r")
17998 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17999 "TARGET_LWP"
18000 {
18001 rtx (*insn)(rtx);
18002
18003 insn = (TARGET_64BIT
18004 ? gen_lwp_slwpcbdi
18005 : gen_lwp_slwpcbsi);
18006
18007 emit_insn (insn (operands[0]));
18008 DONE;
18009 })
18010
18011 (define_insn "lwp_slwpcb<mode>"
18012 [(set (match_operand:P 0 "register_operand" "=r")
18013 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18014 "TARGET_LWP"
18015 "slwpcb\t%0"
18016 [(set_attr "type" "lwp")
18017 (set_attr "mode" "<MODE>")
18018 (set_attr "length" "5")])
18019
18020 (define_expand "lwp_lwpval<mode>3"
18021 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18022 (match_operand:SI 2 "nonimmediate_operand" "rm")
18023 (match_operand:SI 3 "const_int_operand" "i")]
18024 UNSPECV_LWPVAL_INTRINSIC)]
18025 "TARGET_LWP"
18026 ;; Avoid unused variable warning.
18027 "(void) operands[0];")
18028
18029 (define_insn "*lwp_lwpval<mode>3_1"
18030 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18031 (match_operand:SI 1 "nonimmediate_operand" "rm")
18032 (match_operand:SI 2 "const_int_operand" "i")]
18033 UNSPECV_LWPVAL_INTRINSIC)]
18034 "TARGET_LWP"
18035 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18036 [(set_attr "type" "lwp")
18037 (set_attr "mode" "<MODE>")
18038 (set (attr "length")
18039 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18040
18041 (define_expand "lwp_lwpins<mode>3"
18042 [(set (reg:CCC FLAGS_REG)
18043 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18044 (match_operand:SI 2 "nonimmediate_operand" "rm")
18045 (match_operand:SI 3 "const_int_operand" "i")]
18046 UNSPECV_LWPINS_INTRINSIC))
18047 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18048 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18049 "TARGET_LWP")
18050
18051 (define_insn "*lwp_lwpins<mode>3_1"
18052 [(set (reg:CCC FLAGS_REG)
18053 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18054 (match_operand:SI 1 "nonimmediate_operand" "rm")
18055 (match_operand:SI 2 "const_int_operand" "i")]
18056 UNSPECV_LWPINS_INTRINSIC))]
18057 "TARGET_LWP"
18058 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18059 [(set_attr "type" "lwp")
18060 (set_attr "mode" "<MODE>")
18061 (set (attr "length")
18062 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18063
18064 (define_insn "rdfsbase<mode>"
18065 [(set (match_operand:SWI48 0 "register_operand" "=r")
18066 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18067 "TARGET_64BIT && TARGET_FSGSBASE"
18068 "rdfsbase %0"
18069 [(set_attr "type" "other")
18070 (set_attr "prefix_extra" "2")])
18071
18072 (define_insn "rdgsbase<mode>"
18073 [(set (match_operand:SWI48 0 "register_operand" "=r")
18074 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18075 "TARGET_64BIT && TARGET_FSGSBASE"
18076 "rdgsbase %0"
18077 [(set_attr "type" "other")
18078 (set_attr "prefix_extra" "2")])
18079
18080 (define_insn "wrfsbase<mode>"
18081 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18082 UNSPECV_WRFSBASE)]
18083 "TARGET_64BIT && TARGET_FSGSBASE"
18084 "wrfsbase %0"
18085 [(set_attr "type" "other")
18086 (set_attr "prefix_extra" "2")])
18087
18088 (define_insn "wrgsbase<mode>"
18089 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18090 UNSPECV_WRGSBASE)]
18091 "TARGET_64BIT && TARGET_FSGSBASE"
18092 "wrgsbase %0"
18093 [(set_attr "type" "other")
18094 (set_attr "prefix_extra" "2")])
18095
18096 (define_insn "rdrand<mode>_1"
18097 [(set (match_operand:SWI248 0 "register_operand" "=r")
18098 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18099 (set (reg:CCC FLAGS_REG)
18100 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18101 "TARGET_RDRND"
18102 "rdrand\t%0"
18103 [(set_attr "type" "other")
18104 (set_attr "prefix_extra" "1")])
18105
18106 (define_expand "pause"
18107 [(set (match_dup 0)
18108 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18109 ""
18110 {
18111 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18112 MEM_VOLATILE_P (operands[0]) = 1;
18113 })
18114
18115 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18116 ;; They have the same encoding.
18117 (define_insn "*pause"
18118 [(set (match_operand:BLK 0 "" "")
18119 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18120 ""
18121 "rep; nop"
18122 [(set_attr "length" "2")
18123 (set_attr "memory" "unknown")])
18124
18125 (include "mmx.md")
18126 (include "sse.md")
18127 (include "sync.md")