551e25d623ebd837ef615db1c42dea0d01f49f0a
[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
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 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
63
64 ;; UNSPEC usage:
65
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
68 UNSPEC_GOT
69 UNSPEC_GOTOFF
70 UNSPEC_GOTPCREL
71 UNSPEC_GOTTPOFF
72 UNSPEC_TPOFF
73 UNSPEC_NTPOFF
74 UNSPEC_DTPOFF
75 UNSPEC_GOTNTPOFF
76 UNSPEC_INDNTPOFF
77 UNSPEC_PLTOFF
78 UNSPEC_MACHOPIC_OFFSET
79 UNSPEC_PCREL
80
81 ;; Prologue support
82 UNSPEC_STACK_ALLOC
83 UNSPEC_SET_GOT
84 UNSPEC_REG_SAVE
85 UNSPEC_DEF_CFA
86 UNSPEC_SET_RIP
87 UNSPEC_SET_GOT_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
89 UNSPEC_STACK_CHECK
90
91 ;; TLS support
92 UNSPEC_TP
93 UNSPEC_TLS_GD
94 UNSPEC_TLS_LD_BASE
95 UNSPEC_TLSDESC
96 UNSPEC_TLS_IE_SUN
97
98 ;; Other random patterns
99 UNSPEC_SCAS
100 UNSPEC_FNSTSW
101 UNSPEC_SAHF
102 UNSPEC_PARITY
103 UNSPEC_FSTCW
104 UNSPEC_ADD_CARRY
105 UNSPEC_FLDCW
106 UNSPEC_REP
107 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_TRUNC_NOOP
109 UNSPEC_DIV_ALREADY_SPLIT
110 UNSPEC_CALL_NEEDS_VZEROUPPER
111
112 ;; For SSE/MMX support:
113 UNSPEC_FIX_NOTRUNC
114 UNSPEC_MASKMOV
115 UNSPEC_MOVMSK
116 UNSPEC_MOVNT
117 UNSPEC_MOVU
118 UNSPEC_RCP
119 UNSPEC_RSQRT
120 UNSPEC_SFENCE
121 UNSPEC_PFRCP
122 UNSPEC_PFRCPIT1
123 UNSPEC_PFRCPIT2
124 UNSPEC_PFRSQRT
125 UNSPEC_PFRSQIT1
126 UNSPEC_MFENCE
127 UNSPEC_LFENCE
128 UNSPEC_PSADBW
129 UNSPEC_LDDQU
130 UNSPEC_MS_TO_SYSV_CALL
131
132 ;; Generic math support
133 UNSPEC_COPYSIGN
134 UNSPEC_IEEE_MIN ; not commutative
135 UNSPEC_IEEE_MAX ; not commutative
136
137 ;; x87 Floating point
138 UNSPEC_SIN
139 UNSPEC_COS
140 UNSPEC_FPATAN
141 UNSPEC_FYL2X
142 UNSPEC_FYL2XP1
143 UNSPEC_FRNDINT
144 UNSPEC_FIST
145 UNSPEC_F2XM1
146 UNSPEC_TAN
147 UNSPEC_FXAM
148
149 ;; x87 Rounding
150 UNSPEC_FRNDINT_FLOOR
151 UNSPEC_FRNDINT_CEIL
152 UNSPEC_FRNDINT_TRUNC
153 UNSPEC_FRNDINT_MASK_PM
154 UNSPEC_FIST_FLOOR
155 UNSPEC_FIST_CEIL
156
157 ;; x87 Double output FP
158 UNSPEC_SINCOS_COS
159 UNSPEC_SINCOS_SIN
160 UNSPEC_XTRACT_FRACT
161 UNSPEC_XTRACT_EXP
162 UNSPEC_FSCALE_FRACT
163 UNSPEC_FSCALE_EXP
164 UNSPEC_FPREM_F
165 UNSPEC_FPREM_U
166 UNSPEC_FPREM1_F
167 UNSPEC_FPREM1_U
168
169 UNSPEC_C2_FLAG
170 UNSPEC_FXAM_MEM
171
172 ;; SSP patterns
173 UNSPEC_SP_SET
174 UNSPEC_SP_TEST
175 UNSPEC_SP_TLS_SET
176 UNSPEC_SP_TLS_TEST
177
178 ;; SSSE3
179 UNSPEC_PSHUFB
180 UNSPEC_PSIGN
181 UNSPEC_PALIGNR
182
183 ;; For SSE4A support
184 UNSPEC_EXTRQI
185 UNSPEC_EXTRQ
186 UNSPEC_INSERTQI
187 UNSPEC_INSERTQ
188
189 ;; For SSE4.1 support
190 UNSPEC_BLENDV
191 UNSPEC_INSERTPS
192 UNSPEC_DP
193 UNSPEC_MOVNTDQA
194 UNSPEC_MPSADBW
195 UNSPEC_PHMINPOSUW
196 UNSPEC_PTEST
197 UNSPEC_ROUND
198
199 ;; For SSE4.2 support
200 UNSPEC_CRC32
201 UNSPEC_PCMPESTR
202 UNSPEC_PCMPISTR
203
204 ;; For FMA4 support
205 UNSPEC_FMADDSUB
206 UNSPEC_XOP_UNSIGNED_CMP
207 UNSPEC_XOP_TRUEFALSE
208 UNSPEC_XOP_PERMUTE
209 UNSPEC_FRCZ
210
211 ;; For AES support
212 UNSPEC_AESENC
213 UNSPEC_AESENCLAST
214 UNSPEC_AESDEC
215 UNSPEC_AESDECLAST
216 UNSPEC_AESIMC
217 UNSPEC_AESKEYGENASSIST
218
219 ;; For PCLMUL support
220 UNSPEC_PCLMUL
221
222 ;; For AVX support
223 UNSPEC_PCMP
224 UNSPEC_VPERMIL
225 UNSPEC_VPERMIL2
226 UNSPEC_VPERMIL2F128
227 UNSPEC_CAST
228 UNSPEC_VTESTP
229 UNSPEC_VCVTPH2PS
230 UNSPEC_VCVTPS2PH
231
232 ;; For BMI support
233 UNSPEC_BEXTR
234
235 ;; For RDRAND support
236 UNSPEC_RDRAND
237 ])
238
239 (define_c_enum "unspecv" [
240 UNSPECV_BLOCKAGE
241 UNSPECV_STACK_PROBE
242 UNSPECV_PROBE_STACK_RANGE
243 UNSPECV_EMMS
244 UNSPECV_LDMXCSR
245 UNSPECV_STMXCSR
246 UNSPECV_FEMMS
247 UNSPECV_CLFLUSH
248 UNSPECV_ALIGN
249 UNSPECV_MONITOR
250 UNSPECV_MWAIT
251 UNSPECV_CMPXCHG
252 UNSPECV_XCHG
253 UNSPECV_LOCK
254 UNSPECV_PROLOGUE_USE
255 UNSPECV_CLD
256 UNSPECV_NOPS
257 UNSPECV_VZEROALL
258 UNSPECV_VZEROUPPER
259 UNSPECV_RDTSC
260 UNSPECV_RDTSCP
261 UNSPECV_RDPMC
262 UNSPECV_LLWP_INTRINSIC
263 UNSPECV_SLWP_INTRINSIC
264 UNSPECV_LWPVAL_INTRINSIC
265 UNSPECV_LWPINS_INTRINSIC
266 UNSPECV_RDFSBASE
267 UNSPECV_RDGSBASE
268 UNSPECV_WRFSBASE
269 UNSPECV_WRGSBASE
270 UNSPECV_SPLIT_STACK_RETURN
271 ])
272
273 ;; Constants to represent rounding modes in the ROUND instruction
274 (define_constants
275 [(ROUND_FLOOR 0x1)
276 (ROUND_CEIL 0x2)
277 (ROUND_TRUNC 0x3)
278 (ROUND_MXCSR 0x4)
279 (ROUND_NO_EXC 0x8)
280 ])
281
282 ;; Constants to represent pcomtrue/pcomfalse variants
283 (define_constants
284 [(PCOM_FALSE 0)
285 (PCOM_TRUE 1)
286 (COM_FALSE_S 2)
287 (COM_FALSE_P 3)
288 (COM_TRUE_S 4)
289 (COM_TRUE_P 5)
290 ])
291
292 ;; Constants used in the XOP pperm instruction
293 (define_constants
294 [(PPERM_SRC 0x00) /* copy source */
295 (PPERM_INVERT 0x20) /* invert source */
296 (PPERM_REVERSE 0x40) /* bit reverse source */
297 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
298 (PPERM_ZERO 0x80) /* all 0's */
299 (PPERM_ONES 0xa0) /* all 1's */
300 (PPERM_SIGN 0xc0) /* propagate sign bit */
301 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
302 (PPERM_SRC1 0x00) /* use first source byte */
303 (PPERM_SRC2 0x10) /* use second source byte */
304 ])
305
306 ;; Registers by name.
307 (define_constants
308 [(AX_REG 0)
309 (DX_REG 1)
310 (CX_REG 2)
311 (BX_REG 3)
312 (SI_REG 4)
313 (DI_REG 5)
314 (BP_REG 6)
315 (SP_REG 7)
316 (ST0_REG 8)
317 (ST1_REG 9)
318 (ST2_REG 10)
319 (ST3_REG 11)
320 (ST4_REG 12)
321 (ST5_REG 13)
322 (ST6_REG 14)
323 (ST7_REG 15)
324 (FLAGS_REG 17)
325 (FPSR_REG 18)
326 (FPCR_REG 19)
327 (XMM0_REG 21)
328 (XMM1_REG 22)
329 (XMM2_REG 23)
330 (XMM3_REG 24)
331 (XMM4_REG 25)
332 (XMM5_REG 26)
333 (XMM6_REG 27)
334 (XMM7_REG 28)
335 (MM0_REG 29)
336 (MM1_REG 30)
337 (MM2_REG 31)
338 (MM3_REG 32)
339 (MM4_REG 33)
340 (MM5_REG 34)
341 (MM6_REG 35)
342 (MM7_REG 36)
343 (R8_REG 37)
344 (R9_REG 38)
345 (R10_REG 39)
346 (R11_REG 40)
347 (R12_REG 41)
348 (R13_REG 42)
349 (XMM8_REG 45)
350 (XMM9_REG 46)
351 (XMM10_REG 47)
352 (XMM11_REG 48)
353 (XMM12_REG 49)
354 (XMM13_REG 50)
355 (XMM14_REG 51)
356 (XMM15_REG 52)
357 ])
358
359 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
360 ;; from i386.c.
361
362 ;; In C guard expressions, put expressions which may be compile-time
363 ;; constants first. This allows for better optimization. For
364 ;; example, write "TARGET_64BIT && reload_completed", not
365 ;; "reload_completed && TARGET_64BIT".
366
367 \f
368 ;; Processor type.
369 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
370 atom,generic64,amdfam10,bdver1,btver1"
371 (const (symbol_ref "ix86_schedule")))
372
373 ;; A basic instruction type. Refinements due to arguments to be
374 ;; provided in other attributes.
375 (define_attr "type"
376 "other,multi,
377 alu,alu1,negnot,imov,imovx,lea,
378 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
379 icmp,test,ibr,setcc,icmov,
380 push,pop,call,callv,leave,
381 str,bitmanip,
382 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
383 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
384 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
385 ssemuladd,sse4arg,lwp,
386 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
387 (const_string "other"))
388
389 ;; Main data type used by the insn
390 (define_attr "mode"
391 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
392 (const_string "unknown"))
393
394 ;; The CPU unit operations uses.
395 (define_attr "unit" "integer,i387,sse,mmx,unknown"
396 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
397 (const_string "i387")
398 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
399 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
400 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
401 (const_string "sse")
402 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
403 (const_string "mmx")
404 (eq_attr "type" "other")
405 (const_string "unknown")]
406 (const_string "integer")))
407
408 ;; The (bounding maximum) length of an instruction immediate.
409 (define_attr "length_immediate" ""
410 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
411 bitmanip")
412 (const_int 0)
413 (eq_attr "unit" "i387,sse,mmx")
414 (const_int 0)
415 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
416 imul,icmp,push,pop")
417 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
418 (eq_attr "type" "imov,test")
419 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
420 (eq_attr "type" "call")
421 (if_then_else (match_operand 0 "constant_call_address_operand" "")
422 (const_int 4)
423 (const_int 0))
424 (eq_attr "type" "callv")
425 (if_then_else (match_operand 1 "constant_call_address_operand" "")
426 (const_int 4)
427 (const_int 0))
428 ;; We don't know the size before shorten_branches. Expect
429 ;; the instruction to fit for better scheduling.
430 (eq_attr "type" "ibr")
431 (const_int 1)
432 ]
433 (symbol_ref "/* Update immediate_length and other attributes! */
434 gcc_unreachable (),1")))
435
436 ;; The (bounding maximum) length of an instruction address.
437 (define_attr "length_address" ""
438 (cond [(eq_attr "type" "str,other,multi,fxch")
439 (const_int 0)
440 (and (eq_attr "type" "call")
441 (match_operand 0 "constant_call_address_operand" ""))
442 (const_int 0)
443 (and (eq_attr "type" "callv")
444 (match_operand 1 "constant_call_address_operand" ""))
445 (const_int 0)
446 ]
447 (symbol_ref "ix86_attr_length_address_default (insn)")))
448
449 ;; Set when length prefix is used.
450 (define_attr "prefix_data16" ""
451 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
452 (const_int 0)
453 (eq_attr "mode" "HI")
454 (const_int 1)
455 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
456 (const_int 1)
457 ]
458 (const_int 0)))
459
460 ;; Set when string REP prefix is used.
461 (define_attr "prefix_rep" ""
462 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
463 (const_int 0)
464 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
465 (const_int 1)
466 ]
467 (const_int 0)))
468
469 ;; Set when 0f opcode prefix is used.
470 (define_attr "prefix_0f" ""
471 (if_then_else
472 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
473 (eq_attr "unit" "sse,mmx"))
474 (const_int 1)
475 (const_int 0)))
476
477 ;; Set when REX opcode prefix is used.
478 (define_attr "prefix_rex" ""
479 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
480 (const_int 0)
481 (and (eq_attr "mode" "DI")
482 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
483 (eq_attr "unit" "!mmx")))
484 (const_int 1)
485 (and (eq_attr "mode" "QI")
486 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
487 (const_int 0)))
488 (const_int 1)
489 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
490 (const_int 0))
491 (const_int 1)
492 (and (eq_attr "type" "imovx")
493 (match_operand:QI 1 "ext_QIreg_operand" ""))
494 (const_int 1)
495 ]
496 (const_int 0)))
497
498 ;; There are also additional prefixes in 3DNOW, SSSE3.
499 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
500 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
501 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
502 (define_attr "prefix_extra" ""
503 (cond [(eq_attr "type" "ssemuladd,sse4arg")
504 (const_int 2)
505 (eq_attr "type" "sseiadd1,ssecvt1")
506 (const_int 1)
507 ]
508 (const_int 0)))
509
510 ;; Prefix used: original, VEX or maybe VEX.
511 (define_attr "prefix" "orig,vex,maybe_vex"
512 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
513 (const_string "vex")
514 (const_string "orig")))
515
516 ;; VEX W bit is used.
517 (define_attr "prefix_vex_w" "" (const_int 0))
518
519 ;; The length of VEX prefix
520 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
521 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
522 ;; still prefix_0f 1, with prefix_extra 1.
523 (define_attr "length_vex" ""
524 (if_then_else (and (eq_attr "prefix_0f" "1")
525 (eq_attr "prefix_extra" "0"))
526 (if_then_else (eq_attr "prefix_vex_w" "1")
527 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
528 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
529 (if_then_else (eq_attr "prefix_vex_w" "1")
530 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
531 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
532
533 ;; Set when modrm byte is used.
534 (define_attr "modrm" ""
535 (cond [(eq_attr "type" "str,leave")
536 (const_int 0)
537 (eq_attr "unit" "i387")
538 (const_int 0)
539 (and (eq_attr "type" "incdec")
540 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
541 (ior (match_operand:SI 1 "register_operand" "")
542 (match_operand:HI 1 "register_operand" ""))))
543 (const_int 0)
544 (and (eq_attr "type" "push")
545 (not (match_operand 1 "memory_operand" "")))
546 (const_int 0)
547 (and (eq_attr "type" "pop")
548 (not (match_operand 0 "memory_operand" "")))
549 (const_int 0)
550 (and (eq_attr "type" "imov")
551 (and (not (eq_attr "mode" "DI"))
552 (ior (and (match_operand 0 "register_operand" "")
553 (match_operand 1 "immediate_operand" ""))
554 (ior (and (match_operand 0 "ax_reg_operand" "")
555 (match_operand 1 "memory_displacement_only_operand" ""))
556 (and (match_operand 0 "memory_displacement_only_operand" "")
557 (match_operand 1 "ax_reg_operand" ""))))))
558 (const_int 0)
559 (and (eq_attr "type" "call")
560 (match_operand 0 "constant_call_address_operand" ""))
561 (const_int 0)
562 (and (eq_attr "type" "callv")
563 (match_operand 1 "constant_call_address_operand" ""))
564 (const_int 0)
565 (and (eq_attr "type" "alu,alu1,icmp,test")
566 (match_operand 0 "ax_reg_operand" ""))
567 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
568 ]
569 (const_int 1)))
570
571 ;; The (bounding maximum) length of an instruction in bytes.
572 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
573 ;; Later we may want to split them and compute proper length as for
574 ;; other insns.
575 (define_attr "length" ""
576 (cond [(eq_attr "type" "other,multi,fistp,frndint")
577 (const_int 16)
578 (eq_attr "type" "fcmp")
579 (const_int 4)
580 (eq_attr "unit" "i387")
581 (plus (const_int 2)
582 (plus (attr "prefix_data16")
583 (attr "length_address")))
584 (ior (eq_attr "prefix" "vex")
585 (and (eq_attr "prefix" "maybe_vex")
586 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
587 (plus (attr "length_vex")
588 (plus (attr "length_immediate")
589 (plus (attr "modrm")
590 (attr "length_address"))))]
591 (plus (plus (attr "modrm")
592 (plus (attr "prefix_0f")
593 (plus (attr "prefix_rex")
594 (plus (attr "prefix_extra")
595 (const_int 1)))))
596 (plus (attr "prefix_rep")
597 (plus (attr "prefix_data16")
598 (plus (attr "length_immediate")
599 (attr "length_address")))))))
600
601 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
602 ;; `store' if there is a simple memory reference therein, or `unknown'
603 ;; if the instruction is complex.
604
605 (define_attr "memory" "none,load,store,both,unknown"
606 (cond [(eq_attr "type" "other,multi,str,lwp")
607 (const_string "unknown")
608 (eq_attr "type" "lea,fcmov,fpspc")
609 (const_string "none")
610 (eq_attr "type" "fistp,leave")
611 (const_string "both")
612 (eq_attr "type" "frndint")
613 (const_string "load")
614 (eq_attr "type" "push")
615 (if_then_else (match_operand 1 "memory_operand" "")
616 (const_string "both")
617 (const_string "store"))
618 (eq_attr "type" "pop")
619 (if_then_else (match_operand 0 "memory_operand" "")
620 (const_string "both")
621 (const_string "load"))
622 (eq_attr "type" "setcc")
623 (if_then_else (match_operand 0 "memory_operand" "")
624 (const_string "store")
625 (const_string "none"))
626 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
627 (if_then_else (ior (match_operand 0 "memory_operand" "")
628 (match_operand 1 "memory_operand" ""))
629 (const_string "load")
630 (const_string "none"))
631 (eq_attr "type" "ibr")
632 (if_then_else (match_operand 0 "memory_operand" "")
633 (const_string "load")
634 (const_string "none"))
635 (eq_attr "type" "call")
636 (if_then_else (match_operand 0 "constant_call_address_operand" "")
637 (const_string "none")
638 (const_string "load"))
639 (eq_attr "type" "callv")
640 (if_then_else (match_operand 1 "constant_call_address_operand" "")
641 (const_string "none")
642 (const_string "load"))
643 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
644 (match_operand 1 "memory_operand" ""))
645 (const_string "both")
646 (and (match_operand 0 "memory_operand" "")
647 (match_operand 1 "memory_operand" ""))
648 (const_string "both")
649 (match_operand 0 "memory_operand" "")
650 (const_string "store")
651 (match_operand 1 "memory_operand" "")
652 (const_string "load")
653 (and (eq_attr "type"
654 "!alu1,negnot,ishift1,
655 imov,imovx,icmp,test,bitmanip,
656 fmov,fcmp,fsgn,
657 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
658 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
659 (match_operand 2 "memory_operand" ""))
660 (const_string "load")
661 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
662 (match_operand 3 "memory_operand" ""))
663 (const_string "load")
664 ]
665 (const_string "none")))
666
667 ;; Indicates if an instruction has both an immediate and a displacement.
668
669 (define_attr "imm_disp" "false,true,unknown"
670 (cond [(eq_attr "type" "other,multi")
671 (const_string "unknown")
672 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
673 (and (match_operand 0 "memory_displacement_operand" "")
674 (match_operand 1 "immediate_operand" "")))
675 (const_string "true")
676 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
677 (and (match_operand 0 "memory_displacement_operand" "")
678 (match_operand 2 "immediate_operand" "")))
679 (const_string "true")
680 ]
681 (const_string "false")))
682
683 ;; Indicates if an FP operation has an integer source.
684
685 (define_attr "fp_int_src" "false,true"
686 (const_string "false"))
687
688 ;; Defines rounding mode of an FP operation.
689
690 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
691 (const_string "any"))
692
693 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
694 (define_attr "use_carry" "0,1" (const_string "0"))
695
696 ;; Define attribute to indicate unaligned ssemov insns
697 (define_attr "movu" "0,1" (const_string "0"))
698
699 ;; Used to control the "enabled" attribute on a per-instruction basis.
700 (define_attr "isa" "base,noavx,avx"
701 (const_string "base"))
702
703 (define_attr "enabled" ""
704 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
705 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
706 ]
707 (const_int 1)))
708
709 ;; Describe a user's asm statement.
710 (define_asm_attributes
711 [(set_attr "length" "128")
712 (set_attr "type" "multi")])
713
714 (define_code_iterator plusminus [plus minus])
715
716 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
717
718 ;; Base name for define_insn
719 (define_code_attr plusminus_insn
720 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
721 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
722
723 ;; Base name for insn mnemonic.
724 (define_code_attr plusminus_mnemonic
725 [(plus "add") (ss_plus "adds") (us_plus "addus")
726 (minus "sub") (ss_minus "subs") (us_minus "subus")])
727 (define_code_attr plusminus_carry_mnemonic
728 [(plus "adc") (minus "sbb")])
729
730 ;; Mark commutative operators as such in constraints.
731 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
732 (minus "") (ss_minus "") (us_minus "")])
733
734 ;; Mapping of signed max and min
735 (define_code_iterator smaxmin [smax smin])
736
737 ;; Mapping of unsigned max and min
738 (define_code_iterator umaxmin [umax umin])
739
740 ;; Base name for integer and FP insn mnemonic
741 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
742 (umax "maxu") (umin "minu")])
743 (define_code_attr maxmin_float [(smax "max") (smin "min")])
744
745 ;; Mapping of logic operators
746 (define_code_iterator any_logic [and ior xor])
747 (define_code_iterator any_or [ior xor])
748
749 ;; Base name for insn mnemonic.
750 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
751
752 ;; Mapping of shift-right operators
753 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
754
755 ;; Base name for define_insn
756 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
757
758 ;; Base name for insn mnemonic.
759 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
760
761 ;; Mapping of rotate operators
762 (define_code_iterator any_rotate [rotate rotatert])
763
764 ;; Base name for define_insn
765 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
766
767 ;; Base name for insn mnemonic.
768 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
769
770 ;; Mapping of abs neg operators
771 (define_code_iterator absneg [abs neg])
772
773 ;; Base name for x87 insn mnemonic.
774 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
775
776 ;; Used in signed and unsigned widening multiplications.
777 (define_code_iterator any_extend [sign_extend zero_extend])
778
779 ;; Various insn prefixes for signed and unsigned operations.
780 (define_code_attr u [(sign_extend "") (zero_extend "u")
781 (div "") (udiv "u")])
782 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
783
784 ;; Used in signed and unsigned divisions.
785 (define_code_iterator any_div [div udiv])
786
787 ;; Instruction prefix for signed and unsigned operations.
788 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
789 (div "i") (udiv "")])
790
791 ;; 64bit single word integer modes.
792 (define_mode_iterator SWI1248x [QI HI SI DI])
793
794 ;; 64bit single word integer modes without QImode and HImode.
795 (define_mode_iterator SWI48x [SI DI])
796
797 ;; Single word integer modes.
798 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
799
800 ;; Single word integer modes without SImode and DImode.
801 (define_mode_iterator SWI12 [QI HI])
802
803 ;; Single word integer modes without DImode.
804 (define_mode_iterator SWI124 [QI HI SI])
805
806 ;; Single word integer modes without QImode and DImode.
807 (define_mode_iterator SWI24 [HI SI])
808
809 ;; Single word integer modes without QImode.
810 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
811
812 ;; Single word integer modes without QImode and HImode.
813 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
814
815 ;; All math-dependant single and double word integer modes.
816 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
817 (HI "TARGET_HIMODE_MATH")
818 SI DI (TI "TARGET_64BIT")])
819
820 ;; Math-dependant single word integer modes.
821 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI (DI "TARGET_64BIT")])
824
825 ;; Math-dependant single word integer modes without DImode.
826 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
828 SI])
829
830 ;; Math-dependant single word integer modes without QImode.
831 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
832 SI (DI "TARGET_64BIT")])
833
834 ;; Double word integer modes.
835 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
836 (TI "TARGET_64BIT")])
837
838 ;; Double word integer modes as mode attribute.
839 (define_mode_attr DWI [(SI "DI") (DI "TI")])
840 (define_mode_attr dwi [(SI "di") (DI "ti")])
841
842 ;; Half mode for double word integer modes.
843 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
844 (DI "TARGET_64BIT")])
845
846 ;; Instruction suffix for integer modes.
847 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
848
849 ;; Pointer size prefix for integer modes (Intel asm dialect)
850 (define_mode_attr iptrsize [(QI "BYTE")
851 (HI "WORD")
852 (SI "DWORD")
853 (DI "QWORD")])
854
855 ;; Register class for integer modes.
856 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
857
858 ;; Immediate operand constraint for integer modes.
859 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
860
861 ;; General operand constraint for word modes.
862 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
863
864 ;; Immediate operand constraint for double integer modes.
865 (define_mode_attr di [(SI "iF") (DI "e")])
866
867 ;; Immediate operand constraint for shifts.
868 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
869
870 ;; General operand predicate for integer modes.
871 (define_mode_attr general_operand
872 [(QI "general_operand")
873 (HI "general_operand")
874 (SI "general_operand")
875 (DI "x86_64_general_operand")
876 (TI "x86_64_general_operand")])
877
878 ;; General sign/zero extend operand predicate for integer modes.
879 (define_mode_attr general_szext_operand
880 [(QI "general_operand")
881 (HI "general_operand")
882 (SI "general_operand")
883 (DI "x86_64_szext_general_operand")])
884
885 ;; Immediate operand predicate for integer modes.
886 (define_mode_attr immediate_operand
887 [(QI "immediate_operand")
888 (HI "immediate_operand")
889 (SI "immediate_operand")
890 (DI "x86_64_immediate_operand")])
891
892 ;; Nonmemory operand predicate for integer modes.
893 (define_mode_attr nonmemory_operand
894 [(QI "nonmemory_operand")
895 (HI "nonmemory_operand")
896 (SI "nonmemory_operand")
897 (DI "x86_64_nonmemory_operand")])
898
899 ;; Operand predicate for shifts.
900 (define_mode_attr shift_operand
901 [(QI "nonimmediate_operand")
902 (HI "nonimmediate_operand")
903 (SI "nonimmediate_operand")
904 (DI "shiftdi_operand")
905 (TI "register_operand")])
906
907 ;; Operand predicate for shift argument.
908 (define_mode_attr shift_immediate_operand
909 [(QI "const_1_to_31_operand")
910 (HI "const_1_to_31_operand")
911 (SI "const_1_to_31_operand")
912 (DI "const_1_to_63_operand")])
913
914 ;; Input operand predicate for arithmetic left shifts.
915 (define_mode_attr ashl_input_operand
916 [(QI "nonimmediate_operand")
917 (HI "nonimmediate_operand")
918 (SI "nonimmediate_operand")
919 (DI "ashldi_input_operand")
920 (TI "reg_or_pm1_operand")])
921
922 ;; SSE and x87 SFmode and DFmode floating point modes
923 (define_mode_iterator MODEF [SF DF])
924
925 ;; All x87 floating point modes
926 (define_mode_iterator X87MODEF [SF DF XF])
927
928 ;; All integer modes handled by x87 fisttp operator.
929 (define_mode_iterator X87MODEI [HI SI DI])
930
931 ;; All integer modes handled by integer x87 operators.
932 (define_mode_iterator X87MODEI12 [HI SI])
933
934 ;; All integer modes handled by SSE cvtts?2si* operators.
935 (define_mode_iterator SSEMODEI24 [SI DI])
936
937 ;; SSE instruction suffix for various modes
938 (define_mode_attr ssemodesuffix
939 [(SF "ss") (DF "sd")
940 (V8SF "ps") (V4DF "pd")
941 (V4SF "ps") (V2DF "pd")
942 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
943 (V8SI "si")])
944
945 ;; SSE vector suffix for floating point modes
946 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
947
948 ;; SSE vector mode corresponding to a scalar mode
949 (define_mode_attr ssevecmode
950 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
951
952 ;; Instruction suffix for REX 64bit operators.
953 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
954
955 ;; This mode iterator allows :P to be used for patterns that operate on
956 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
957 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
958 \f
959 ;; Scheduling descriptions
960
961 (include "pentium.md")
962 (include "ppro.md")
963 (include "k6.md")
964 (include "athlon.md")
965 (include "bdver1.md")
966 (include "geode.md")
967 (include "atom.md")
968 (include "core2.md")
969
970 \f
971 ;; Operand and operator predicates and constraints
972
973 (include "predicates.md")
974 (include "constraints.md")
975
976 \f
977 ;; Compare and branch/compare and store instructions.
978
979 (define_expand "cbranch<mode>4"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
982 (match_operand:SDWIM 2 "<general_operand>" "")))
983 (set (pc) (if_then_else
984 (match_operator 0 "ordered_comparison_operator"
985 [(reg:CC FLAGS_REG) (const_int 0)])
986 (label_ref (match_operand 3 "" ""))
987 (pc)))]
988 ""
989 {
990 if (MEM_P (operands[1]) && MEM_P (operands[2]))
991 operands[1] = force_reg (<MODE>mode, operands[1]);
992 ix86_expand_branch (GET_CODE (operands[0]),
993 operands[1], operands[2], operands[3]);
994 DONE;
995 })
996
997 (define_expand "cstore<mode>4"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1000 (match_operand:SWIM 3 "<general_operand>" "")))
1001 (set (match_operand:QI 0 "register_operand" "")
1002 (match_operator 1 "ordered_comparison_operator"
1003 [(reg:CC FLAGS_REG) (const_int 0)]))]
1004 ""
1005 {
1006 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1007 operands[2] = force_reg (<MODE>mode, operands[2]);
1008 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1009 operands[2], operands[3]);
1010 DONE;
1011 })
1012
1013 (define_expand "cmp<mode>_1"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1016 (match_operand:SWI48 1 "<general_operand>" "")))])
1017
1018 (define_insn "*cmp<mode>_ccno_1"
1019 [(set (reg FLAGS_REG)
1020 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1021 (match_operand:SWI 1 "const0_operand" "")))]
1022 "ix86_match_ccmode (insn, CCNOmode)"
1023 "@
1024 test{<imodesuffix>}\t%0, %0
1025 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1026 [(set_attr "type" "test,icmp")
1027 (set_attr "length_immediate" "0,1")
1028 (set_attr "mode" "<MODE>")])
1029
1030 (define_insn "*cmp<mode>_1"
1031 [(set (reg FLAGS_REG)
1032 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1033 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1034 "ix86_match_ccmode (insn, CCmode)"
1035 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "<MODE>")])
1038
1039 (define_insn "*cmp<mode>_minus_1"
1040 [(set (reg FLAGS_REG)
1041 (compare
1042 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1043 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1044 (const_int 0)))]
1045 "ix86_match_ccmode (insn, CCGOCmode)"
1046 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1047 [(set_attr "type" "icmp")
1048 (set_attr "mode" "<MODE>")])
1049
1050 (define_insn "*cmpqi_ext_1"
1051 [(set (reg FLAGS_REG)
1052 (compare
1053 (match_operand:QI 0 "general_operand" "Qm")
1054 (subreg:QI
1055 (zero_extract:SI
1056 (match_operand 1 "ext_register_operand" "Q")
1057 (const_int 8)
1058 (const_int 8)) 0)))]
1059 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1060 "cmp{b}\t{%h1, %0|%0, %h1}"
1061 [(set_attr "type" "icmp")
1062 (set_attr "mode" "QI")])
1063
1064 (define_insn "*cmpqi_ext_1_rex64"
1065 [(set (reg FLAGS_REG)
1066 (compare
1067 (match_operand:QI 0 "register_operand" "Q")
1068 (subreg:QI
1069 (zero_extract:SI
1070 (match_operand 1 "ext_register_operand" "Q")
1071 (const_int 8)
1072 (const_int 8)) 0)))]
1073 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1074 "cmp{b}\t{%h1, %0|%0, %h1}"
1075 [(set_attr "type" "icmp")
1076 (set_attr "mode" "QI")])
1077
1078 (define_insn "*cmpqi_ext_2"
1079 [(set (reg FLAGS_REG)
1080 (compare
1081 (subreg:QI
1082 (zero_extract:SI
1083 (match_operand 0 "ext_register_operand" "Q")
1084 (const_int 8)
1085 (const_int 8)) 0)
1086 (match_operand:QI 1 "const0_operand" "")))]
1087 "ix86_match_ccmode (insn, CCNOmode)"
1088 "test{b}\t%h0, %h0"
1089 [(set_attr "type" "test")
1090 (set_attr "length_immediate" "0")
1091 (set_attr "mode" "QI")])
1092
1093 (define_expand "cmpqi_ext_3"
1094 [(set (reg:CC FLAGS_REG)
1095 (compare:CC
1096 (subreg:QI
1097 (zero_extract:SI
1098 (match_operand 0 "ext_register_operand" "")
1099 (const_int 8)
1100 (const_int 8)) 0)
1101 (match_operand:QI 1 "immediate_operand" "")))])
1102
1103 (define_insn "*cmpqi_ext_3_insn"
1104 [(set (reg FLAGS_REG)
1105 (compare
1106 (subreg:QI
1107 (zero_extract:SI
1108 (match_operand 0 "ext_register_operand" "Q")
1109 (const_int 8)
1110 (const_int 8)) 0)
1111 (match_operand:QI 1 "general_operand" "Qmn")))]
1112 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1113 "cmp{b}\t{%1, %h0|%h0, %1}"
1114 [(set_attr "type" "icmp")
1115 (set_attr "modrm" "1")
1116 (set_attr "mode" "QI")])
1117
1118 (define_insn "*cmpqi_ext_3_insn_rex64"
1119 [(set (reg FLAGS_REG)
1120 (compare
1121 (subreg:QI
1122 (zero_extract:SI
1123 (match_operand 0 "ext_register_operand" "Q")
1124 (const_int 8)
1125 (const_int 8)) 0)
1126 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1127 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1128 "cmp{b}\t{%1, %h0|%h0, %1}"
1129 [(set_attr "type" "icmp")
1130 (set_attr "modrm" "1")
1131 (set_attr "mode" "QI")])
1132
1133 (define_insn "*cmpqi_ext_4"
1134 [(set (reg FLAGS_REG)
1135 (compare
1136 (subreg:QI
1137 (zero_extract:SI
1138 (match_operand 0 "ext_register_operand" "Q")
1139 (const_int 8)
1140 (const_int 8)) 0)
1141 (subreg:QI
1142 (zero_extract:SI
1143 (match_operand 1 "ext_register_operand" "Q")
1144 (const_int 8)
1145 (const_int 8)) 0)))]
1146 "ix86_match_ccmode (insn, CCmode)"
1147 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1148 [(set_attr "type" "icmp")
1149 (set_attr "mode" "QI")])
1150
1151 ;; These implement float point compares.
1152 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1153 ;; which would allow mix and match FP modes on the compares. Which is what
1154 ;; the old patterns did, but with many more of them.
1155
1156 (define_expand "cbranchxf4"
1157 [(set (reg:CC FLAGS_REG)
1158 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1159 (match_operand:XF 2 "nonmemory_operand" "")))
1160 (set (pc) (if_then_else
1161 (match_operator 0 "ix86_fp_comparison_operator"
1162 [(reg:CC FLAGS_REG)
1163 (const_int 0)])
1164 (label_ref (match_operand 3 "" ""))
1165 (pc)))]
1166 "TARGET_80387"
1167 {
1168 ix86_expand_branch (GET_CODE (operands[0]),
1169 operands[1], operands[2], operands[3]);
1170 DONE;
1171 })
1172
1173 (define_expand "cstorexf4"
1174 [(set (reg:CC FLAGS_REG)
1175 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1176 (match_operand:XF 3 "nonmemory_operand" "")))
1177 (set (match_operand:QI 0 "register_operand" "")
1178 (match_operator 1 "ix86_fp_comparison_operator"
1179 [(reg:CC FLAGS_REG)
1180 (const_int 0)]))]
1181 "TARGET_80387"
1182 {
1183 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1184 operands[2], operands[3]);
1185 DONE;
1186 })
1187
1188 (define_expand "cbranch<mode>4"
1189 [(set (reg:CC FLAGS_REG)
1190 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1191 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1192 (set (pc) (if_then_else
1193 (match_operator 0 "ix86_fp_comparison_operator"
1194 [(reg:CC FLAGS_REG)
1195 (const_int 0)])
1196 (label_ref (match_operand 3 "" ""))
1197 (pc)))]
1198 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1199 {
1200 ix86_expand_branch (GET_CODE (operands[0]),
1201 operands[1], operands[2], operands[3]);
1202 DONE;
1203 })
1204
1205 (define_expand "cstore<mode>4"
1206 [(set (reg:CC FLAGS_REG)
1207 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1208 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1209 (set (match_operand:QI 0 "register_operand" "")
1210 (match_operator 1 "ix86_fp_comparison_operator"
1211 [(reg:CC FLAGS_REG)
1212 (const_int 0)]))]
1213 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1214 {
1215 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1216 operands[2], operands[3]);
1217 DONE;
1218 })
1219
1220 (define_expand "cbranchcc4"
1221 [(set (pc) (if_then_else
1222 (match_operator 0 "comparison_operator"
1223 [(match_operand 1 "flags_reg_operand" "")
1224 (match_operand 2 "const0_operand" "")])
1225 (label_ref (match_operand 3 "" ""))
1226 (pc)))]
1227 ""
1228 {
1229 ix86_expand_branch (GET_CODE (operands[0]),
1230 operands[1], operands[2], operands[3]);
1231 DONE;
1232 })
1233
1234 (define_expand "cstorecc4"
1235 [(set (match_operand:QI 0 "register_operand" "")
1236 (match_operator 1 "comparison_operator"
1237 [(match_operand 2 "flags_reg_operand" "")
1238 (match_operand 3 "const0_operand" "")]))]
1239 ""
1240 {
1241 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1242 operands[2], operands[3]);
1243 DONE;
1244 })
1245
1246
1247 ;; FP compares, step 1:
1248 ;; Set the FP condition codes.
1249 ;;
1250 ;; CCFPmode compare with exceptions
1251 ;; CCFPUmode compare with no exceptions
1252
1253 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1254 ;; used to manage the reg stack popping would not be preserved.
1255
1256 (define_insn "*cmpfp_0"
1257 [(set (match_operand:HI 0 "register_operand" "=a")
1258 (unspec:HI
1259 [(compare:CCFP
1260 (match_operand 1 "register_operand" "f")
1261 (match_operand 2 "const0_operand" ""))]
1262 UNSPEC_FNSTSW))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1264 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1265 "* return output_fp_compare (insn, operands, false, false);"
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1268 (set (attr "mode")
1269 (cond [(match_operand:SF 1 "" "")
1270 (const_string "SF")
1271 (match_operand:DF 1 "" "")
1272 (const_string "DF")
1273 ]
1274 (const_string "XF")))])
1275
1276 (define_insn_and_split "*cmpfp_0_cc"
1277 [(set (reg:CCFP FLAGS_REG)
1278 (compare:CCFP
1279 (match_operand 1 "register_operand" "f")
1280 (match_operand 2 "const0_operand" "")))
1281 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1283 && TARGET_SAHF && !TARGET_CMOVE
1284 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1285 "#"
1286 "&& reload_completed"
1287 [(set (match_dup 0)
1288 (unspec:HI
1289 [(compare:CCFP (match_dup 1)(match_dup 2))]
1290 UNSPEC_FNSTSW))
1291 (set (reg:CC FLAGS_REG)
1292 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1293 ""
1294 [(set_attr "type" "multi")
1295 (set_attr "unit" "i387")
1296 (set (attr "mode")
1297 (cond [(match_operand:SF 1 "" "")
1298 (const_string "SF")
1299 (match_operand:DF 1 "" "")
1300 (const_string "DF")
1301 ]
1302 (const_string "XF")))])
1303
1304 (define_insn "*cmpfp_xf"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1306 (unspec:HI
1307 [(compare:CCFP
1308 (match_operand:XF 1 "register_operand" "f")
1309 (match_operand:XF 2 "register_operand" "f"))]
1310 UNSPEC_FNSTSW))]
1311 "TARGET_80387"
1312 "* return output_fp_compare (insn, operands, false, false);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "XF")])
1316
1317 (define_insn_and_split "*cmpfp_xf_cc"
1318 [(set (reg:CCFP FLAGS_REG)
1319 (compare:CCFP
1320 (match_operand:XF 1 "register_operand" "f")
1321 (match_operand:XF 2 "register_operand" "f")))
1322 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1323 "TARGET_80387
1324 && TARGET_SAHF && !TARGET_CMOVE"
1325 "#"
1326 "&& reload_completed"
1327 [(set (match_dup 0)
1328 (unspec:HI
1329 [(compare:CCFP (match_dup 1)(match_dup 2))]
1330 UNSPEC_FNSTSW))
1331 (set (reg:CC FLAGS_REG)
1332 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1333 ""
1334 [(set_attr "type" "multi")
1335 (set_attr "unit" "i387")
1336 (set_attr "mode" "XF")])
1337
1338 (define_insn "*cmpfp_<mode>"
1339 [(set (match_operand:HI 0 "register_operand" "=a")
1340 (unspec:HI
1341 [(compare:CCFP
1342 (match_operand:MODEF 1 "register_operand" "f")
1343 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1344 UNSPEC_FNSTSW))]
1345 "TARGET_80387"
1346 "* return output_fp_compare (insn, operands, false, false);"
1347 [(set_attr "type" "multi")
1348 (set_attr "unit" "i387")
1349 (set_attr "mode" "<MODE>")])
1350
1351 (define_insn_and_split "*cmpfp_<mode>_cc"
1352 [(set (reg:CCFP FLAGS_REG)
1353 (compare:CCFP
1354 (match_operand:MODEF 1 "register_operand" "f")
1355 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1356 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1357 "TARGET_80387
1358 && TARGET_SAHF && !TARGET_CMOVE"
1359 "#"
1360 "&& reload_completed"
1361 [(set (match_dup 0)
1362 (unspec:HI
1363 [(compare:CCFP (match_dup 1)(match_dup 2))]
1364 UNSPEC_FNSTSW))
1365 (set (reg:CC FLAGS_REG)
1366 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1367 ""
1368 [(set_attr "type" "multi")
1369 (set_attr "unit" "i387")
1370 (set_attr "mode" "<MODE>")])
1371
1372 (define_insn "*cmpfp_u"
1373 [(set (match_operand:HI 0 "register_operand" "=a")
1374 (unspec:HI
1375 [(compare:CCFPU
1376 (match_operand 1 "register_operand" "f")
1377 (match_operand 2 "register_operand" "f"))]
1378 UNSPEC_FNSTSW))]
1379 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1380 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1381 "* return output_fp_compare (insn, operands, false, true);"
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1384 (set (attr "mode")
1385 (cond [(match_operand:SF 1 "" "")
1386 (const_string "SF")
1387 (match_operand:DF 1 "" "")
1388 (const_string "DF")
1389 ]
1390 (const_string "XF")))])
1391
1392 (define_insn_and_split "*cmpfp_u_cc"
1393 [(set (reg:CCFPU FLAGS_REG)
1394 (compare:CCFPU
1395 (match_operand 1 "register_operand" "f")
1396 (match_operand 2 "register_operand" "f")))
1397 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1398 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1399 && TARGET_SAHF && !TARGET_CMOVE
1400 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1401 "#"
1402 "&& reload_completed"
1403 [(set (match_dup 0)
1404 (unspec:HI
1405 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1406 UNSPEC_FNSTSW))
1407 (set (reg:CC FLAGS_REG)
1408 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1409 ""
1410 [(set_attr "type" "multi")
1411 (set_attr "unit" "i387")
1412 (set (attr "mode")
1413 (cond [(match_operand:SF 1 "" "")
1414 (const_string "SF")
1415 (match_operand:DF 1 "" "")
1416 (const_string "DF")
1417 ]
1418 (const_string "XF")))])
1419
1420 (define_insn "*cmpfp_<mode>"
1421 [(set (match_operand:HI 0 "register_operand" "=a")
1422 (unspec:HI
1423 [(compare:CCFP
1424 (match_operand 1 "register_operand" "f")
1425 (match_operator 3 "float_operator"
1426 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1427 UNSPEC_FNSTSW))]
1428 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1430 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1431 "* return output_fp_compare (insn, operands, false, false);"
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "fp_int_src" "true")
1435 (set_attr "mode" "<MODE>")])
1436
1437 (define_insn_and_split "*cmpfp_<mode>_cc"
1438 [(set (reg:CCFP FLAGS_REG)
1439 (compare:CCFP
1440 (match_operand 1 "register_operand" "f")
1441 (match_operator 3 "float_operator"
1442 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1443 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1444 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1445 && TARGET_SAHF && !TARGET_CMOVE
1446 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1447 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1448 "#"
1449 "&& reload_completed"
1450 [(set (match_dup 0)
1451 (unspec:HI
1452 [(compare:CCFP
1453 (match_dup 1)
1454 (match_op_dup 3 [(match_dup 2)]))]
1455 UNSPEC_FNSTSW))
1456 (set (reg:CC FLAGS_REG)
1457 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1458 ""
1459 [(set_attr "type" "multi")
1460 (set_attr "unit" "i387")
1461 (set_attr "fp_int_src" "true")
1462 (set_attr "mode" "<MODE>")])
1463
1464 ;; FP compares, step 2
1465 ;; Move the fpsw to ax.
1466
1467 (define_insn "x86_fnstsw_1"
1468 [(set (match_operand:HI 0 "register_operand" "=a")
1469 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1470 "TARGET_80387"
1471 "fnstsw\t%0"
1472 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1473 (set_attr "mode" "SI")
1474 (set_attr "unit" "i387")])
1475
1476 ;; FP compares, step 3
1477 ;; Get ax into flags, general case.
1478
1479 (define_insn "x86_sahf_1"
1480 [(set (reg:CC FLAGS_REG)
1481 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1482 UNSPEC_SAHF))]
1483 "TARGET_SAHF"
1484 {
1485 #ifndef HAVE_AS_IX86_SAHF
1486 if (TARGET_64BIT)
1487 return ASM_BYTE "0x9e";
1488 else
1489 #endif
1490 return "sahf";
1491 }
1492 [(set_attr "length" "1")
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")
1495 (set_attr "bdver1_decode" "direct")
1496 (set_attr "mode" "SI")])
1497
1498 ;; Pentium Pro can do steps 1 through 3 in one go.
1499 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1500 (define_insn "*cmpfp_i_mixed"
1501 [(set (reg:CCFP FLAGS_REG)
1502 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1503 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1504 "TARGET_MIX_SSE_I387
1505 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1506 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507 "* return output_fp_compare (insn, operands, true, false);"
1508 [(set_attr "type" "fcmp,ssecomi")
1509 (set_attr "prefix" "orig,maybe_vex")
1510 (set (attr "mode")
1511 (if_then_else (match_operand:SF 1 "" "")
1512 (const_string "SF")
1513 (const_string "DF")))
1514 (set (attr "prefix_rep")
1515 (if_then_else (eq_attr "type" "ssecomi")
1516 (const_string "0")
1517 (const_string "*")))
1518 (set (attr "prefix_data16")
1519 (cond [(eq_attr "type" "fcmp")
1520 (const_string "*")
1521 (eq_attr "mode" "DF")
1522 (const_string "1")
1523 ]
1524 (const_string "0")))
1525 (set_attr "athlon_decode" "vector")
1526 (set_attr "amdfam10_decode" "direct")
1527 (set_attr "bdver1_decode" "double")])
1528
1529 (define_insn "*cmpfp_i_sse"
1530 [(set (reg:CCFP FLAGS_REG)
1531 (compare:CCFP (match_operand 0 "register_operand" "x")
1532 (match_operand 1 "nonimmediate_operand" "xm")))]
1533 "TARGET_SSE_MATH
1534 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1535 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1536 "* return output_fp_compare (insn, operands, true, false);"
1537 [(set_attr "type" "ssecomi")
1538 (set_attr "prefix" "maybe_vex")
1539 (set (attr "mode")
1540 (if_then_else (match_operand:SF 1 "" "")
1541 (const_string "SF")
1542 (const_string "DF")))
1543 (set_attr "prefix_rep" "0")
1544 (set (attr "prefix_data16")
1545 (if_then_else (eq_attr "mode" "DF")
1546 (const_string "1")
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_i_i387"
1553 [(set (reg:CCFP FLAGS_REG)
1554 (compare:CCFP (match_operand 0 "register_operand" "f")
1555 (match_operand 1 "register_operand" "f")))]
1556 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1557 && TARGET_CMOVE
1558 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1559 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560 "* return output_fp_compare (insn, operands, true, false);"
1561 [(set_attr "type" "fcmp")
1562 (set (attr "mode")
1563 (cond [(match_operand:SF 1 "" "")
1564 (const_string "SF")
1565 (match_operand:DF 1 "" "")
1566 (const_string "DF")
1567 ]
1568 (const_string "XF")))
1569 (set_attr "athlon_decode" "vector")
1570 (set_attr "amdfam10_decode" "direct")
1571 (set_attr "bdver1_decode" "double")])
1572
1573 (define_insn "*cmpfp_iu_mixed"
1574 [(set (reg:CCFPU FLAGS_REG)
1575 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1576 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1577 "TARGET_MIX_SSE_I387
1578 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1579 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580 "* return output_fp_compare (insn, operands, true, true);"
1581 [(set_attr "type" "fcmp,ssecomi")
1582 (set_attr "prefix" "orig,maybe_vex")
1583 (set (attr "mode")
1584 (if_then_else (match_operand:SF 1 "" "")
1585 (const_string "SF")
1586 (const_string "DF")))
1587 (set (attr "prefix_rep")
1588 (if_then_else (eq_attr "type" "ssecomi")
1589 (const_string "0")
1590 (const_string "*")))
1591 (set (attr "prefix_data16")
1592 (cond [(eq_attr "type" "fcmp")
1593 (const_string "*")
1594 (eq_attr "mode" "DF")
1595 (const_string "1")
1596 ]
1597 (const_string "0")))
1598 (set_attr "athlon_decode" "vector")
1599 (set_attr "amdfam10_decode" "direct")
1600 (set_attr "bdver1_decode" "double")])
1601
1602 (define_insn "*cmpfp_iu_sse"
1603 [(set (reg:CCFPU FLAGS_REG)
1604 (compare:CCFPU (match_operand 0 "register_operand" "x")
1605 (match_operand 1 "nonimmediate_operand" "xm")))]
1606 "TARGET_SSE_MATH
1607 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1608 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1609 "* return output_fp_compare (insn, operands, true, true);"
1610 [(set_attr "type" "ssecomi")
1611 (set_attr "prefix" "maybe_vex")
1612 (set (attr "mode")
1613 (if_then_else (match_operand:SF 1 "" "")
1614 (const_string "SF")
1615 (const_string "DF")))
1616 (set_attr "prefix_rep" "0")
1617 (set (attr "prefix_data16")
1618 (if_then_else (eq_attr "mode" "DF")
1619 (const_string "1")
1620 (const_string "0")))
1621 (set_attr "athlon_decode" "vector")
1622 (set_attr "amdfam10_decode" "direct")
1623 (set_attr "bdver1_decode" "double")])
1624
1625 (define_insn "*cmpfp_iu_387"
1626 [(set (reg:CCFPU FLAGS_REG)
1627 (compare:CCFPU (match_operand 0 "register_operand" "f")
1628 (match_operand 1 "register_operand" "f")))]
1629 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1630 && TARGET_CMOVE
1631 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1632 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633 "* return output_fp_compare (insn, operands, true, true);"
1634 [(set_attr "type" "fcmp")
1635 (set (attr "mode")
1636 (cond [(match_operand:SF 1 "" "")
1637 (const_string "SF")
1638 (match_operand:DF 1 "" "")
1639 (const_string "DF")
1640 ]
1641 (const_string "XF")))
1642 (set_attr "athlon_decode" "vector")
1643 (set_attr "amdfam10_decode" "direct")
1644 (set_attr "bdver1_decode" "direct")])
1645 \f
1646 ;; Push/pop instructions.
1647
1648 (define_insn "*push<mode>2"
1649 [(set (match_operand:DWI 0 "push_operand" "=<")
1650 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1651 ""
1652 "#")
1653
1654 (define_split
1655 [(set (match_operand:TI 0 "push_operand" "")
1656 (match_operand:TI 1 "general_operand" ""))]
1657 "TARGET_64BIT && reload_completed
1658 && !SSE_REG_P (operands[1])"
1659 [(const_int 0)]
1660 "ix86_split_long_move (operands); DONE;")
1661
1662 (define_insn "*pushdi2_rex64"
1663 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1664 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1665 "TARGET_64BIT"
1666 "@
1667 push{q}\t%1
1668 #"
1669 [(set_attr "type" "push,multi")
1670 (set_attr "mode" "DI")])
1671
1672 ;; Convert impossible pushes of immediate to existing instructions.
1673 ;; First try to get scratch register and go through it. In case this
1674 ;; fails, push sign extended lower part first and then overwrite
1675 ;; upper part by 32bit move.
1676 (define_peephole2
1677 [(match_scratch:DI 2 "r")
1678 (set (match_operand:DI 0 "push_operand" "")
1679 (match_operand:DI 1 "immediate_operand" ""))]
1680 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1681 && !x86_64_immediate_operand (operands[1], DImode)"
1682 [(set (match_dup 2) (match_dup 1))
1683 (set (match_dup 0) (match_dup 2))])
1684
1685 ;; We need to define this as both peepholer and splitter for case
1686 ;; peephole2 pass is not run.
1687 ;; "&& 1" is needed to keep it from matching the previous pattern.
1688 (define_peephole2
1689 [(set (match_operand:DI 0 "push_operand" "")
1690 (match_operand:DI 1 "immediate_operand" ""))]
1691 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1692 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1693 [(set (match_dup 0) (match_dup 1))
1694 (set (match_dup 2) (match_dup 3))]
1695 {
1696 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1697
1698 operands[1] = gen_lowpart (DImode, operands[2]);
1699 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1700 GEN_INT (4)));
1701 })
1702
1703 (define_split
1704 [(set (match_operand:DI 0 "push_operand" "")
1705 (match_operand:DI 1 "immediate_operand" ""))]
1706 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1707 ? epilogue_completed : reload_completed)
1708 && !symbolic_operand (operands[1], DImode)
1709 && !x86_64_immediate_operand (operands[1], DImode)"
1710 [(set (match_dup 0) (match_dup 1))
1711 (set (match_dup 2) (match_dup 3))]
1712 {
1713 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1714
1715 operands[1] = gen_lowpart (DImode, operands[2]);
1716 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1717 GEN_INT (4)));
1718 })
1719
1720 (define_split
1721 [(set (match_operand:DI 0 "push_operand" "")
1722 (match_operand:DI 1 "general_operand" ""))]
1723 "!TARGET_64BIT && reload_completed
1724 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1725 [(const_int 0)]
1726 "ix86_split_long_move (operands); DONE;")
1727
1728 (define_insn "*pushsi2"
1729 [(set (match_operand:SI 0 "push_operand" "=<")
1730 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1731 "!TARGET_64BIT"
1732 "push{l}\t%1"
1733 [(set_attr "type" "push")
1734 (set_attr "mode" "SI")])
1735
1736 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1737 ;; "push a byte/word". But actually we use pushl, which has the effect
1738 ;; of rounding the amount pushed up to a word.
1739
1740 ;; For TARGET_64BIT we always round up to 8 bytes.
1741 (define_insn "*push<mode>2_rex64"
1742 [(set (match_operand:SWI124 0 "push_operand" "=X")
1743 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1744 "TARGET_64BIT"
1745 "push{q}\t%q1"
1746 [(set_attr "type" "push")
1747 (set_attr "mode" "DI")])
1748
1749 (define_insn "*push<mode>2"
1750 [(set (match_operand:SWI12 0 "push_operand" "=X")
1751 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1752 "!TARGET_64BIT"
1753 "push{l}\t%k1"
1754 [(set_attr "type" "push")
1755 (set_attr "mode" "SI")])
1756
1757 (define_insn "*push<mode>2_prologue"
1758 [(set (match_operand:P 0 "push_operand" "=<")
1759 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1760 (clobber (mem:BLK (scratch)))]
1761 ""
1762 "push{<imodesuffix>}\t%1"
1763 [(set_attr "type" "push")
1764 (set_attr "mode" "<MODE>")])
1765
1766 (define_insn "*pop<mode>1"
1767 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1768 (match_operand:P 1 "pop_operand" ">"))]
1769 ""
1770 "pop{<imodesuffix>}\t%0"
1771 [(set_attr "type" "pop")
1772 (set_attr "mode" "<MODE>")])
1773
1774 (define_insn "*pop<mode>1_epilogue"
1775 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1776 (match_operand:P 1 "pop_operand" ">"))
1777 (clobber (mem:BLK (scratch)))]
1778 ""
1779 "pop{<imodesuffix>}\t%0"
1780 [(set_attr "type" "pop")
1781 (set_attr "mode" "<MODE>")])
1782 \f
1783 ;; Move instructions.
1784
1785 (define_expand "movoi"
1786 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1787 (match_operand:OI 1 "general_operand" ""))]
1788 "TARGET_AVX"
1789 "ix86_expand_move (OImode, operands); DONE;")
1790
1791 (define_expand "movti"
1792 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1793 (match_operand:TI 1 "nonimmediate_operand" ""))]
1794 "TARGET_64BIT || TARGET_SSE"
1795 {
1796 if (TARGET_64BIT)
1797 ix86_expand_move (TImode, operands);
1798 else if (push_operand (operands[0], TImode))
1799 ix86_expand_push (TImode, operands[1]);
1800 else
1801 ix86_expand_vector_move (TImode, operands);
1802 DONE;
1803 })
1804
1805 ;; This expands to what emit_move_complex would generate if we didn't
1806 ;; have a movti pattern. Having this avoids problems with reload on
1807 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1808 ;; to have around all the time.
1809 (define_expand "movcdi"
1810 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1811 (match_operand:CDI 1 "general_operand" ""))]
1812 ""
1813 {
1814 if (push_operand (operands[0], CDImode))
1815 emit_move_complex_push (CDImode, operands[0], operands[1]);
1816 else
1817 emit_move_complex_parts (operands[0], operands[1]);
1818 DONE;
1819 })
1820
1821 (define_expand "mov<mode>"
1822 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1823 (match_operand:SWI1248x 1 "general_operand" ""))]
1824 ""
1825 "ix86_expand_move (<MODE>mode, operands); DONE;")
1826
1827 (define_insn "*mov<mode>_xor"
1828 [(set (match_operand:SWI48 0 "register_operand" "=r")
1829 (match_operand:SWI48 1 "const0_operand" ""))
1830 (clobber (reg:CC FLAGS_REG))]
1831 "reload_completed"
1832 "xor{l}\t%k0, %k0"
1833 [(set_attr "type" "alu1")
1834 (set_attr "mode" "SI")
1835 (set_attr "length_immediate" "0")])
1836
1837 (define_insn "*mov<mode>_or"
1838 [(set (match_operand:SWI48 0 "register_operand" "=r")
1839 (match_operand:SWI48 1 "const_int_operand" ""))
1840 (clobber (reg:CC FLAGS_REG))]
1841 "reload_completed
1842 && operands[1] == constm1_rtx"
1843 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1844 [(set_attr "type" "alu1")
1845 (set_attr "mode" "<MODE>")
1846 (set_attr "length_immediate" "1")])
1847
1848 (define_insn "*movoi_internal_avx"
1849 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1850 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1851 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1852 {
1853 switch (which_alternative)
1854 {
1855 case 0:
1856 return "vxorps\t%0, %0, %0";
1857 case 1:
1858 case 2:
1859 if (misaligned_operand (operands[0], OImode)
1860 || misaligned_operand (operands[1], OImode))
1861 return "vmovdqu\t{%1, %0|%0, %1}";
1862 else
1863 return "vmovdqa\t{%1, %0|%0, %1}";
1864 default:
1865 gcc_unreachable ();
1866 }
1867 }
1868 [(set_attr "type" "sselog1,ssemov,ssemov")
1869 (set_attr "prefix" "vex")
1870 (set_attr "mode" "OI")])
1871
1872 (define_insn "*movti_internal_rex64"
1873 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1874 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1875 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1876 {
1877 switch (which_alternative)
1878 {
1879 case 0:
1880 case 1:
1881 return "#";
1882 case 2:
1883 if (get_attr_mode (insn) == MODE_V4SF)
1884 return "%vxorps\t%0, %d0";
1885 else
1886 return "%vpxor\t%0, %d0";
1887 case 3:
1888 case 4:
1889 /* TDmode values are passed as TImode on the stack. Moving them
1890 to stack may result in unaligned memory access. */
1891 if (misaligned_operand (operands[0], TImode)
1892 || misaligned_operand (operands[1], TImode))
1893 {
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovups\t{%1, %0|%0, %1}";
1896 else
1897 return "%vmovdqu\t{%1, %0|%0, %1}";
1898 }
1899 else
1900 {
1901 if (get_attr_mode (insn) == MODE_V4SF)
1902 return "%vmovaps\t{%1, %0|%0, %1}";
1903 else
1904 return "%vmovdqa\t{%1, %0|%0, %1}";
1905 }
1906 default:
1907 gcc_unreachable ();
1908 }
1909 }
1910 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1911 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1912 (set (attr "mode")
1913 (cond [(eq_attr "alternative" "2,3")
1914 (if_then_else
1915 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1916 (const_int 0))
1917 (const_string "V4SF")
1918 (const_string "TI"))
1919 (eq_attr "alternative" "4")
1920 (if_then_else
1921 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1922 (const_int 0))
1923 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1924 (const_int 0)))
1925 (const_string "V4SF")
1926 (const_string "TI"))]
1927 (const_string "DI")))])
1928
1929 (define_split
1930 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1931 (match_operand:TI 1 "general_operand" ""))]
1932 "reload_completed
1933 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1934 [(const_int 0)]
1935 "ix86_split_long_move (operands); DONE;")
1936
1937 (define_insn "*movti_internal_sse"
1938 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1939 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1940 "TARGET_SSE && !TARGET_64BIT
1941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942 {
1943 switch (which_alternative)
1944 {
1945 case 0:
1946 if (get_attr_mode (insn) == MODE_V4SF)
1947 return "%vxorps\t%0, %d0";
1948 else
1949 return "%vpxor\t%0, %d0";
1950 case 1:
1951 case 2:
1952 /* TDmode values are passed as TImode on the stack. Moving them
1953 to stack may result in unaligned memory access. */
1954 if (misaligned_operand (operands[0], TImode)
1955 || misaligned_operand (operands[1], TImode))
1956 {
1957 if (get_attr_mode (insn) == MODE_V4SF)
1958 return "%vmovups\t{%1, %0|%0, %1}";
1959 else
1960 return "%vmovdqu\t{%1, %0|%0, %1}";
1961 }
1962 else
1963 {
1964 if (get_attr_mode (insn) == MODE_V4SF)
1965 return "%vmovaps\t{%1, %0|%0, %1}";
1966 else
1967 return "%vmovdqa\t{%1, %0|%0, %1}";
1968 }
1969 default:
1970 gcc_unreachable ();
1971 }
1972 }
1973 [(set_attr "type" "sselog1,ssemov,ssemov")
1974 (set_attr "prefix" "maybe_vex")
1975 (set (attr "mode")
1976 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1977 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1978 (const_int 0)))
1979 (const_string "V4SF")
1980 (and (eq_attr "alternative" "2")
1981 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1982 (const_int 0)))
1983 (const_string "V4SF")]
1984 (const_string "TI")))])
1985
1986 (define_insn "*movdi_internal_rex64"
1987 [(set (match_operand:DI 0 "nonimmediate_operand"
1988 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1989 (match_operand:DI 1 "general_operand"
1990 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1991 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 {
1993 switch (get_attr_type (insn))
1994 {
1995 case TYPE_SSECVT:
1996 if (SSE_REG_P (operands[0]))
1997 return "movq2dq\t{%1, %0|%0, %1}";
1998 else
1999 return "movdq2q\t{%1, %0|%0, %1}";
2000
2001 case TYPE_SSEMOV:
2002 if (get_attr_mode (insn) == MODE_TI)
2003 return "%vmovdqa\t{%1, %0|%0, %1}";
2004 /* Handle broken assemblers that require movd instead of movq. */
2005 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006 return "%vmovd\t{%1, %0|%0, %1}";
2007 else
2008 return "%vmovq\t{%1, %0|%0, %1}";
2009
2010 case TYPE_MMXMOV:
2011 /* Handle broken assemblers that require movd instead of movq. */
2012 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2013 return "movd\t{%1, %0|%0, %1}";
2014 else
2015 return "movq\t{%1, %0|%0, %1}";
2016
2017 case TYPE_SSELOG1:
2018 return "%vpxor\t%0, %d0";
2019
2020 case TYPE_MMX:
2021 return "pxor\t%0, %0";
2022
2023 case TYPE_MULTI:
2024 return "#";
2025
2026 case TYPE_LEA:
2027 return "lea{q}\t{%a1, %0|%0, %a1}";
2028
2029 default:
2030 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2031 if (get_attr_mode (insn) == MODE_SI)
2032 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2033 else if (which_alternative == 2)
2034 return "movabs{q}\t{%1, %0|%0, %1}";
2035 else
2036 return "mov{q}\t{%1, %0|%0, %1}";
2037 }
2038 }
2039 [(set (attr "type")
2040 (cond [(eq_attr "alternative" "5")
2041 (const_string "mmx")
2042 (eq_attr "alternative" "6,7,8,9,10")
2043 (const_string "mmxmov")
2044 (eq_attr "alternative" "11")
2045 (const_string "sselog1")
2046 (eq_attr "alternative" "12,13,14,15,16")
2047 (const_string "ssemov")
2048 (eq_attr "alternative" "17,18")
2049 (const_string "ssecvt")
2050 (eq_attr "alternative" "4")
2051 (const_string "multi")
2052 (match_operand:DI 1 "pic_32bit_operand" "")
2053 (const_string "lea")
2054 ]
2055 (const_string "imov")))
2056 (set (attr "modrm")
2057 (if_then_else
2058 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2059 (const_string "0")
2060 (const_string "*")))
2061 (set (attr "length_immediate")
2062 (if_then_else
2063 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2064 (const_string "8")
2065 (const_string "*")))
2066 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2067 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2068 (set (attr "prefix")
2069 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2070 (const_string "maybe_vex")
2071 (const_string "orig")))
2072 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2073
2074 ;; Convert impossible stores of immediate to existing instructions.
2075 ;; First try to get scratch register and go through it. In case this
2076 ;; fails, move by 32bit parts.
2077 (define_peephole2
2078 [(match_scratch:DI 2 "r")
2079 (set (match_operand:DI 0 "memory_operand" "")
2080 (match_operand:DI 1 "immediate_operand" ""))]
2081 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2082 && !x86_64_immediate_operand (operands[1], DImode)"
2083 [(set (match_dup 2) (match_dup 1))
2084 (set (match_dup 0) (match_dup 2))])
2085
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 ;; "&& 1" is needed to keep it from matching the previous pattern.
2089 (define_peephole2
2090 [(set (match_operand:DI 0 "memory_operand" "")
2091 (match_operand:DI 1 "immediate_operand" ""))]
2092 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2093 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2094 [(set (match_dup 2) (match_dup 3))
2095 (set (match_dup 4) (match_dup 5))]
2096 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2097
2098 (define_split
2099 [(set (match_operand:DI 0 "memory_operand" "")
2100 (match_operand:DI 1 "immediate_operand" ""))]
2101 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2102 ? epilogue_completed : reload_completed)
2103 && !symbolic_operand (operands[1], DImode)
2104 && !x86_64_immediate_operand (operands[1], DImode)"
2105 [(set (match_dup 2) (match_dup 3))
2106 (set (match_dup 4) (match_dup 5))]
2107 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2108
2109 (define_insn "*movdi_internal"
2110 [(set (match_operand:DI 0 "nonimmediate_operand"
2111 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2112 (match_operand:DI 1 "general_operand"
2113 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2114 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2115 "@
2116 #
2117 #
2118 pxor\t%0, %0
2119 movq\t{%1, %0|%0, %1}
2120 movq\t{%1, %0|%0, %1}
2121 %vpxor\t%0, %d0
2122 %vmovq\t{%1, %0|%0, %1}
2123 %vmovdqa\t{%1, %0|%0, %1}
2124 %vmovq\t{%1, %0|%0, %1}
2125 xorps\t%0, %0
2126 movlps\t{%1, %0|%0, %1}
2127 movaps\t{%1, %0|%0, %1}
2128 movlps\t{%1, %0|%0, %1}"
2129 [(set (attr "isa")
2130 (if_then_else (eq_attr "alternative" "9,10,11,12")
2131 (const_string "noavx")
2132 (const_string "base")))
2133 (set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2134 (set (attr "prefix")
2135 (if_then_else (eq_attr "alternative" "5,6,7,8")
2136 (const_string "maybe_vex")
2137 (const_string "orig")))
2138 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2139
2140 (define_split
2141 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2142 (match_operand:DI 1 "general_operand" ""))]
2143 "!TARGET_64BIT && reload_completed
2144 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2145 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2146 [(const_int 0)]
2147 "ix86_split_long_move (operands); DONE;")
2148
2149 (define_insn "*movsi_internal"
2150 [(set (match_operand:SI 0 "nonimmediate_operand"
2151 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2152 (match_operand:SI 1 "general_operand"
2153 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2154 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2155 {
2156 switch (get_attr_type (insn))
2157 {
2158 case TYPE_SSELOG1:
2159 if (get_attr_mode (insn) == MODE_TI)
2160 return "%vpxor\t%0, %d0";
2161 return "%vxorps\t%0, %d0";
2162
2163 case TYPE_SSEMOV:
2164 switch (get_attr_mode (insn))
2165 {
2166 case MODE_TI:
2167 return "%vmovdqa\t{%1, %0|%0, %1}";
2168 case MODE_V4SF:
2169 return "%vmovaps\t{%1, %0|%0, %1}";
2170 case MODE_SI:
2171 return "%vmovd\t{%1, %0|%0, %1}";
2172 case MODE_SF:
2173 return "%vmovss\t{%1, %0|%0, %1}";
2174 default:
2175 gcc_unreachable ();
2176 }
2177
2178 case TYPE_MMX:
2179 return "pxor\t%0, %0";
2180
2181 case TYPE_MMXMOV:
2182 if (get_attr_mode (insn) == MODE_DI)
2183 return "movq\t{%1, %0|%0, %1}";
2184 return "movd\t{%1, %0|%0, %1}";
2185
2186 case TYPE_LEA:
2187 return "lea{l}\t{%a1, %0|%0, %a1}";
2188
2189 default:
2190 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2191 return "mov{l}\t{%1, %0|%0, %1}";
2192 }
2193 }
2194 [(set (attr "type")
2195 (cond [(eq_attr "alternative" "2")
2196 (const_string "mmx")
2197 (eq_attr "alternative" "3,4,5")
2198 (const_string "mmxmov")
2199 (eq_attr "alternative" "6")
2200 (const_string "sselog1")
2201 (eq_attr "alternative" "7,8,9,10,11")
2202 (const_string "ssemov")
2203 (match_operand:DI 1 "pic_32bit_operand" "")
2204 (const_string "lea")
2205 ]
2206 (const_string "imov")))
2207 (set (attr "prefix")
2208 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2209 (const_string "orig")
2210 (const_string "maybe_vex")))
2211 (set (attr "prefix_data16")
2212 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2213 (const_string "1")
2214 (const_string "*")))
2215 (set (attr "mode")
2216 (cond [(eq_attr "alternative" "2,3")
2217 (const_string "DI")
2218 (eq_attr "alternative" "6,7")
2219 (if_then_else
2220 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2221 (const_string "V4SF")
2222 (const_string "TI"))
2223 (and (eq_attr "alternative" "8,9,10,11")
2224 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2225 (const_string "SF")
2226 ]
2227 (const_string "SI")))])
2228
2229 (define_insn "*movhi_internal"
2230 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2231 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2232 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2233 {
2234 switch (get_attr_type (insn))
2235 {
2236 case TYPE_IMOVX:
2237 /* movzwl is faster than movw on p2 due to partial word stalls,
2238 though not as fast as an aligned movl. */
2239 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2240 default:
2241 if (get_attr_mode (insn) == MODE_SI)
2242 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2243 else
2244 return "mov{w}\t{%1, %0|%0, %1}";
2245 }
2246 }
2247 [(set (attr "type")
2248 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2249 (const_int 0))
2250 (const_string "imov")
2251 (and (eq_attr "alternative" "0")
2252 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2253 (const_int 0))
2254 (eq (symbol_ref "TARGET_HIMODE_MATH")
2255 (const_int 0))))
2256 (const_string "imov")
2257 (and (eq_attr "alternative" "1,2")
2258 (match_operand:HI 1 "aligned_operand" ""))
2259 (const_string "imov")
2260 (and (ne (symbol_ref "TARGET_MOVX")
2261 (const_int 0))
2262 (eq_attr "alternative" "0,2"))
2263 (const_string "imovx")
2264 ]
2265 (const_string "imov")))
2266 (set (attr "mode")
2267 (cond [(eq_attr "type" "imovx")
2268 (const_string "SI")
2269 (and (eq_attr "alternative" "1,2")
2270 (match_operand:HI 1 "aligned_operand" ""))
2271 (const_string "SI")
2272 (and (eq_attr "alternative" "0")
2273 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2274 (const_int 0))
2275 (eq (symbol_ref "TARGET_HIMODE_MATH")
2276 (const_int 0))))
2277 (const_string "SI")
2278 ]
2279 (const_string "HI")))])
2280
2281 ;; Situation is quite tricky about when to choose full sized (SImode) move
2282 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2283 ;; partial register dependency machines (such as AMD Athlon), where QImode
2284 ;; moves issue extra dependency and for partial register stalls machines
2285 ;; that don't use QImode patterns (and QImode move cause stall on the next
2286 ;; instruction).
2287 ;;
2288 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2289 ;; register stall machines with, where we use QImode instructions, since
2290 ;; partial register stall can be caused there. Then we use movzx.
2291 (define_insn "*movqi_internal"
2292 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2293 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2294 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2295 {
2296 switch (get_attr_type (insn))
2297 {
2298 case TYPE_IMOVX:
2299 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2300 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2301 default:
2302 if (get_attr_mode (insn) == MODE_SI)
2303 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2304 else
2305 return "mov{b}\t{%1, %0|%0, %1}";
2306 }
2307 }
2308 [(set (attr "type")
2309 (cond [(and (eq_attr "alternative" "5")
2310 (not (match_operand:QI 1 "aligned_operand" "")))
2311 (const_string "imovx")
2312 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2313 (const_int 0))
2314 (const_string "imov")
2315 (and (eq_attr "alternative" "3")
2316 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2317 (const_int 0))
2318 (eq (symbol_ref "TARGET_QIMODE_MATH")
2319 (const_int 0))))
2320 (const_string "imov")
2321 (eq_attr "alternative" "3,5")
2322 (const_string "imovx")
2323 (and (ne (symbol_ref "TARGET_MOVX")
2324 (const_int 0))
2325 (eq_attr "alternative" "2"))
2326 (const_string "imovx")
2327 ]
2328 (const_string "imov")))
2329 (set (attr "mode")
2330 (cond [(eq_attr "alternative" "3,4,5")
2331 (const_string "SI")
2332 (eq_attr "alternative" "6")
2333 (const_string "QI")
2334 (eq_attr "type" "imovx")
2335 (const_string "SI")
2336 (and (eq_attr "type" "imov")
2337 (and (eq_attr "alternative" "0,1")
2338 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2339 (const_int 0))
2340 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2341 (const_int 0))
2342 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2343 (const_int 0))))))
2344 (const_string "SI")
2345 ;; Avoid partial register stalls when not using QImode arithmetic
2346 (and (eq_attr "type" "imov")
2347 (and (eq_attr "alternative" "0,1")
2348 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2349 (const_int 0))
2350 (eq (symbol_ref "TARGET_QIMODE_MATH")
2351 (const_int 0)))))
2352 (const_string "SI")
2353 ]
2354 (const_string "QI")))])
2355
2356 ;; Stores and loads of ax to arbitrary constant address.
2357 ;; We fake an second form of instruction to force reload to load address
2358 ;; into register when rax is not available
2359 (define_insn "*movabs<mode>_1"
2360 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2361 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2362 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2363 "@
2364 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2365 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2366 [(set_attr "type" "imov")
2367 (set_attr "modrm" "0,*")
2368 (set_attr "length_address" "8,0")
2369 (set_attr "length_immediate" "0,*")
2370 (set_attr "memory" "store")
2371 (set_attr "mode" "<MODE>")])
2372
2373 (define_insn "*movabs<mode>_2"
2374 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2375 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2376 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2377 "@
2378 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2379 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2380 [(set_attr "type" "imov")
2381 (set_attr "modrm" "0,*")
2382 (set_attr "length_address" "8,0")
2383 (set_attr "length_immediate" "0")
2384 (set_attr "memory" "load")
2385 (set_attr "mode" "<MODE>")])
2386
2387 (define_insn "*swap<mode>"
2388 [(set (match_operand:SWI48 0 "register_operand" "+r")
2389 (match_operand:SWI48 1 "register_operand" "+r"))
2390 (set (match_dup 1)
2391 (match_dup 0))]
2392 ""
2393 "xchg{<imodesuffix>}\t%1, %0"
2394 [(set_attr "type" "imov")
2395 (set_attr "mode" "<MODE>")
2396 (set_attr "pent_pair" "np")
2397 (set_attr "athlon_decode" "vector")
2398 (set_attr "amdfam10_decode" "double")
2399 (set_attr "bdver1_decode" "double")])
2400
2401 (define_insn "*swap<mode>_1"
2402 [(set (match_operand:SWI12 0 "register_operand" "+r")
2403 (match_operand:SWI12 1 "register_operand" "+r"))
2404 (set (match_dup 1)
2405 (match_dup 0))]
2406 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2407 "xchg{l}\t%k1, %k0"
2408 [(set_attr "type" "imov")
2409 (set_attr "mode" "SI")
2410 (set_attr "pent_pair" "np")
2411 (set_attr "athlon_decode" "vector")
2412 (set_attr "amdfam10_decode" "double")
2413 (set_attr "bdver1_decode" "double")])
2414
2415 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2416 ;; is disabled for AMDFAM10
2417 (define_insn "*swap<mode>_2"
2418 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2419 (match_operand:SWI12 1 "register_operand" "+<r>"))
2420 (set (match_dup 1)
2421 (match_dup 0))]
2422 "TARGET_PARTIAL_REG_STALL"
2423 "xchg{<imodesuffix>}\t%1, %0"
2424 [(set_attr "type" "imov")
2425 (set_attr "mode" "<MODE>")
2426 (set_attr "pent_pair" "np")
2427 (set_attr "athlon_decode" "vector")])
2428
2429 (define_expand "movstrict<mode>"
2430 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2431 (match_operand:SWI12 1 "general_operand" ""))]
2432 ""
2433 {
2434 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2435 FAIL;
2436 if (GET_CODE (operands[0]) == SUBREG
2437 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2438 FAIL;
2439 /* Don't generate memory->memory moves, go through a register */
2440 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2441 operands[1] = force_reg (<MODE>mode, operands[1]);
2442 })
2443
2444 (define_insn "*movstrict<mode>_1"
2445 [(set (strict_low_part
2446 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2447 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2448 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2450 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2451 [(set_attr "type" "imov")
2452 (set_attr "mode" "<MODE>")])
2453
2454 (define_insn "*movstrict<mode>_xor"
2455 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2456 (match_operand:SWI12 1 "const0_operand" ""))
2457 (clobber (reg:CC FLAGS_REG))]
2458 "reload_completed"
2459 "xor{<imodesuffix>}\t%0, %0"
2460 [(set_attr "type" "alu1")
2461 (set_attr "mode" "<MODE>")
2462 (set_attr "length_immediate" "0")])
2463
2464 (define_insn "*mov<mode>_extv_1"
2465 [(set (match_operand:SWI24 0 "register_operand" "=R")
2466 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2467 (const_int 8)
2468 (const_int 8)))]
2469 ""
2470 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2471 [(set_attr "type" "imovx")
2472 (set_attr "mode" "SI")])
2473
2474 (define_insn "*movqi_extv_1_rex64"
2475 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2476 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2477 (const_int 8)
2478 (const_int 8)))]
2479 "TARGET_64BIT"
2480 {
2481 switch (get_attr_type (insn))
2482 {
2483 case TYPE_IMOVX:
2484 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2485 default:
2486 return "mov{b}\t{%h1, %0|%0, %h1}";
2487 }
2488 }
2489 [(set (attr "type")
2490 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2491 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2492 (ne (symbol_ref "TARGET_MOVX")
2493 (const_int 0))))
2494 (const_string "imovx")
2495 (const_string "imov")))
2496 (set (attr "mode")
2497 (if_then_else (eq_attr "type" "imovx")
2498 (const_string "SI")
2499 (const_string "QI")))])
2500
2501 (define_insn "*movqi_extv_1"
2502 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2503 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2504 (const_int 8)
2505 (const_int 8)))]
2506 "!TARGET_64BIT"
2507 {
2508 switch (get_attr_type (insn))
2509 {
2510 case TYPE_IMOVX:
2511 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2512 default:
2513 return "mov{b}\t{%h1, %0|%0, %h1}";
2514 }
2515 }
2516 [(set (attr "type")
2517 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2518 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2519 (ne (symbol_ref "TARGET_MOVX")
2520 (const_int 0))))
2521 (const_string "imovx")
2522 (const_string "imov")))
2523 (set (attr "mode")
2524 (if_then_else (eq_attr "type" "imovx")
2525 (const_string "SI")
2526 (const_string "QI")))])
2527
2528 (define_insn "*mov<mode>_extzv_1"
2529 [(set (match_operand:SWI48 0 "register_operand" "=R")
2530 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2531 (const_int 8)
2532 (const_int 8)))]
2533 ""
2534 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535 [(set_attr "type" "imovx")
2536 (set_attr "mode" "SI")])
2537
2538 (define_insn "*movqi_extzv_2_rex64"
2539 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2540 (subreg:QI
2541 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2542 (const_int 8)
2543 (const_int 8)) 0))]
2544 "TARGET_64BIT"
2545 {
2546 switch (get_attr_type (insn))
2547 {
2548 case TYPE_IMOVX:
2549 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2550 default:
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2552 }
2553 }
2554 [(set (attr "type")
2555 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2556 (ne (symbol_ref "TARGET_MOVX")
2557 (const_int 0)))
2558 (const_string "imovx")
2559 (const_string "imov")))
2560 (set (attr "mode")
2561 (if_then_else (eq_attr "type" "imovx")
2562 (const_string "SI")
2563 (const_string "QI")))])
2564
2565 (define_insn "*movqi_extzv_2"
2566 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2567 (subreg:QI
2568 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2569 (const_int 8)
2570 (const_int 8)) 0))]
2571 "!TARGET_64BIT"
2572 {
2573 switch (get_attr_type (insn))
2574 {
2575 case TYPE_IMOVX:
2576 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2577 default:
2578 return "mov{b}\t{%h1, %0|%0, %h1}";
2579 }
2580 }
2581 [(set (attr "type")
2582 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2583 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2584 (ne (symbol_ref "TARGET_MOVX")
2585 (const_int 0))))
2586 (const_string "imovx")
2587 (const_string "imov")))
2588 (set (attr "mode")
2589 (if_then_else (eq_attr "type" "imovx")
2590 (const_string "SI")
2591 (const_string "QI")))])
2592
2593 (define_expand "mov<mode>_insv_1"
2594 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2595 (const_int 8)
2596 (const_int 8))
2597 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2598
2599 (define_insn "*mov<mode>_insv_1_rex64"
2600 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2601 (const_int 8)
2602 (const_int 8))
2603 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2604 "TARGET_64BIT"
2605 "mov{b}\t{%b1, %h0|%h0, %b1}"
2606 [(set_attr "type" "imov")
2607 (set_attr "mode" "QI")])
2608
2609 (define_insn "*movsi_insv_1"
2610 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2611 (const_int 8)
2612 (const_int 8))
2613 (match_operand:SI 1 "general_operand" "Qmn"))]
2614 "!TARGET_64BIT"
2615 "mov{b}\t{%b1, %h0|%h0, %b1}"
2616 [(set_attr "type" "imov")
2617 (set_attr "mode" "QI")])
2618
2619 (define_insn "*movqi_insv_2"
2620 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2621 (const_int 8)
2622 (const_int 8))
2623 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2624 (const_int 8)))]
2625 ""
2626 "mov{b}\t{%h1, %h0|%h0, %h1}"
2627 [(set_attr "type" "imov")
2628 (set_attr "mode" "QI")])
2629 \f
2630 ;; Floating point push instructions.
2631
2632 (define_insn "*pushtf"
2633 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2634 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2635 "TARGET_SSE2"
2636 {
2637 /* This insn should be already split before reg-stack. */
2638 gcc_unreachable ();
2639 }
2640 [(set_attr "type" "multi")
2641 (set_attr "unit" "sse,*,*")
2642 (set_attr "mode" "TF,SI,SI")])
2643
2644 (define_split
2645 [(set (match_operand:TF 0 "push_operand" "")
2646 (match_operand:TF 1 "sse_reg_operand" ""))]
2647 "TARGET_SSE2 && reload_completed"
2648 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2649 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2650
2651 (define_split
2652 [(set (match_operand:TF 0 "push_operand" "")
2653 (match_operand:TF 1 "general_operand" ""))]
2654 "TARGET_SSE2 && reload_completed
2655 && !SSE_REG_P (operands[1])"
2656 [(const_int 0)]
2657 "ix86_split_long_move (operands); DONE;")
2658
2659 (define_insn "*pushxf"
2660 [(set (match_operand:XF 0 "push_operand" "=<,<")
2661 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2662 "optimize_function_for_speed_p (cfun)"
2663 {
2664 /* This insn should be already split before reg-stack. */
2665 gcc_unreachable ();
2666 }
2667 [(set_attr "type" "multi")
2668 (set_attr "unit" "i387,*")
2669 (set_attr "mode" "XF,SI")])
2670
2671 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2672 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2673 ;; Pushing using integer instructions is longer except for constants
2674 ;; and direct memory references (assuming that any given constant is pushed
2675 ;; only once, but this ought to be handled elsewhere).
2676
2677 (define_insn "*pushxf_nointeger"
2678 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2679 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2680 "optimize_function_for_size_p (cfun)"
2681 {
2682 /* This insn should be already split before reg-stack. */
2683 gcc_unreachable ();
2684 }
2685 [(set_attr "type" "multi")
2686 (set_attr "unit" "i387,*,*")
2687 (set_attr "mode" "XF,SI,SI")])
2688
2689 (define_split
2690 [(set (match_operand:XF 0 "push_operand" "")
2691 (match_operand:XF 1 "fp_register_operand" ""))]
2692 "reload_completed"
2693 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2694 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2695 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2696
2697 (define_split
2698 [(set (match_operand:XF 0 "push_operand" "")
2699 (match_operand:XF 1 "general_operand" ""))]
2700 "reload_completed
2701 && !FP_REG_P (operands[1])"
2702 [(const_int 0)]
2703 "ix86_split_long_move (operands); DONE;")
2704
2705 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2706 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2707 ;; On the average, pushdf using integers can be still shorter.
2708
2709 (define_insn "*pushdf"
2710 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2711 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2712 ""
2713 {
2714 /* This insn should be already split before reg-stack. */
2715 gcc_unreachable ();
2716 }
2717 [(set_attr "type" "multi")
2718 (set_attr "unit" "i387,*,*")
2719 (set_attr "mode" "DF,SI,DF")])
2720
2721 ;; %%% Kill this when call knows how to work this out.
2722 (define_split
2723 [(set (match_operand:DF 0 "push_operand" "")
2724 (match_operand:DF 1 "any_fp_register_operand" ""))]
2725 "reload_completed"
2726 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2727 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2728
2729 (define_split
2730 [(set (match_operand:DF 0 "push_operand" "")
2731 (match_operand:DF 1 "general_operand" ""))]
2732 "reload_completed
2733 && !ANY_FP_REG_P (operands[1])"
2734 [(const_int 0)]
2735 "ix86_split_long_move (operands); DONE;")
2736
2737 (define_insn "*pushsf_rex64"
2738 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2739 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2740 "TARGET_64BIT"
2741 {
2742 /* Anything else should be already split before reg-stack. */
2743 gcc_assert (which_alternative == 1);
2744 return "push{q}\t%q1";
2745 }
2746 [(set_attr "type" "multi,push,multi")
2747 (set_attr "unit" "i387,*,*")
2748 (set_attr "mode" "SF,DI,SF")])
2749
2750 (define_insn "*pushsf"
2751 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2752 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2753 "!TARGET_64BIT"
2754 {
2755 /* Anything else should be already split before reg-stack. */
2756 gcc_assert (which_alternative == 1);
2757 return "push{l}\t%1";
2758 }
2759 [(set_attr "type" "multi,push,multi")
2760 (set_attr "unit" "i387,*,*")
2761 (set_attr "mode" "SF,SI,SF")])
2762
2763 (define_split
2764 [(set (match_operand:SF 0 "push_operand" "")
2765 (match_operand:SF 1 "memory_operand" ""))]
2766 "reload_completed
2767 && MEM_P (operands[1])
2768 && (operands[2] = find_constant_src (insn))"
2769 [(set (match_dup 0)
2770 (match_dup 2))])
2771
2772 ;; %%% Kill this when call knows how to work this out.
2773 (define_split
2774 [(set (match_operand:SF 0 "push_operand" "")
2775 (match_operand:SF 1 "any_fp_register_operand" ""))]
2776 "reload_completed"
2777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2780 \f
2781 ;; Floating point move instructions.
2782
2783 (define_expand "movtf"
2784 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2785 (match_operand:TF 1 "nonimmediate_operand" ""))]
2786 "TARGET_SSE2"
2787 {
2788 ix86_expand_move (TFmode, operands);
2789 DONE;
2790 })
2791
2792 (define_expand "mov<mode>"
2793 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2794 (match_operand:X87MODEF 1 "general_operand" ""))]
2795 ""
2796 "ix86_expand_move (<MODE>mode, operands); DONE;")
2797
2798 (define_insn "*movtf_internal"
2799 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2800 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2801 "TARGET_SSE2
2802 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2803 {
2804 switch (which_alternative)
2805 {
2806 case 0:
2807 case 1:
2808 if (get_attr_mode (insn) == MODE_V4SF)
2809 return "%vmovaps\t{%1, %0|%0, %1}";
2810 else
2811 return "%vmovdqa\t{%1, %0|%0, %1}";
2812
2813 case 2:
2814 return standard_sse_constant_opcode (insn, operands[1]);
2815
2816 case 3:
2817 case 4:
2818 return "#";
2819
2820 default:
2821 gcc_unreachable ();
2822 }
2823 }
2824 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2825 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2826 (set (attr "mode")
2827 (cond [(eq_attr "alternative" "0,2")
2828 (if_then_else
2829 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2830 (const_int 0))
2831 (const_string "V4SF")
2832 (const_string "TI"))
2833 (eq_attr "alternative" "1")
2834 (if_then_else
2835 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2836 (const_int 0))
2837 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2838 (const_int 0)))
2839 (const_string "V4SF")
2840 (const_string "TI"))]
2841 (const_string "DI")))])
2842
2843 (define_split
2844 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2845 (match_operand:TF 1 "general_operand" ""))]
2846 "reload_completed
2847 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2848 [(const_int 0)]
2849 "ix86_split_long_move (operands); DONE;")
2850
2851 (define_insn "*movxf_internal"
2852 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,Yx*r ,o")
2853 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2854 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2855 && (!can_create_pseudo_p ()
2856 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2857 || GET_CODE (operands[1]) != CONST_DOUBLE
2858 || (optimize_function_for_size_p (cfun)
2859 && standard_80387_constant_p (operands[1]) > 0)
2860 || memory_operand (operands[0], XFmode))"
2861 {
2862 switch (which_alternative)
2863 {
2864 case 0:
2865 case 1:
2866 return output_387_reg_move (insn, operands);
2867
2868 case 2:
2869 return standard_80387_constant_opcode (operands[1]);
2870
2871 case 3: case 4:
2872 return "#";
2873 default:
2874 gcc_unreachable ();
2875 }
2876 }
2877 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2878 (set_attr "mode" "XF,XF,XF,SI,SI")])
2879
2880 (define_split
2881 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2882 (match_operand:XF 1 "general_operand" ""))]
2883 "reload_completed
2884 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2885 && ! (FP_REG_P (operands[0]) ||
2886 (GET_CODE (operands[0]) == SUBREG
2887 && FP_REG_P (SUBREG_REG (operands[0]))))
2888 && ! (FP_REG_P (operands[1]) ||
2889 (GET_CODE (operands[1]) == SUBREG
2890 && FP_REG_P (SUBREG_REG (operands[1]))))"
2891 [(const_int 0)]
2892 "ix86_split_long_move (operands); DONE;")
2893
2894 (define_insn "*movdf_internal_rex64"
2895 [(set (match_operand:DF 0 "nonimmediate_operand"
2896 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2897 (match_operand:DF 1 "general_operand"
2898 "fm,f,G,rm,r,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2899 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2900 && (!can_create_pseudo_p ()
2901 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2902 || GET_CODE (operands[1]) != CONST_DOUBLE
2903 || (optimize_function_for_size_p (cfun)
2904 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2905 && standard_80387_constant_p (operands[1]) > 0)
2906 || (TARGET_SSE2 && TARGET_SSE_MATH
2907 && standard_sse_constant_p (operands[1]))))
2908 || memory_operand (operands[0], DFmode))"
2909 {
2910 switch (which_alternative)
2911 {
2912 case 0:
2913 case 1:
2914 return output_387_reg_move (insn, operands);
2915
2916 case 2:
2917 return standard_80387_constant_opcode (operands[1]);
2918
2919 case 3:
2920 case 4:
2921 return "mov{q}\t{%1, %0|%0, %1}";
2922
2923 case 5:
2924 return "movabs{q}\t{%1, %0|%0, %1}";
2925
2926 case 6:
2927 return "#";
2928
2929 case 7:
2930 return standard_sse_constant_opcode (insn, operands[1]);
2931
2932 case 8:
2933 case 9:
2934 case 10:
2935 switch (get_attr_mode (insn))
2936 {
2937 case MODE_V4SF:
2938 return "%vmovaps\t{%1, %0|%0, %1}";
2939 case MODE_V2DF:
2940 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2941 return "%vmovaps\t{%1, %0|%0, %1}";
2942 else
2943 return "%vmovapd\t{%1, %0|%0, %1}";
2944 case MODE_TI:
2945 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946 return "%vmovaps\t{%1, %0|%0, %1}";
2947 else
2948 return "%vmovdqa\t{%1, %0|%0, %1}";
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 else
2955 return "%vmovsd\t{%1, %0|%0, %1}";
2956 case MODE_V1DF:
2957 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2958 case MODE_V2SF:
2959 return "%vmovlps\t{%1, %d0|%d0, %1}";
2960 default:
2961 gcc_unreachable ();
2962 }
2963
2964 case 11:
2965 case 12:
2966 /* Handle broken assemblers that require movd instead of movq. */
2967 return "%vmovd\t{%1, %0|%0, %1}";
2968
2969 default:
2970 gcc_unreachable();
2971 }
2972 }
2973 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2974 (set (attr "modrm")
2975 (if_then_else
2976 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2977 (const_string "0")
2978 (const_string "*")))
2979 (set (attr "length_immediate")
2980 (if_then_else
2981 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2982 (const_string "8")
2983 (const_string "*")))
2984 (set (attr "prefix")
2985 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2986 (const_string "orig")
2987 (const_string "maybe_vex")))
2988 (set (attr "prefix_data16")
2989 (if_then_else (eq_attr "mode" "V1DF")
2990 (const_string "1")
2991 (const_string "*")))
2992 (set (attr "mode")
2993 (cond [(eq_attr "alternative" "0,1,2")
2994 (const_string "DF")
2995 (eq_attr "alternative" "3,4,5,6,11,12")
2996 (const_string "DI")
2997
2998 /* For SSE1, we have many fewer alternatives. */
2999 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3000 (cond [(eq_attr "alternative" "7,8")
3001 (const_string "V4SF")
3002 ]
3003 (const_string "V2SF"))
3004
3005 /* xorps is one byte shorter. */
3006 (eq_attr "alternative" "7")
3007 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3008 (const_int 0))
3009 (const_string "V4SF")
3010 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3011 (const_int 0))
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 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3024 (const_int 0))
3025 (const_string "V4SF")
3026 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3027 (const_int 0))
3028 (const_string "V2DF")
3029 ]
3030 (const_string "DF"))
3031 /* For architectures resolving dependencies on register
3032 parts we may avoid extra work to zero out upper part
3033 of register. */
3034 (eq_attr "alternative" "9")
3035 (if_then_else
3036 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3037 (const_int 0))
3038 (const_string "V1DF")
3039 (const_string "DF"))
3040 ]
3041 (const_string "DF")))])
3042
3043 ;; Possible store forwarding (partial memory) stall in alternative 4.
3044 (define_insn "*movdf_internal"
3045 [(set (match_operand:DF 0 "nonimmediate_operand"
3046 "=f,m,f,Yd*r ,o ,Y2*x,Y2*x,Y2*x,m ")
3047 (match_operand:DF 1 "general_operand"
3048 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3049 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3050 && (!can_create_pseudo_p ()
3051 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3052 || GET_CODE (operands[1]) != CONST_DOUBLE
3053 || (!TARGET_INTEGER_DFMODE_MOVES
3054 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3055 && standard_80387_constant_p (operands[1]) > 0)
3056 || (TARGET_SSE2 && TARGET_SSE_MATH
3057 && standard_sse_constant_p (operands[1])))
3058 && !memory_operand (operands[0], DFmode))
3059 || ((TARGET_INTEGER_DFMODE_MOVES
3060 || !TARGET_MEMORY_MISMATCH_STALL)
3061 && memory_operand (operands[0], DFmode)))"
3062 {
3063 switch (which_alternative)
3064 {
3065 case 0:
3066 case 1:
3067 return output_387_reg_move (insn, operands);
3068
3069 case 2:
3070 return standard_80387_constant_opcode (operands[1]);
3071
3072 case 3:
3073 case 4:
3074 return "#";
3075
3076 case 5:
3077 return standard_sse_constant_opcode (insn, operands[1]);
3078
3079 case 6:
3080 case 7:
3081 case 8:
3082 switch (get_attr_mode (insn))
3083 {
3084 case MODE_V4SF:
3085 return "%vmovaps\t{%1, %0|%0, %1}";
3086 case MODE_V2DF:
3087 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3088 return "%vmovaps\t{%1, %0|%0, %1}";
3089 else
3090 return "%vmovapd\t{%1, %0|%0, %1}";
3091 case MODE_TI:
3092 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "%vmovaps\t{%1, %0|%0, %1}";
3094 else
3095 return "%vmovdqa\t{%1, %0|%0, %1}";
3096 case MODE_DI:
3097 return "%vmovq\t{%1, %0|%0, %1}";
3098 case MODE_DF:
3099 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3100 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3101 else
3102 return "%vmovsd\t{%1, %0|%0, %1}";
3103 case MODE_V1DF:
3104 if (TARGET_AVX && REG_P (operands[0]))
3105 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3106 else
3107 return "%vmovlpd\t{%1, %0|%0, %1}";
3108 case MODE_V2SF:
3109 if (TARGET_AVX && REG_P (operands[0]))
3110 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3111 else
3112 return "%vmovlps\t{%1, %0|%0, %1}";
3113 default:
3114 gcc_unreachable ();
3115 }
3116
3117 default:
3118 gcc_unreachable ();
3119 }
3120 }
3121 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3122 (set (attr "prefix")
3123 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3124 (const_string "orig")
3125 (const_string "maybe_vex")))
3126 (set (attr "prefix_data16")
3127 (if_then_else (eq_attr "mode" "V1DF")
3128 (const_string "1")
3129 (const_string "*")))
3130 (set (attr "mode")
3131 (cond [(eq_attr "alternative" "0,1,2")
3132 (const_string "DF")
3133 (eq_attr "alternative" "3,4")
3134 (const_string "SI")
3135
3136 /* For SSE1, we have many fewer alternatives. */
3137 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3138 (cond [(eq_attr "alternative" "5,6")
3139 (const_string "V4SF")
3140 ]
3141 (const_string "V2SF"))
3142
3143 /* xorps is one byte shorter. */
3144 (eq_attr "alternative" "5")
3145 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3146 (const_int 0))
3147 (const_string "V4SF")
3148 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3149 (const_int 0))
3150 (const_string "TI")
3151 ]
3152 (const_string "V2DF"))
3153
3154 /* For architectures resolving dependencies on
3155 whole SSE registers use APD move to break dependency
3156 chains, otherwise use short move to avoid extra work.
3157
3158 movaps encodes one byte shorter. */
3159 (eq_attr "alternative" "6")
3160 (cond
3161 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3162 (const_int 0))
3163 (const_string "V4SF")
3164 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3165 (const_int 0))
3166 (const_string "V2DF")
3167 ]
3168 (const_string "DF"))
3169 /* For architectures resolving dependencies on register
3170 parts we may avoid extra work to zero out upper part
3171 of register. */
3172 (eq_attr "alternative" "7")
3173 (if_then_else
3174 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3175 (const_int 0))
3176 (const_string "V1DF")
3177 (const_string "DF"))
3178 ]
3179 (const_string "DF")))])
3180
3181 (define_split
3182 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3183 (match_operand:DF 1 "general_operand" ""))]
3184 "reload_completed
3185 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3186 && ! (ANY_FP_REG_P (operands[0]) ||
3187 (GET_CODE (operands[0]) == SUBREG
3188 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3189 && ! (ANY_FP_REG_P (operands[1]) ||
3190 (GET_CODE (operands[1]) == SUBREG
3191 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3192 [(const_int 0)]
3193 "ix86_split_long_move (operands); DONE;")
3194
3195 (define_insn "*movsf_internal"
3196 [(set (match_operand:SF 0 "nonimmediate_operand"
3197 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3198 (match_operand:SF 1 "general_operand"
3199 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3200 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3201 && (!can_create_pseudo_p ()
3202 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3203 || GET_CODE (operands[1]) != CONST_DOUBLE
3204 || (optimize_function_for_size_p (cfun)
3205 && ((!TARGET_SSE_MATH
3206 && standard_80387_constant_p (operands[1]) > 0)
3207 || (TARGET_SSE_MATH
3208 && standard_sse_constant_p (operands[1]))))
3209 || memory_operand (operands[0], SFmode))"
3210 {
3211 switch (which_alternative)
3212 {
3213 case 0:
3214 case 1:
3215 return output_387_reg_move (insn, operands);
3216
3217 case 2:
3218 return standard_80387_constant_opcode (operands[1]);
3219
3220 case 3:
3221 case 4:
3222 return "mov{l}\t{%1, %0|%0, %1}";
3223
3224 case 5:
3225 return standard_sse_constant_opcode (insn, operands[1]);
3226
3227 case 6:
3228 if (get_attr_mode (insn) == MODE_V4SF)
3229 return "%vmovaps\t{%1, %0|%0, %1}";
3230 else
3231 return "%vmovss\t{%1, %d0|%d0, %1}";
3232 case 7:
3233 if (TARGET_AVX && REG_P (operands[1]))
3234 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3235 else
3236 return "%vmovss\t{%1, %0|%0, %1}";
3237 case 8:
3238 return "%vmovss\t{%1, %0|%0, %1}";
3239
3240 case 9: case 10: case 14: case 15:
3241 return "movd\t{%1, %0|%0, %1}";
3242
3243 case 11:
3244 return "movq\t{%1, %0|%0, %1}";
3245
3246 case 12: case 13:
3247 return "%vmovd\t{%1, %0|%0, %1}";
3248
3249 default:
3250 gcc_unreachable ();
3251 }
3252 }
3253 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3254 (set (attr "prefix")
3255 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3256 (const_string "maybe_vex")
3257 (const_string "orig")))
3258 (set (attr "mode")
3259 (cond [(eq_attr "alternative" "3,4,9,10")
3260 (const_string "SI")
3261 (eq_attr "alternative" "5")
3262 (if_then_else
3263 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3264 (const_int 0))
3265 (ne (symbol_ref "TARGET_SSE2")
3266 (const_int 0)))
3267 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3268 (const_int 0)))
3269 (const_string "TI")
3270 (const_string "V4SF"))
3271 /* For architectures resolving dependencies on
3272 whole SSE registers use APS move to break dependency
3273 chains, otherwise use short move to avoid extra work.
3274
3275 Do the same for architectures resolving dependencies on
3276 the parts. While in DF mode it is better to always handle
3277 just register parts, the SF mode is different due to lack
3278 of instructions to load just part of the register. It is
3279 better to maintain the whole registers in single format
3280 to avoid problems on using packed logical operations. */
3281 (eq_attr "alternative" "6")
3282 (if_then_else
3283 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3284 (const_int 0))
3285 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3286 (const_int 0)))
3287 (const_string "V4SF")
3288 (const_string "SF"))
3289 (eq_attr "alternative" "11")
3290 (const_string "DI")]
3291 (const_string "SF")))])
3292
3293 (define_split
3294 [(set (match_operand 0 "register_operand" "")
3295 (match_operand 1 "memory_operand" ""))]
3296 "reload_completed
3297 && MEM_P (operands[1])
3298 && (GET_MODE (operands[0]) == TFmode
3299 || GET_MODE (operands[0]) == XFmode
3300 || GET_MODE (operands[0]) == DFmode
3301 || GET_MODE (operands[0]) == SFmode)
3302 && (operands[2] = find_constant_src (insn))"
3303 [(set (match_dup 0) (match_dup 2))]
3304 {
3305 rtx c = operands[2];
3306 rtx r = operands[0];
3307
3308 if (GET_CODE (r) == SUBREG)
3309 r = SUBREG_REG (r);
3310
3311 if (SSE_REG_P (r))
3312 {
3313 if (!standard_sse_constant_p (c))
3314 FAIL;
3315 }
3316 else if (FP_REG_P (r))
3317 {
3318 if (standard_80387_constant_p (c) < 1)
3319 FAIL;
3320 }
3321 else if (MMX_REG_P (r))
3322 FAIL;
3323 })
3324
3325 (define_split
3326 [(set (match_operand 0 "register_operand" "")
3327 (float_extend (match_operand 1 "memory_operand" "")))]
3328 "reload_completed
3329 && MEM_P (operands[1])
3330 && (GET_MODE (operands[0]) == TFmode
3331 || GET_MODE (operands[0]) == XFmode
3332 || GET_MODE (operands[0]) == DFmode
3333 || GET_MODE (operands[0]) == SFmode)
3334 && (operands[2] = find_constant_src (insn))"
3335 [(set (match_dup 0) (match_dup 2))]
3336 {
3337 rtx c = operands[2];
3338 rtx r = operands[0];
3339
3340 if (GET_CODE (r) == SUBREG)
3341 r = SUBREG_REG (r);
3342
3343 if (SSE_REG_P (r))
3344 {
3345 if (!standard_sse_constant_p (c))
3346 FAIL;
3347 }
3348 else if (FP_REG_P (r))
3349 {
3350 if (standard_80387_constant_p (c) < 1)
3351 FAIL;
3352 }
3353 else if (MMX_REG_P (r))
3354 FAIL;
3355 })
3356
3357 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3358 (define_split
3359 [(set (match_operand:X87MODEF 0 "register_operand" "")
3360 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3361 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3362 && (standard_80387_constant_p (operands[1]) == 8
3363 || standard_80387_constant_p (operands[1]) == 9)"
3364 [(set (match_dup 0)(match_dup 1))
3365 (set (match_dup 0)
3366 (neg:X87MODEF (match_dup 0)))]
3367 {
3368 REAL_VALUE_TYPE r;
3369
3370 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3371 if (real_isnegzero (&r))
3372 operands[1] = CONST0_RTX (<MODE>mode);
3373 else
3374 operands[1] = CONST1_RTX (<MODE>mode);
3375 })
3376
3377 (define_insn "swapxf"
3378 [(set (match_operand:XF 0 "register_operand" "+f")
3379 (match_operand:XF 1 "register_operand" "+f"))
3380 (set (match_dup 1)
3381 (match_dup 0))]
3382 "TARGET_80387"
3383 {
3384 if (STACK_TOP_P (operands[0]))
3385 return "fxch\t%1";
3386 else
3387 return "fxch\t%0";
3388 }
3389 [(set_attr "type" "fxch")
3390 (set_attr "mode" "XF")])
3391
3392 (define_insn "*swap<mode>"
3393 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3394 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3395 (set (match_dup 1)
3396 (match_dup 0))]
3397 "TARGET_80387 || reload_completed"
3398 {
3399 if (STACK_TOP_P (operands[0]))
3400 return "fxch\t%1";
3401 else
3402 return "fxch\t%0";
3403 }
3404 [(set_attr "type" "fxch")
3405 (set_attr "mode" "<MODE>")])
3406 \f
3407 ;; Zero extension instructions
3408
3409 (define_expand "zero_extendsidi2"
3410 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3411 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3412 ""
3413 {
3414 if (!TARGET_64BIT)
3415 {
3416 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3417 DONE;
3418 }
3419 })
3420
3421 (define_insn "*zero_extendsidi2_rex64"
3422 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3423 (zero_extend:DI
3424 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3425 "TARGET_64BIT"
3426 "@
3427 mov\t{%k1, %k0|%k0, %k1}
3428 #
3429 movd\t{%1, %0|%0, %1}
3430 movd\t{%1, %0|%0, %1}
3431 %vmovd\t{%1, %0|%0, %1}
3432 %vmovd\t{%1, %0|%0, %1}"
3433 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3434 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3435 (set_attr "prefix_0f" "0,*,*,*,*,*")
3436 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3437
3438 (define_split
3439 [(set (match_operand:DI 0 "memory_operand" "")
3440 (zero_extend:DI (match_dup 0)))]
3441 "TARGET_64BIT"
3442 [(set (match_dup 4) (const_int 0))]
3443 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3444
3445 ;; %%% Kill me once multi-word ops are sane.
3446 (define_insn "zero_extendsidi2_1"
3447 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3448 (zero_extend:DI
3449 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3450 (clobber (reg:CC FLAGS_REG))]
3451 "!TARGET_64BIT"
3452 "@
3453 #
3454 #
3455 #
3456 movd\t{%1, %0|%0, %1}
3457 movd\t{%1, %0|%0, %1}
3458 %vmovd\t{%1, %0|%0, %1}
3459 %vmovd\t{%1, %0|%0, %1}"
3460 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3461 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3462 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3463
3464 (define_split
3465 [(set (match_operand:DI 0 "register_operand" "")
3466 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3467 (clobber (reg:CC FLAGS_REG))]
3468 "!TARGET_64BIT && reload_completed
3469 && true_regnum (operands[0]) == true_regnum (operands[1])"
3470 [(set (match_dup 4) (const_int 0))]
3471 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3472
3473 (define_split
3474 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3475 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3476 (clobber (reg:CC FLAGS_REG))]
3477 "!TARGET_64BIT && reload_completed
3478 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3479 [(set (match_dup 3) (match_dup 1))
3480 (set (match_dup 4) (const_int 0))]
3481 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3482
3483 (define_insn "zero_extend<mode>di2"
3484 [(set (match_operand:DI 0 "register_operand" "=r")
3485 (zero_extend:DI
3486 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3487 "TARGET_64BIT"
3488 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3489 [(set_attr "type" "imovx")
3490 (set_attr "mode" "SI")])
3491
3492 (define_expand "zero_extendhisi2"
3493 [(set (match_operand:SI 0 "register_operand" "")
3494 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3495 ""
3496 {
3497 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3498 {
3499 operands[1] = force_reg (HImode, operands[1]);
3500 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3501 DONE;
3502 }
3503 })
3504
3505 (define_insn_and_split "zero_extendhisi2_and"
3506 [(set (match_operand:SI 0 "register_operand" "=r")
3507 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3508 (clobber (reg:CC FLAGS_REG))]
3509 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3510 "#"
3511 "&& reload_completed"
3512 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3513 (clobber (reg:CC FLAGS_REG))])]
3514 ""
3515 [(set_attr "type" "alu1")
3516 (set_attr "mode" "SI")])
3517
3518 (define_insn "*zero_extendhisi2_movzwl"
3519 [(set (match_operand:SI 0 "register_operand" "=r")
3520 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3521 "!TARGET_ZERO_EXTEND_WITH_AND
3522 || optimize_function_for_size_p (cfun)"
3523 "movz{wl|x}\t{%1, %0|%0, %1}"
3524 [(set_attr "type" "imovx")
3525 (set_attr "mode" "SI")])
3526
3527 (define_expand "zero_extendqi<mode>2"
3528 [(parallel
3529 [(set (match_operand:SWI24 0 "register_operand" "")
3530 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3531 (clobber (reg:CC FLAGS_REG))])])
3532
3533 (define_insn "*zero_extendqi<mode>2_and"
3534 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3535 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3536 (clobber (reg:CC FLAGS_REG))]
3537 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3538 "#"
3539 [(set_attr "type" "alu1")
3540 (set_attr "mode" "<MODE>")])
3541
3542 ;; When source and destination does not overlap, clear destination
3543 ;; first and then do the movb
3544 (define_split
3545 [(set (match_operand:SWI24 0 "register_operand" "")
3546 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3547 (clobber (reg:CC FLAGS_REG))]
3548 "reload_completed
3549 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3550 && ANY_QI_REG_P (operands[0])
3551 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3552 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3553 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3554 {
3555 operands[2] = gen_lowpart (QImode, operands[0]);
3556 ix86_expand_clear (operands[0]);
3557 })
3558
3559 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3560 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3561 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3562 (clobber (reg:CC FLAGS_REG))]
3563 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3564 "#"
3565 [(set_attr "type" "imovx,alu1")
3566 (set_attr "mode" "<MODE>")])
3567
3568 ;; For the movzbl case strip only the clobber
3569 (define_split
3570 [(set (match_operand:SWI24 0 "register_operand" "")
3571 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3572 (clobber (reg:CC FLAGS_REG))]
3573 "reload_completed
3574 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3575 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3576 [(set (match_dup 0)
3577 (zero_extend:SWI24 (match_dup 1)))])
3578
3579 ; zero extend to SImode to avoid partial register stalls
3580 (define_insn "*zero_extendqi<mode>2_movzbl"
3581 [(set (match_operand:SWI24 0 "register_operand" "=r")
3582 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3583 "reload_completed
3584 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3585 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3586 [(set_attr "type" "imovx")
3587 (set_attr "mode" "SI")])
3588
3589 ;; Rest is handled by single and.
3590 (define_split
3591 [(set (match_operand:SWI24 0 "register_operand" "")
3592 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3593 (clobber (reg:CC FLAGS_REG))]
3594 "reload_completed
3595 && true_regnum (operands[0]) == true_regnum (operands[1])"
3596 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3597 (clobber (reg:CC FLAGS_REG))])])
3598 \f
3599 ;; Sign extension instructions
3600
3601 (define_expand "extendsidi2"
3602 [(set (match_operand:DI 0 "register_operand" "")
3603 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3604 ""
3605 {
3606 if (!TARGET_64BIT)
3607 {
3608 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3609 DONE;
3610 }
3611 })
3612
3613 (define_insn "*extendsidi2_rex64"
3614 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3615 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3616 "TARGET_64BIT"
3617 "@
3618 {cltq|cdqe}
3619 movs{lq|x}\t{%1, %0|%0, %1}"
3620 [(set_attr "type" "imovx")
3621 (set_attr "mode" "DI")
3622 (set_attr "prefix_0f" "0")
3623 (set_attr "modrm" "0,1")])
3624
3625 (define_insn "extendsidi2_1"
3626 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3627 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3628 (clobber (reg:CC FLAGS_REG))
3629 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3630 "!TARGET_64BIT"
3631 "#")
3632
3633 ;; Extend to memory case when source register does die.
3634 (define_split
3635 [(set (match_operand:DI 0 "memory_operand" "")
3636 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3637 (clobber (reg:CC FLAGS_REG))
3638 (clobber (match_operand:SI 2 "register_operand" ""))]
3639 "(reload_completed
3640 && dead_or_set_p (insn, operands[1])
3641 && !reg_mentioned_p (operands[1], operands[0]))"
3642 [(set (match_dup 3) (match_dup 1))
3643 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3644 (clobber (reg:CC FLAGS_REG))])
3645 (set (match_dup 4) (match_dup 1))]
3646 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3647
3648 ;; Extend to memory case when source register does not die.
3649 (define_split
3650 [(set (match_operand:DI 0 "memory_operand" "")
3651 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3652 (clobber (reg:CC FLAGS_REG))
3653 (clobber (match_operand:SI 2 "register_operand" ""))]
3654 "reload_completed"
3655 [(const_int 0)]
3656 {
3657 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3658
3659 emit_move_insn (operands[3], operands[1]);
3660
3661 /* Generate a cltd if possible and doing so it profitable. */
3662 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3663 && true_regnum (operands[1]) == AX_REG
3664 && true_regnum (operands[2]) == DX_REG)
3665 {
3666 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3667 }
3668 else
3669 {
3670 emit_move_insn (operands[2], operands[1]);
3671 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3672 }
3673 emit_move_insn (operands[4], operands[2]);
3674 DONE;
3675 })
3676
3677 ;; Extend to register case. Optimize case where source and destination
3678 ;; registers match and cases where we can use cltd.
3679 (define_split
3680 [(set (match_operand:DI 0 "register_operand" "")
3681 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3682 (clobber (reg:CC FLAGS_REG))
3683 (clobber (match_scratch:SI 2 ""))]
3684 "reload_completed"
3685 [(const_int 0)]
3686 {
3687 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3688
3689 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3690 emit_move_insn (operands[3], operands[1]);
3691
3692 /* Generate a cltd if possible and doing so it profitable. */
3693 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3694 && true_regnum (operands[3]) == AX_REG
3695 && true_regnum (operands[4]) == DX_REG)
3696 {
3697 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3698 DONE;
3699 }
3700
3701 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3702 emit_move_insn (operands[4], operands[1]);
3703
3704 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3705 DONE;
3706 })
3707
3708 (define_insn "extend<mode>di2"
3709 [(set (match_operand:DI 0 "register_operand" "=r")
3710 (sign_extend:DI
3711 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3712 "TARGET_64BIT"
3713 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "DI")])
3716
3717 (define_insn "extendhisi2"
3718 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3719 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3720 ""
3721 {
3722 switch (get_attr_prefix_0f (insn))
3723 {
3724 case 0:
3725 return "{cwtl|cwde}";
3726 default:
3727 return "movs{wl|x}\t{%1, %0|%0, %1}";
3728 }
3729 }
3730 [(set_attr "type" "imovx")
3731 (set_attr "mode" "SI")
3732 (set (attr "prefix_0f")
3733 ;; movsx is short decodable while cwtl is vector decoded.
3734 (if_then_else (and (eq_attr "cpu" "!k6")
3735 (eq_attr "alternative" "0"))
3736 (const_string "0")
3737 (const_string "1")))
3738 (set (attr "modrm")
3739 (if_then_else (eq_attr "prefix_0f" "0")
3740 (const_string "0")
3741 (const_string "1")))])
3742
3743 (define_insn "*extendhisi2_zext"
3744 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3745 (zero_extend:DI
3746 (sign_extend:SI
3747 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3748 "TARGET_64BIT"
3749 {
3750 switch (get_attr_prefix_0f (insn))
3751 {
3752 case 0:
3753 return "{cwtl|cwde}";
3754 default:
3755 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3756 }
3757 }
3758 [(set_attr "type" "imovx")
3759 (set_attr "mode" "SI")
3760 (set (attr "prefix_0f")
3761 ;; movsx is short decodable while cwtl is vector decoded.
3762 (if_then_else (and (eq_attr "cpu" "!k6")
3763 (eq_attr "alternative" "0"))
3764 (const_string "0")
3765 (const_string "1")))
3766 (set (attr "modrm")
3767 (if_then_else (eq_attr "prefix_0f" "0")
3768 (const_string "0")
3769 (const_string "1")))])
3770
3771 (define_insn "extendqisi2"
3772 [(set (match_operand:SI 0 "register_operand" "=r")
3773 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3774 ""
3775 "movs{bl|x}\t{%1, %0|%0, %1}"
3776 [(set_attr "type" "imovx")
3777 (set_attr "mode" "SI")])
3778
3779 (define_insn "*extendqisi2_zext"
3780 [(set (match_operand:DI 0 "register_operand" "=r")
3781 (zero_extend:DI
3782 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3783 "TARGET_64BIT"
3784 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3785 [(set_attr "type" "imovx")
3786 (set_attr "mode" "SI")])
3787
3788 (define_insn "extendqihi2"
3789 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3790 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3791 ""
3792 {
3793 switch (get_attr_prefix_0f (insn))
3794 {
3795 case 0:
3796 return "{cbtw|cbw}";
3797 default:
3798 return "movs{bw|x}\t{%1, %0|%0, %1}";
3799 }
3800 }
3801 [(set_attr "type" "imovx")
3802 (set_attr "mode" "HI")
3803 (set (attr "prefix_0f")
3804 ;; movsx is short decodable while cwtl is vector decoded.
3805 (if_then_else (and (eq_attr "cpu" "!k6")
3806 (eq_attr "alternative" "0"))
3807 (const_string "0")
3808 (const_string "1")))
3809 (set (attr "modrm")
3810 (if_then_else (eq_attr "prefix_0f" "0")
3811 (const_string "0")
3812 (const_string "1")))])
3813 \f
3814 ;; Conversions between float and double.
3815
3816 ;; These are all no-ops in the model used for the 80387.
3817 ;; So just emit moves.
3818
3819 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3820 (define_split
3821 [(set (match_operand:DF 0 "push_operand" "")
3822 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3823 "reload_completed"
3824 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3825 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3826
3827 (define_split
3828 [(set (match_operand:XF 0 "push_operand" "")
3829 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3830 "reload_completed"
3831 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3832 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3833 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3834
3835 (define_expand "extendsfdf2"
3836 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3837 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3838 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3839 {
3840 /* ??? Needed for compress_float_constant since all fp constants
3841 are TARGET_LEGITIMATE_CONSTANT_P. */
3842 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3843 {
3844 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3845 && standard_80387_constant_p (operands[1]) > 0)
3846 {
3847 operands[1] = simplify_const_unary_operation
3848 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3849 emit_move_insn_1 (operands[0], operands[1]);
3850 DONE;
3851 }
3852 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3853 }
3854 })
3855
3856 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3857 cvtss2sd:
3858 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3859 cvtps2pd xmm2,xmm1
3860 We do the conversion post reload to avoid producing of 128bit spills
3861 that might lead to ICE on 32bit target. The sequence unlikely combine
3862 anyway. */
3863 (define_split
3864 [(set (match_operand:DF 0 "register_operand" "")
3865 (float_extend:DF
3866 (match_operand:SF 1 "nonimmediate_operand" "")))]
3867 "TARGET_USE_VECTOR_FP_CONVERTS
3868 && optimize_insn_for_speed_p ()
3869 && reload_completed && SSE_REG_P (operands[0])"
3870 [(set (match_dup 2)
3871 (float_extend:V2DF
3872 (vec_select:V2SF
3873 (match_dup 3)
3874 (parallel [(const_int 0) (const_int 1)]))))]
3875 {
3876 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3877 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3878 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3879 Try to avoid move when unpacking can be done in source. */
3880 if (REG_P (operands[1]))
3881 {
3882 /* If it is unsafe to overwrite upper half of source, we need
3883 to move to destination and unpack there. */
3884 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3885 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3886 && true_regnum (operands[0]) != true_regnum (operands[1]))
3887 {
3888 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3889 emit_move_insn (tmp, operands[1]);
3890 }
3891 else
3892 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3893 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3894 operands[3]));
3895 }
3896 else
3897 emit_insn (gen_vec_setv4sf_0 (operands[3],
3898 CONST0_RTX (V4SFmode), operands[1]));
3899 })
3900
3901 (define_insn "*extendsfdf2_mixed"
3902 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3903 (float_extend:DF
3904 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3905 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3906 {
3907 switch (which_alternative)
3908 {
3909 case 0:
3910 case 1:
3911 return output_387_reg_move (insn, operands);
3912
3913 case 2:
3914 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3915
3916 default:
3917 gcc_unreachable ();
3918 }
3919 }
3920 [(set_attr "type" "fmov,fmov,ssecvt")
3921 (set_attr "prefix" "orig,orig,maybe_vex")
3922 (set_attr "mode" "SF,XF,DF")])
3923
3924 (define_insn "*extendsfdf2_sse"
3925 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3926 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3927 "TARGET_SSE2 && TARGET_SSE_MATH"
3928 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3929 [(set_attr "type" "ssecvt")
3930 (set_attr "prefix" "maybe_vex")
3931 (set_attr "mode" "DF")])
3932
3933 (define_insn "*extendsfdf2_i387"
3934 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3935 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3936 "TARGET_80387"
3937 "* return output_387_reg_move (insn, operands);"
3938 [(set_attr "type" "fmov")
3939 (set_attr "mode" "SF,XF")])
3940
3941 (define_expand "extend<mode>xf2"
3942 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3943 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3944 "TARGET_80387"
3945 {
3946 /* ??? Needed for compress_float_constant since all fp constants
3947 are TARGET_LEGITIMATE_CONSTANT_P. */
3948 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3949 {
3950 if (standard_80387_constant_p (operands[1]) > 0)
3951 {
3952 operands[1] = simplify_const_unary_operation
3953 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3954 emit_move_insn_1 (operands[0], operands[1]);
3955 DONE;
3956 }
3957 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3958 }
3959 })
3960
3961 (define_insn "*extend<mode>xf2_i387"
3962 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3963 (float_extend:XF
3964 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3965 "TARGET_80387"
3966 "* return output_387_reg_move (insn, operands);"
3967 [(set_attr "type" "fmov")
3968 (set_attr "mode" "<MODE>,XF")])
3969
3970 ;; %%% This seems bad bad news.
3971 ;; This cannot output into an f-reg because there is no way to be sure
3972 ;; of truncating in that case. Otherwise this is just like a simple move
3973 ;; insn. So we pretend we can output to a reg in order to get better
3974 ;; register preferencing, but we really use a stack slot.
3975
3976 ;; Conversion from DFmode to SFmode.
3977
3978 (define_expand "truncdfsf2"
3979 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3980 (float_truncate:SF
3981 (match_operand:DF 1 "nonimmediate_operand" "")))]
3982 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3983 {
3984 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3985 ;
3986 else if (flag_unsafe_math_optimizations)
3987 ;
3988 else
3989 {
3990 enum ix86_stack_slot slot = (virtuals_instantiated
3991 ? SLOT_TEMP
3992 : SLOT_VIRTUAL);
3993 rtx temp = assign_386_stack_local (SFmode, slot);
3994 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3995 DONE;
3996 }
3997 })
3998
3999 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4000 cvtsd2ss:
4001 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4002 cvtpd2ps xmm2,xmm1
4003 We do the conversion post reload to avoid producing of 128bit spills
4004 that might lead to ICE on 32bit target. The sequence unlikely combine
4005 anyway. */
4006 (define_split
4007 [(set (match_operand:SF 0 "register_operand" "")
4008 (float_truncate:SF
4009 (match_operand:DF 1 "nonimmediate_operand" "")))]
4010 "TARGET_USE_VECTOR_FP_CONVERTS
4011 && optimize_insn_for_speed_p ()
4012 && reload_completed && SSE_REG_P (operands[0])"
4013 [(set (match_dup 2)
4014 (vec_concat:V4SF
4015 (float_truncate:V2SF
4016 (match_dup 4))
4017 (match_dup 3)))]
4018 {
4019 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4020 operands[3] = CONST0_RTX (V2SFmode);
4021 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4022 /* Use movsd for loading from memory, unpcklpd for registers.
4023 Try to avoid move when unpacking can be done in source, or SSE3
4024 movddup is available. */
4025 if (REG_P (operands[1]))
4026 {
4027 if (!TARGET_SSE3
4028 && true_regnum (operands[0]) != true_regnum (operands[1])
4029 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4030 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4031 {
4032 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4033 emit_move_insn (tmp, operands[1]);
4034 operands[1] = tmp;
4035 }
4036 else if (!TARGET_SSE3)
4037 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4038 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4039 }
4040 else
4041 emit_insn (gen_sse2_loadlpd (operands[4],
4042 CONST0_RTX (V2DFmode), operands[1]));
4043 })
4044
4045 (define_expand "truncdfsf2_with_temp"
4046 [(parallel [(set (match_operand:SF 0 "" "")
4047 (float_truncate:SF (match_operand:DF 1 "" "")))
4048 (clobber (match_operand:SF 2 "" ""))])])
4049
4050 (define_insn "*truncdfsf_fast_mixed"
4051 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4052 (float_truncate:SF
4053 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4054 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4055 {
4056 switch (which_alternative)
4057 {
4058 case 0:
4059 return output_387_reg_move (insn, operands);
4060 case 1:
4061 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4062 default:
4063 gcc_unreachable ();
4064 }
4065 }
4066 [(set_attr "type" "fmov,ssecvt")
4067 (set_attr "prefix" "orig,maybe_vex")
4068 (set_attr "mode" "SF")])
4069
4070 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4071 ;; because nothing we do here is unsafe.
4072 (define_insn "*truncdfsf_fast_sse"
4073 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4074 (float_truncate:SF
4075 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4076 "TARGET_SSE2 && TARGET_SSE_MATH"
4077 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4078 [(set_attr "type" "ssecvt")
4079 (set_attr "prefix" "maybe_vex")
4080 (set_attr "mode" "SF")])
4081
4082 (define_insn "*truncdfsf_fast_i387"
4083 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4084 (float_truncate:SF
4085 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4086 "TARGET_80387 && flag_unsafe_math_optimizations"
4087 "* return output_387_reg_move (insn, operands);"
4088 [(set_attr "type" "fmov")
4089 (set_attr "mode" "SF")])
4090
4091 (define_insn "*truncdfsf_mixed"
4092 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4093 (float_truncate:SF
4094 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4095 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4096 "TARGET_MIX_SSE_I387"
4097 {
4098 switch (which_alternative)
4099 {
4100 case 0:
4101 return output_387_reg_move (insn, operands);
4102 case 1:
4103 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4104
4105 default:
4106 return "#";
4107 }
4108 }
4109 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4110 (set_attr "unit" "*,*,i387,i387,i387")
4111 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4112 (set_attr "mode" "SF")])
4113
4114 (define_insn "*truncdfsf_i387"
4115 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4116 (float_truncate:SF
4117 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4118 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4119 "TARGET_80387"
4120 {
4121 switch (which_alternative)
4122 {
4123 case 0:
4124 return output_387_reg_move (insn, operands);
4125
4126 default:
4127 return "#";
4128 }
4129 }
4130 [(set_attr "type" "fmov,multi,multi,multi")
4131 (set_attr "unit" "*,i387,i387,i387")
4132 (set_attr "mode" "SF")])
4133
4134 (define_insn "*truncdfsf2_i387_1"
4135 [(set (match_operand:SF 0 "memory_operand" "=m")
4136 (float_truncate:SF
4137 (match_operand:DF 1 "register_operand" "f")))]
4138 "TARGET_80387
4139 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4140 && !TARGET_MIX_SSE_I387"
4141 "* return output_387_reg_move (insn, operands);"
4142 [(set_attr "type" "fmov")
4143 (set_attr "mode" "SF")])
4144
4145 (define_split
4146 [(set (match_operand:SF 0 "register_operand" "")
4147 (float_truncate:SF
4148 (match_operand:DF 1 "fp_register_operand" "")))
4149 (clobber (match_operand 2 "" ""))]
4150 "reload_completed"
4151 [(set (match_dup 2) (match_dup 1))
4152 (set (match_dup 0) (match_dup 2))]
4153 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4154
4155 ;; Conversion from XFmode to {SF,DF}mode
4156
4157 (define_expand "truncxf<mode>2"
4158 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4159 (float_truncate:MODEF
4160 (match_operand:XF 1 "register_operand" "")))
4161 (clobber (match_dup 2))])]
4162 "TARGET_80387"
4163 {
4164 if (flag_unsafe_math_optimizations)
4165 {
4166 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4167 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4168 if (reg != operands[0])
4169 emit_move_insn (operands[0], reg);
4170 DONE;
4171 }
4172 else
4173 {
4174 enum ix86_stack_slot slot = (virtuals_instantiated
4175 ? SLOT_TEMP
4176 : SLOT_VIRTUAL);
4177 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4178 }
4179 })
4180
4181 (define_insn "*truncxfsf2_mixed"
4182 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4183 (float_truncate:SF
4184 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4185 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4186 "TARGET_80387"
4187 {
4188 gcc_assert (!which_alternative);
4189 return output_387_reg_move (insn, operands);
4190 }
4191 [(set_attr "type" "fmov,multi,multi,multi")
4192 (set_attr "unit" "*,i387,i387,i387")
4193 (set_attr "mode" "SF")])
4194
4195 (define_insn "*truncxfdf2_mixed"
4196 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4197 (float_truncate:DF
4198 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4199 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4200 "TARGET_80387"
4201 {
4202 gcc_assert (!which_alternative);
4203 return output_387_reg_move (insn, operands);
4204 }
4205 [(set_attr "type" "fmov,multi,multi,multi")
4206 (set_attr "unit" "*,i387,i387,i387")
4207 (set_attr "mode" "DF")])
4208
4209 (define_insn "truncxf<mode>2_i387_noop"
4210 [(set (match_operand:MODEF 0 "register_operand" "=f")
4211 (float_truncate:MODEF
4212 (match_operand:XF 1 "register_operand" "f")))]
4213 "TARGET_80387 && flag_unsafe_math_optimizations"
4214 "* return output_387_reg_move (insn, operands);"
4215 [(set_attr "type" "fmov")
4216 (set_attr "mode" "<MODE>")])
4217
4218 (define_insn "*truncxf<mode>2_i387"
4219 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4220 (float_truncate:MODEF
4221 (match_operand:XF 1 "register_operand" "f")))]
4222 "TARGET_80387"
4223 "* return output_387_reg_move (insn, operands);"
4224 [(set_attr "type" "fmov")
4225 (set_attr "mode" "<MODE>")])
4226
4227 (define_split
4228 [(set (match_operand:MODEF 0 "register_operand" "")
4229 (float_truncate:MODEF
4230 (match_operand:XF 1 "register_operand" "")))
4231 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4232 "TARGET_80387 && reload_completed"
4233 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4234 (set (match_dup 0) (match_dup 2))])
4235
4236 (define_split
4237 [(set (match_operand:MODEF 0 "memory_operand" "")
4238 (float_truncate:MODEF
4239 (match_operand:XF 1 "register_operand" "")))
4240 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4241 "TARGET_80387"
4242 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4243 \f
4244 ;; Signed conversion to DImode.
4245
4246 (define_expand "fix_truncxfdi2"
4247 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248 (fix:DI (match_operand:XF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4250 "TARGET_80387"
4251 {
4252 if (TARGET_FISTTP)
4253 {
4254 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4255 DONE;
4256 }
4257 })
4258
4259 (define_expand "fix_trunc<mode>di2"
4260 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4262 (clobber (reg:CC FLAGS_REG))])]
4263 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4264 {
4265 if (TARGET_FISTTP
4266 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4267 {
4268 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4269 DONE;
4270 }
4271 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4272 {
4273 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275 if (out != operands[0])
4276 emit_move_insn (operands[0], out);
4277 DONE;
4278 }
4279 })
4280
4281 ;; Signed conversion to SImode.
4282
4283 (define_expand "fix_truncxfsi2"
4284 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285 (fix:SI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4287 "TARGET_80387"
4288 {
4289 if (TARGET_FISTTP)
4290 {
4291 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4292 DONE;
4293 }
4294 })
4295
4296 (define_expand "fix_trunc<mode>si2"
4297 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4301 {
4302 if (TARGET_FISTTP
4303 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304 {
4305 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4306 DONE;
4307 }
4308 if (SSE_FLOAT_MODE_P (<MODE>mode))
4309 {
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4314 DONE;
4315 }
4316 })
4317
4318 ;; Signed conversion to HImode.
4319
4320 (define_expand "fix_trunc<mode>hi2"
4321 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4324 "TARGET_80387
4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4326 {
4327 if (TARGET_FISTTP)
4328 {
4329 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4330 DONE;
4331 }
4332 })
4333
4334 ;; Unsigned conversion to SImode.
4335
4336 (define_expand "fixuns_trunc<mode>si2"
4337 [(parallel
4338 [(set (match_operand:SI 0 "register_operand" "")
4339 (unsigned_fix:SI
4340 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4341 (use (match_dup 2))
4342 (clobber (match_scratch:<ssevecmode> 3 ""))
4343 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4344 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4345 {
4346 enum machine_mode mode = <MODE>mode;
4347 enum machine_mode vecmode = <ssevecmode>mode;
4348 REAL_VALUE_TYPE TWO31r;
4349 rtx two31;
4350
4351 if (optimize_insn_for_size_p ())
4352 FAIL;
4353
4354 real_ldexp (&TWO31r, &dconst1, 31);
4355 two31 = const_double_from_real_value (TWO31r, mode);
4356 two31 = ix86_build_const_vector (vecmode, true, two31);
4357 operands[2] = force_reg (vecmode, two31);
4358 })
4359
4360 (define_insn_and_split "*fixuns_trunc<mode>_1"
4361 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4362 (unsigned_fix:SI
4363 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4364 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4365 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4366 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4367 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4368 && optimize_function_for_speed_p (cfun)"
4369 "#"
4370 "&& reload_completed"
4371 [(const_int 0)]
4372 {
4373 ix86_split_convert_uns_si_sse (operands);
4374 DONE;
4375 })
4376
4377 ;; Unsigned conversion to HImode.
4378 ;; Without these patterns, we'll try the unsigned SI conversion which
4379 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4380
4381 (define_expand "fixuns_trunc<mode>hi2"
4382 [(set (match_dup 2)
4383 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4384 (set (match_operand:HI 0 "nonimmediate_operand" "")
4385 (subreg:HI (match_dup 2) 0))]
4386 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4387 "operands[2] = gen_reg_rtx (SImode);")
4388
4389 ;; When SSE is available, it is always faster to use it!
4390 (define_insn "fix_trunc<mode>di_sse"
4391 [(set (match_operand:DI 0 "register_operand" "=r,r")
4392 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4393 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4394 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4395 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4396 [(set_attr "type" "sseicvt")
4397 (set_attr "prefix" "maybe_vex")
4398 (set_attr "prefix_rex" "1")
4399 (set_attr "mode" "<MODE>")
4400 (set_attr "athlon_decode" "double,vector")
4401 (set_attr "amdfam10_decode" "double,double")
4402 (set_attr "bdver1_decode" "double,double")])
4403
4404 (define_insn "fix_trunc<mode>si_sse"
4405 [(set (match_operand:SI 0 "register_operand" "=r,r")
4406 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4407 "SSE_FLOAT_MODE_P (<MODE>mode)
4408 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4409 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4410 [(set_attr "type" "sseicvt")
4411 (set_attr "prefix" "maybe_vex")
4412 (set_attr "mode" "<MODE>")
4413 (set_attr "athlon_decode" "double,vector")
4414 (set_attr "amdfam10_decode" "double,double")
4415 (set_attr "bdver1_decode" "double,double")])
4416
4417 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4418 (define_peephole2
4419 [(set (match_operand:MODEF 0 "register_operand" "")
4420 (match_operand:MODEF 1 "memory_operand" ""))
4421 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422 (fix:SSEMODEI24 (match_dup 0)))]
4423 "TARGET_SHORTEN_X87_SSE
4424 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4425 && peep2_reg_dead_p (2, operands[0])"
4426 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4427
4428 ;; Avoid vector decoded forms of the instruction.
4429 (define_peephole2
4430 [(match_scratch:DF 2 "Y2")
4431 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4434 [(set (match_dup 2) (match_dup 1))
4435 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4436
4437 (define_peephole2
4438 [(match_scratch:SF 2 "x")
4439 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4440 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4441 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4442 [(set (match_dup 2) (match_dup 1))
4443 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4444
4445 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4446 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4447 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4448 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4449 && TARGET_FISTTP
4450 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4451 && (TARGET_64BIT || <MODE>mode != DImode))
4452 && TARGET_SSE_MATH)
4453 && can_create_pseudo_p ()"
4454 "#"
4455 "&& 1"
4456 [(const_int 0)]
4457 {
4458 if (memory_operand (operands[0], VOIDmode))
4459 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4460 else
4461 {
4462 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4463 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4464 operands[1],
4465 operands[2]));
4466 }
4467 DONE;
4468 }
4469 [(set_attr "type" "fisttp")
4470 (set_attr "mode" "<MODE>")])
4471
4472 (define_insn "fix_trunc<mode>_i387_fisttp"
4473 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4474 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4475 (clobber (match_scratch:XF 2 "=&1f"))]
4476 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4477 && TARGET_FISTTP
4478 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4479 && (TARGET_64BIT || <MODE>mode != DImode))
4480 && TARGET_SSE_MATH)"
4481 "* return output_fix_trunc (insn, operands, true);"
4482 [(set_attr "type" "fisttp")
4483 (set_attr "mode" "<MODE>")])
4484
4485 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4486 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4487 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4488 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4489 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4490 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4491 && TARGET_FISTTP
4492 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && (TARGET_64BIT || <MODE>mode != DImode))
4494 && TARGET_SSE_MATH)"
4495 "#"
4496 [(set_attr "type" "fisttp")
4497 (set_attr "mode" "<MODE>")])
4498
4499 (define_split
4500 [(set (match_operand:X87MODEI 0 "register_operand" "")
4501 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4502 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4503 (clobber (match_scratch 3 ""))]
4504 "reload_completed"
4505 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4506 (clobber (match_dup 3))])
4507 (set (match_dup 0) (match_dup 2))])
4508
4509 (define_split
4510 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4511 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4512 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4513 (clobber (match_scratch 3 ""))]
4514 "reload_completed"
4515 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4516 (clobber (match_dup 3))])])
4517
4518 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4519 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4520 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4521 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4522 ;; function in i386.c.
4523 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4524 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4525 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4526 (clobber (reg:CC FLAGS_REG))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528 && !TARGET_FISTTP
4529 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && (TARGET_64BIT || <MODE>mode != DImode))
4531 && can_create_pseudo_p ()"
4532 "#"
4533 "&& 1"
4534 [(const_int 0)]
4535 {
4536 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4537
4538 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4539 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4540 if (memory_operand (operands[0], VOIDmode))
4541 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4542 operands[2], operands[3]));
4543 else
4544 {
4545 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4546 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4547 operands[2], operands[3],
4548 operands[4]));
4549 }
4550 DONE;
4551 }
4552 [(set_attr "type" "fistp")
4553 (set_attr "i387_cw" "trunc")
4554 (set_attr "mode" "<MODE>")])
4555
4556 (define_insn "fix_truncdi_i387"
4557 [(set (match_operand:DI 0 "memory_operand" "=m")
4558 (fix:DI (match_operand 1 "register_operand" "f")))
4559 (use (match_operand:HI 2 "memory_operand" "m"))
4560 (use (match_operand:HI 3 "memory_operand" "m"))
4561 (clobber (match_scratch:XF 4 "=&1f"))]
4562 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4563 && !TARGET_FISTTP
4564 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4565 "* return output_fix_trunc (insn, operands, false);"
4566 [(set_attr "type" "fistp")
4567 (set_attr "i387_cw" "trunc")
4568 (set_attr "mode" "DI")])
4569
4570 (define_insn "fix_truncdi_i387_with_temp"
4571 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4572 (fix:DI (match_operand 1 "register_operand" "f,f")))
4573 (use (match_operand:HI 2 "memory_operand" "m,m"))
4574 (use (match_operand:HI 3 "memory_operand" "m,m"))
4575 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4576 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4577 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4578 && !TARGET_FISTTP
4579 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4580 "#"
4581 [(set_attr "type" "fistp")
4582 (set_attr "i387_cw" "trunc")
4583 (set_attr "mode" "DI")])
4584
4585 (define_split
4586 [(set (match_operand:DI 0 "register_operand" "")
4587 (fix:DI (match_operand 1 "register_operand" "")))
4588 (use (match_operand:HI 2 "memory_operand" ""))
4589 (use (match_operand:HI 3 "memory_operand" ""))
4590 (clobber (match_operand:DI 4 "memory_operand" ""))
4591 (clobber (match_scratch 5 ""))]
4592 "reload_completed"
4593 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4594 (use (match_dup 2))
4595 (use (match_dup 3))
4596 (clobber (match_dup 5))])
4597 (set (match_dup 0) (match_dup 4))])
4598
4599 (define_split
4600 [(set (match_operand:DI 0 "memory_operand" "")
4601 (fix:DI (match_operand 1 "register_operand" "")))
4602 (use (match_operand:HI 2 "memory_operand" ""))
4603 (use (match_operand:HI 3 "memory_operand" ""))
4604 (clobber (match_operand:DI 4 "memory_operand" ""))
4605 (clobber (match_scratch 5 ""))]
4606 "reload_completed"
4607 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4608 (use (match_dup 2))
4609 (use (match_dup 3))
4610 (clobber (match_dup 5))])])
4611
4612 (define_insn "fix_trunc<mode>_i387"
4613 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4614 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4615 (use (match_operand:HI 2 "memory_operand" "m"))
4616 (use (match_operand:HI 3 "memory_operand" "m"))]
4617 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4618 && !TARGET_FISTTP
4619 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4620 "* return output_fix_trunc (insn, operands, false);"
4621 [(set_attr "type" "fistp")
4622 (set_attr "i387_cw" "trunc")
4623 (set_attr "mode" "<MODE>")])
4624
4625 (define_insn "fix_trunc<mode>_i387_with_temp"
4626 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4627 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4628 (use (match_operand:HI 2 "memory_operand" "m,m"))
4629 (use (match_operand:HI 3 "memory_operand" "m,m"))
4630 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4631 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4632 && !TARGET_FISTTP
4633 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4634 "#"
4635 [(set_attr "type" "fistp")
4636 (set_attr "i387_cw" "trunc")
4637 (set_attr "mode" "<MODE>")])
4638
4639 (define_split
4640 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4641 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4642 (use (match_operand:HI 2 "memory_operand" ""))
4643 (use (match_operand:HI 3 "memory_operand" ""))
4644 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4645 "reload_completed"
4646 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4647 (use (match_dup 2))
4648 (use (match_dup 3))])
4649 (set (match_dup 0) (match_dup 4))])
4650
4651 (define_split
4652 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4653 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4654 (use (match_operand:HI 2 "memory_operand" ""))
4655 (use (match_operand:HI 3 "memory_operand" ""))
4656 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4657 "reload_completed"
4658 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4659 (use (match_dup 2))
4660 (use (match_dup 3))])])
4661
4662 (define_insn "x86_fnstcw_1"
4663 [(set (match_operand:HI 0 "memory_operand" "=m")
4664 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4665 "TARGET_80387"
4666 "fnstcw\t%0"
4667 [(set (attr "length")
4668 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4669 (set_attr "mode" "HI")
4670 (set_attr "unit" "i387")
4671 (set_attr "bdver1_decode" "vector")])
4672
4673 (define_insn "x86_fldcw_1"
4674 [(set (reg:HI FPCR_REG)
4675 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4676 "TARGET_80387"
4677 "fldcw\t%0"
4678 [(set (attr "length")
4679 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4680 (set_attr "mode" "HI")
4681 (set_attr "unit" "i387")
4682 (set_attr "athlon_decode" "vector")
4683 (set_attr "amdfam10_decode" "vector")
4684 (set_attr "bdver1_decode" "vector")])
4685 \f
4686 ;; Conversion between fixed point and floating point.
4687
4688 ;; Even though we only accept memory inputs, the backend _really_
4689 ;; wants to be able to do this between registers.
4690
4691 (define_expand "floathi<mode>2"
4692 [(set (match_operand:X87MODEF 0 "register_operand" "")
4693 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4694 "TARGET_80387
4695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696 || TARGET_MIX_SSE_I387)")
4697
4698 ;; Pre-reload splitter to add memory clobber to the pattern.
4699 (define_insn_and_split "*floathi<mode>2_1"
4700 [(set (match_operand:X87MODEF 0 "register_operand" "")
4701 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4702 "TARGET_80387
4703 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4704 || TARGET_MIX_SSE_I387)
4705 && can_create_pseudo_p ()"
4706 "#"
4707 "&& 1"
4708 [(parallel [(set (match_dup 0)
4709 (float:X87MODEF (match_dup 1)))
4710 (clobber (match_dup 2))])]
4711 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4712
4713 (define_insn "*floathi<mode>2_i387_with_temp"
4714 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4715 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4716 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4717 "TARGET_80387
4718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719 || TARGET_MIX_SSE_I387)"
4720 "#"
4721 [(set_attr "type" "fmov,multi")
4722 (set_attr "mode" "<MODE>")
4723 (set_attr "unit" "*,i387")
4724 (set_attr "fp_int_src" "true")])
4725
4726 (define_insn "*floathi<mode>2_i387"
4727 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4728 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4729 "TARGET_80387
4730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4731 || TARGET_MIX_SSE_I387)"
4732 "fild%Z1\t%1"
4733 [(set_attr "type" "fmov")
4734 (set_attr "mode" "<MODE>")
4735 (set_attr "fp_int_src" "true")])
4736
4737 (define_split
4738 [(set (match_operand:X87MODEF 0 "register_operand" "")
4739 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4740 (clobber (match_operand:HI 2 "memory_operand" ""))]
4741 "TARGET_80387
4742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4743 || TARGET_MIX_SSE_I387)
4744 && reload_completed"
4745 [(set (match_dup 2) (match_dup 1))
4746 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4747
4748 (define_split
4749 [(set (match_operand:X87MODEF 0 "register_operand" "")
4750 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4751 (clobber (match_operand:HI 2 "memory_operand" ""))]
4752 "TARGET_80387
4753 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4754 || TARGET_MIX_SSE_I387)
4755 && reload_completed"
4756 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4757
4758 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4759 [(set (match_operand:X87MODEF 0 "register_operand" "")
4760 (float:X87MODEF
4761 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4762 "TARGET_80387
4763 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4764 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4765 {
4766 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4767 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4768 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4769 {
4770 rtx reg = gen_reg_rtx (XFmode);
4771 rtx (*insn)(rtx, rtx);
4772
4773 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4774
4775 if (<X87MODEF:MODE>mode == SFmode)
4776 insn = gen_truncxfsf2;
4777 else if (<X87MODEF:MODE>mode == DFmode)
4778 insn = gen_truncxfdf2;
4779 else
4780 gcc_unreachable ();
4781
4782 emit_insn (insn (operands[0], reg));
4783 DONE;
4784 }
4785 })
4786
4787 ;; Pre-reload splitter to add memory clobber to the pattern.
4788 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4789 [(set (match_operand:X87MODEF 0 "register_operand" "")
4790 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4791 "((TARGET_80387
4792 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4793 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4794 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4795 || TARGET_MIX_SSE_I387))
4796 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4797 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4798 && ((<SSEMODEI24:MODE>mode == SImode
4799 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4800 && optimize_function_for_speed_p (cfun)
4801 && flag_trapping_math)
4802 || !(TARGET_INTER_UNIT_CONVERSIONS
4803 || optimize_function_for_size_p (cfun)))))
4804 && can_create_pseudo_p ()"
4805 "#"
4806 "&& 1"
4807 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4808 (clobber (match_dup 2))])]
4809 {
4810 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4811
4812 /* Avoid store forwarding (partial memory) stall penalty
4813 by passing DImode value through XMM registers. */
4814 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4815 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4816 && optimize_function_for_speed_p (cfun))
4817 {
4818 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4819 operands[1],
4820 operands[2]));
4821 DONE;
4822 }
4823 })
4824
4825 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4826 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4827 (float:MODEF
4828 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4829 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4830 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4831 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4832 "#"
4833 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4834 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4835 (set_attr "unit" "*,i387,*,*,*")
4836 (set_attr "athlon_decode" "*,*,double,direct,double")
4837 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4838 (set_attr "bdver1_decode" "*,*,double,direct,double")
4839 (set_attr "fp_int_src" "true")])
4840
4841 (define_insn "*floatsi<mode>2_vector_mixed"
4842 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4843 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4844 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4845 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4846 "@
4847 fild%Z1\t%1
4848 #"
4849 [(set_attr "type" "fmov,sseicvt")
4850 (set_attr "mode" "<MODE>,<ssevecmode>")
4851 (set_attr "unit" "i387,*")
4852 (set_attr "athlon_decode" "*,direct")
4853 (set_attr "amdfam10_decode" "*,double")
4854 (set_attr "bdver1_decode" "*,direct")
4855 (set_attr "fp_int_src" "true")])
4856
4857 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4858 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4859 (float:MODEF
4860 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4861 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4862 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4863 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4864 "#"
4865 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4866 (set_attr "mode" "<MODEF:MODE>")
4867 (set_attr "unit" "*,i387,*,*")
4868 (set_attr "athlon_decode" "*,*,double,direct")
4869 (set_attr "amdfam10_decode" "*,*,vector,double")
4870 (set_attr "bdver1_decode" "*,*,double,direct")
4871 (set_attr "fp_int_src" "true")])
4872
4873 (define_split
4874 [(set (match_operand:MODEF 0 "register_operand" "")
4875 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4876 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4877 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4878 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4879 && TARGET_INTER_UNIT_CONVERSIONS
4880 && reload_completed
4881 && (SSE_REG_P (operands[0])
4882 || (GET_CODE (operands[0]) == SUBREG
4883 && SSE_REG_P (operands[0])))"
4884 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4885
4886 (define_split
4887 [(set (match_operand:MODEF 0 "register_operand" "")
4888 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4889 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4890 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4891 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4892 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4893 && reload_completed
4894 && (SSE_REG_P (operands[0])
4895 || (GET_CODE (operands[0]) == SUBREG
4896 && SSE_REG_P (operands[0])))"
4897 [(set (match_dup 2) (match_dup 1))
4898 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4899
4900 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
4901 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4902 (float:MODEF
4903 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
4904 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4905 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4906 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4907 "@
4908 fild%Z1\t%1
4909 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
4910 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4911 [(set_attr "type" "fmov,sseicvt,sseicvt")
4912 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4913 (set_attr "mode" "<MODEF:MODE>")
4914 (set (attr "prefix_rex")
4915 (if_then_else
4916 (and (eq_attr "prefix" "maybe_vex")
4917 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4918 (const_string "1")
4919 (const_string "*")))
4920 (set_attr "unit" "i387,*,*")
4921 (set_attr "athlon_decode" "*,double,direct")
4922 (set_attr "amdfam10_decode" "*,vector,double")
4923 (set_attr "bdver1_decode" "*,double,direct")
4924 (set_attr "fp_int_src" "true")])
4925
4926 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
4927 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4928 (float:MODEF
4929 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
4930 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4931 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4933 "@
4934 fild%Z1\t%1
4935 %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4936 [(set_attr "type" "fmov,sseicvt")
4937 (set_attr "prefix" "orig,maybe_vex")
4938 (set_attr "mode" "<MODEF:MODE>")
4939 (set (attr "prefix_rex")
4940 (if_then_else
4941 (and (eq_attr "prefix" "maybe_vex")
4942 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4943 (const_string "1")
4944 (const_string "*")))
4945 (set_attr "athlon_decode" "*,direct")
4946 (set_attr "amdfam10_decode" "*,double")
4947 (set_attr "bdver1_decode" "*,direct")
4948 (set_attr "fp_int_src" "true")])
4949
4950 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4951 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4952 (float:MODEF
4953 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4954 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4955 "TARGET_SSE2 && TARGET_SSE_MATH
4956 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4957 "#"
4958 [(set_attr "type" "sseicvt")
4959 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4960 (set_attr "athlon_decode" "double,direct,double")
4961 (set_attr "amdfam10_decode" "vector,double,double")
4962 (set_attr "bdver1_decode" "double,direct,double")
4963 (set_attr "fp_int_src" "true")])
4964
4965 (define_insn "*floatsi<mode>2_vector_sse"
4966 [(set (match_operand:MODEF 0 "register_operand" "=x")
4967 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4968 "TARGET_SSE2 && TARGET_SSE_MATH
4969 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4970 "#"
4971 [(set_attr "type" "sseicvt")
4972 (set_attr "mode" "<MODE>")
4973 (set_attr "athlon_decode" "direct")
4974 (set_attr "amdfam10_decode" "double")
4975 (set_attr "bdver1_decode" "direct")
4976 (set_attr "fp_int_src" "true")])
4977
4978 (define_split
4979 [(set (match_operand:MODEF 0 "register_operand" "")
4980 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4981 (clobber (match_operand:SI 2 "memory_operand" ""))]
4982 "TARGET_SSE2 && TARGET_SSE_MATH
4983 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4984 && reload_completed
4985 && (SSE_REG_P (operands[0])
4986 || (GET_CODE (operands[0]) == SUBREG
4987 && SSE_REG_P (operands[0])))"
4988 [(const_int 0)]
4989 {
4990 rtx op1 = operands[1];
4991
4992 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4993 <MODE>mode, 0);
4994 if (GET_CODE (op1) == SUBREG)
4995 op1 = SUBREG_REG (op1);
4996
4997 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4998 {
4999 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5000 emit_insn (gen_sse2_loadld (operands[4],
5001 CONST0_RTX (V4SImode), operands[1]));
5002 }
5003 /* We can ignore possible trapping value in the
5004 high part of SSE register for non-trapping math. */
5005 else if (SSE_REG_P (op1) && !flag_trapping_math)
5006 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5007 else
5008 {
5009 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5010 emit_move_insn (operands[2], operands[1]);
5011 emit_insn (gen_sse2_loadld (operands[4],
5012 CONST0_RTX (V4SImode), operands[2]));
5013 }
5014 emit_insn
5015 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5016 DONE;
5017 })
5018
5019 (define_split
5020 [(set (match_operand:MODEF 0 "register_operand" "")
5021 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5022 (clobber (match_operand:SI 2 "memory_operand" ""))]
5023 "TARGET_SSE2 && TARGET_SSE_MATH
5024 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5025 && reload_completed
5026 && (SSE_REG_P (operands[0])
5027 || (GET_CODE (operands[0]) == SUBREG
5028 && SSE_REG_P (operands[0])))"
5029 [(const_int 0)]
5030 {
5031 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5032 <MODE>mode, 0);
5033 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5034
5035 emit_insn (gen_sse2_loadld (operands[4],
5036 CONST0_RTX (V4SImode), operands[1]));
5037 emit_insn
5038 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5039 DONE;
5040 })
5041
5042 (define_split
5043 [(set (match_operand:MODEF 0 "register_operand" "")
5044 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5045 "TARGET_SSE2 && TARGET_SSE_MATH
5046 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5047 && reload_completed
5048 && (SSE_REG_P (operands[0])
5049 || (GET_CODE (operands[0]) == SUBREG
5050 && SSE_REG_P (operands[0])))"
5051 [(const_int 0)]
5052 {
5053 rtx op1 = operands[1];
5054
5055 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5056 <MODE>mode, 0);
5057 if (GET_CODE (op1) == SUBREG)
5058 op1 = SUBREG_REG (op1);
5059
5060 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5061 {
5062 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5063 emit_insn (gen_sse2_loadld (operands[4],
5064 CONST0_RTX (V4SImode), operands[1]));
5065 }
5066 /* We can ignore possible trapping value in the
5067 high part of SSE register for non-trapping math. */
5068 else if (SSE_REG_P (op1) && !flag_trapping_math)
5069 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5070 else
5071 gcc_unreachable ();
5072 emit_insn
5073 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5074 DONE;
5075 })
5076
5077 (define_split
5078 [(set (match_operand:MODEF 0 "register_operand" "")
5079 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5080 "TARGET_SSE2 && TARGET_SSE_MATH
5081 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5082 && reload_completed
5083 && (SSE_REG_P (operands[0])
5084 || (GET_CODE (operands[0]) == SUBREG
5085 && SSE_REG_P (operands[0])))"
5086 [(const_int 0)]
5087 {
5088 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5089 <MODE>mode, 0);
5090 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5091
5092 emit_insn (gen_sse2_loadld (operands[4],
5093 CONST0_RTX (V4SImode), operands[1]));
5094 emit_insn
5095 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5096 DONE;
5097 })
5098
5099 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5100 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5101 (float:MODEF
5102 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5103 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5104 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5105 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5106 "#"
5107 [(set_attr "type" "sseicvt")
5108 (set_attr "mode" "<MODEF:MODE>")
5109 (set_attr "athlon_decode" "double,direct")
5110 (set_attr "amdfam10_decode" "vector,double")
5111 (set_attr "bdver1_decode" "double,direct")
5112 (set_attr "fp_int_src" "true")])
5113
5114 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5115 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5116 (float:MODEF
5117 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5118 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5119 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5120 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5121 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5122 [(set_attr "type" "sseicvt")
5123 (set_attr "prefix" "maybe_vex")
5124 (set_attr "mode" "<MODEF:MODE>")
5125 (set (attr "prefix_rex")
5126 (if_then_else
5127 (and (eq_attr "prefix" "maybe_vex")
5128 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5129 (const_string "1")
5130 (const_string "*")))
5131 (set_attr "athlon_decode" "double,direct")
5132 (set_attr "amdfam10_decode" "vector,double")
5133 (set_attr "bdver1_decode" "double,direct")
5134 (set_attr "fp_int_src" "true")])
5135
5136 (define_split
5137 [(set (match_operand:MODEF 0 "register_operand" "")
5138 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5139 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5140 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5141 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5143 && reload_completed
5144 && (SSE_REG_P (operands[0])
5145 || (GET_CODE (operands[0]) == SUBREG
5146 && SSE_REG_P (operands[0])))"
5147 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5148
5149 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5150 [(set (match_operand:MODEF 0 "register_operand" "=x")
5151 (float:MODEF
5152 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5153 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5154 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5155 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5156 "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5157 [(set_attr "type" "sseicvt")
5158 (set_attr "prefix" "maybe_vex")
5159 (set_attr "mode" "<MODEF:MODE>")
5160 (set (attr "prefix_rex")
5161 (if_then_else
5162 (and (eq_attr "prefix" "maybe_vex")
5163 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5164 (const_string "1")
5165 (const_string "*")))
5166 (set_attr "athlon_decode" "direct")
5167 (set_attr "amdfam10_decode" "double")
5168 (set_attr "bdver1_decode" "direct")
5169 (set_attr "fp_int_src" "true")])
5170
5171 (define_split
5172 [(set (match_operand:MODEF 0 "register_operand" "")
5173 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5174 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5175 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5178 && reload_completed
5179 && (SSE_REG_P (operands[0])
5180 || (GET_CODE (operands[0]) == SUBREG
5181 && SSE_REG_P (operands[0])))"
5182 [(set (match_dup 2) (match_dup 1))
5183 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5184
5185 (define_split
5186 [(set (match_operand:MODEF 0 "register_operand" "")
5187 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5188 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5189 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5190 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5191 && reload_completed
5192 && (SSE_REG_P (operands[0])
5193 || (GET_CODE (operands[0]) == SUBREG
5194 && SSE_REG_P (operands[0])))"
5195 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5196
5197 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5198 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5199 (float:X87MODEF
5200 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5201 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5202 "TARGET_80387
5203 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5204 "@
5205 fild%Z1\t%1
5206 #"
5207 [(set_attr "type" "fmov,multi")
5208 (set_attr "mode" "<X87MODEF:MODE>")
5209 (set_attr "unit" "*,i387")
5210 (set_attr "fp_int_src" "true")])
5211
5212 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5213 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5214 (float:X87MODEF
5215 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5216 "TARGET_80387
5217 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5218 "fild%Z1\t%1"
5219 [(set_attr "type" "fmov")
5220 (set_attr "mode" "<X87MODEF:MODE>")
5221 (set_attr "fp_int_src" "true")])
5222
5223 (define_split
5224 [(set (match_operand:X87MODEF 0 "register_operand" "")
5225 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5226 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5227 "TARGET_80387
5228 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5229 && reload_completed
5230 && FP_REG_P (operands[0])"
5231 [(set (match_dup 2) (match_dup 1))
5232 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5233
5234 (define_split
5235 [(set (match_operand:X87MODEF 0 "register_operand" "")
5236 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5237 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5238 "TARGET_80387
5239 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5240 && reload_completed
5241 && FP_REG_P (operands[0])"
5242 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5243
5244 ;; Avoid store forwarding (partial memory) stall penalty
5245 ;; by passing DImode value through XMM registers. */
5246
5247 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5248 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5249 (float:X87MODEF
5250 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5251 (clobber (match_scratch:V4SI 3 "=X,x"))
5252 (clobber (match_scratch:V4SI 4 "=X,x"))
5253 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5254 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5255 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5256 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5257 "#"
5258 [(set_attr "type" "multi")
5259 (set_attr "mode" "<X87MODEF:MODE>")
5260 (set_attr "unit" "i387")
5261 (set_attr "fp_int_src" "true")])
5262
5263 (define_split
5264 [(set (match_operand:X87MODEF 0 "register_operand" "")
5265 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5266 (clobber (match_scratch:V4SI 3 ""))
5267 (clobber (match_scratch:V4SI 4 ""))
5268 (clobber (match_operand:DI 2 "memory_operand" ""))]
5269 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5270 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5271 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5272 && reload_completed
5273 && FP_REG_P (operands[0])"
5274 [(set (match_dup 2) (match_dup 3))
5275 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5276 {
5277 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5278 Assemble the 64-bit DImode value in an xmm register. */
5279 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5280 gen_rtx_SUBREG (SImode, operands[1], 0)));
5281 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5282 gen_rtx_SUBREG (SImode, operands[1], 4)));
5283 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5284 operands[4]));
5285
5286 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5287 })
5288
5289 (define_split
5290 [(set (match_operand:X87MODEF 0 "register_operand" "")
5291 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5292 (clobber (match_scratch:V4SI 3 ""))
5293 (clobber (match_scratch:V4SI 4 ""))
5294 (clobber (match_operand:DI 2 "memory_operand" ""))]
5295 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5296 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5297 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5298 && reload_completed
5299 && FP_REG_P (operands[0])"
5300 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5301
5302 ;; Avoid store forwarding (partial memory) stall penalty by extending
5303 ;; SImode value to DImode through XMM register instead of pushing two
5304 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5305 ;; targets benefit from this optimization. Also note that fild
5306 ;; loads from memory only.
5307
5308 (define_insn "*floatunssi<mode>2_1"
5309 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5310 (unsigned_float:X87MODEF
5311 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5312 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5313 (clobber (match_scratch:SI 3 "=X,x"))]
5314 "!TARGET_64BIT
5315 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5316 && TARGET_SSE"
5317 "#"
5318 [(set_attr "type" "multi")
5319 (set_attr "mode" "<MODE>")])
5320
5321 (define_split
5322 [(set (match_operand:X87MODEF 0 "register_operand" "")
5323 (unsigned_float:X87MODEF
5324 (match_operand:SI 1 "register_operand" "")))
5325 (clobber (match_operand:DI 2 "memory_operand" ""))
5326 (clobber (match_scratch:SI 3 ""))]
5327 "!TARGET_64BIT
5328 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5329 && TARGET_SSE
5330 && reload_completed"
5331 [(set (match_dup 2) (match_dup 1))
5332 (set (match_dup 0)
5333 (float:X87MODEF (match_dup 2)))]
5334 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5335
5336 (define_split
5337 [(set (match_operand:X87MODEF 0 "register_operand" "")
5338 (unsigned_float:X87MODEF
5339 (match_operand:SI 1 "memory_operand" "")))
5340 (clobber (match_operand:DI 2 "memory_operand" ""))
5341 (clobber (match_scratch:SI 3 ""))]
5342 "!TARGET_64BIT
5343 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5344 && TARGET_SSE
5345 && reload_completed"
5346 [(set (match_dup 2) (match_dup 3))
5347 (set (match_dup 0)
5348 (float:X87MODEF (match_dup 2)))]
5349 {
5350 emit_move_insn (operands[3], operands[1]);
5351 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5352 })
5353
5354 (define_expand "floatunssi<mode>2"
5355 [(parallel
5356 [(set (match_operand:X87MODEF 0 "register_operand" "")
5357 (unsigned_float:X87MODEF
5358 (match_operand:SI 1 "nonimmediate_operand" "")))
5359 (clobber (match_dup 2))
5360 (clobber (match_scratch:SI 3 ""))])]
5361 "!TARGET_64BIT
5362 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5363 && TARGET_SSE)
5364 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5365 {
5366 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5367 {
5368 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5369 DONE;
5370 }
5371 else
5372 {
5373 enum ix86_stack_slot slot = (virtuals_instantiated
5374 ? SLOT_TEMP
5375 : SLOT_VIRTUAL);
5376 operands[2] = assign_386_stack_local (DImode, slot);
5377 }
5378 })
5379
5380 (define_expand "floatunsdisf2"
5381 [(use (match_operand:SF 0 "register_operand" ""))
5382 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5383 "TARGET_64BIT && TARGET_SSE_MATH"
5384 "x86_emit_floatuns (operands); DONE;")
5385
5386 (define_expand "floatunsdidf2"
5387 [(use (match_operand:DF 0 "register_operand" ""))
5388 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5389 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5390 && TARGET_SSE2 && TARGET_SSE_MATH"
5391 {
5392 if (TARGET_64BIT)
5393 x86_emit_floatuns (operands);
5394 else
5395 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5396 DONE;
5397 })
5398 \f
5399 ;; Add instructions
5400
5401 (define_expand "add<mode>3"
5402 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5403 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5404 (match_operand:SDWIM 2 "<general_operand>" "")))]
5405 ""
5406 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5407
5408 (define_insn_and_split "*add<dwi>3_doubleword"
5409 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5410 (plus:<DWI>
5411 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5412 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5413 (clobber (reg:CC FLAGS_REG))]
5414 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5415 "#"
5416 "reload_completed"
5417 [(parallel [(set (reg:CC FLAGS_REG)
5418 (unspec:CC [(match_dup 1) (match_dup 2)]
5419 UNSPEC_ADD_CARRY))
5420 (set (match_dup 0)
5421 (plus:DWIH (match_dup 1) (match_dup 2)))])
5422 (parallel [(set (match_dup 3)
5423 (plus:DWIH
5424 (match_dup 4)
5425 (plus:DWIH
5426 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5427 (match_dup 5))))
5428 (clobber (reg:CC FLAGS_REG))])]
5429 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5430
5431 (define_insn "*add<mode>3_cc"
5432 [(set (reg:CC FLAGS_REG)
5433 (unspec:CC
5434 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5435 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5436 UNSPEC_ADD_CARRY))
5437 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5438 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5439 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5440 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5441 [(set_attr "type" "alu")
5442 (set_attr "mode" "<MODE>")])
5443
5444 (define_insn "addqi3_cc"
5445 [(set (reg:CC FLAGS_REG)
5446 (unspec:CC
5447 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5448 (match_operand:QI 2 "general_operand" "qn,qm")]
5449 UNSPEC_ADD_CARRY))
5450 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5451 (plus:QI (match_dup 1) (match_dup 2)))]
5452 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5453 "add{b}\t{%2, %0|%0, %2}"
5454 [(set_attr "type" "alu")
5455 (set_attr "mode" "QI")])
5456
5457 (define_insn "*lea_1"
5458 [(set (match_operand:P 0 "register_operand" "=r")
5459 (match_operand:P 1 "no_seg_address_operand" "p"))]
5460 ""
5461 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5462 [(set_attr "type" "lea")
5463 (set_attr "mode" "<MODE>")])
5464
5465 (define_insn "*lea_2"
5466 [(set (match_operand:SI 0 "register_operand" "=r")
5467 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5468 "TARGET_64BIT"
5469 "lea{l}\t{%a1, %0|%0, %a1}"
5470 [(set_attr "type" "lea")
5471 (set_attr "mode" "SI")])
5472
5473 (define_insn "*lea_2_zext"
5474 [(set (match_operand:DI 0 "register_operand" "=r")
5475 (zero_extend:DI
5476 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5477 "TARGET_64BIT"
5478 "lea{l}\t{%a1, %k0|%k0, %a1}"
5479 [(set_attr "type" "lea")
5480 (set_attr "mode" "SI")])
5481
5482 (define_insn "*add<mode>_1"
5483 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5484 (plus:SWI48
5485 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5486 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5487 (clobber (reg:CC FLAGS_REG))]
5488 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5489 {
5490 switch (get_attr_type (insn))
5491 {
5492 case TYPE_LEA:
5493 return "#";
5494
5495 case TYPE_INCDEC:
5496 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5497 if (operands[2] == const1_rtx)
5498 return "inc{<imodesuffix>}\t%0";
5499 else
5500 {
5501 gcc_assert (operands[2] == constm1_rtx);
5502 return "dec{<imodesuffix>}\t%0";
5503 }
5504
5505 default:
5506 /* For most processors, ADD is faster than LEA. This alternative
5507 was added to use ADD as much as possible. */
5508 if (which_alternative == 2)
5509 {
5510 rtx tmp;
5511 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5512 }
5513
5514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5516 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5517
5518 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5519 }
5520 }
5521 [(set (attr "type")
5522 (cond [(eq_attr "alternative" "3")
5523 (const_string "lea")
5524 (match_operand:SWI48 2 "incdec_operand" "")
5525 (const_string "incdec")
5526 ]
5527 (const_string "alu")))
5528 (set (attr "length_immediate")
5529 (if_then_else
5530 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5531 (const_string "1")
5532 (const_string "*")))
5533 (set_attr "mode" "<MODE>")])
5534
5535 ;; It may seem that nonimmediate operand is proper one for operand 1.
5536 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5537 ;; we take care in ix86_binary_operator_ok to not allow two memory
5538 ;; operands so proper swapping will be done in reload. This allow
5539 ;; patterns constructed from addsi_1 to match.
5540
5541 (define_insn "*addsi_1_zext"
5542 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5543 (zero_extend:DI
5544 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5545 (match_operand:SI 2 "general_operand" "g,0,li"))))
5546 (clobber (reg:CC FLAGS_REG))]
5547 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5548 {
5549 switch (get_attr_type (insn))
5550 {
5551 case TYPE_LEA:
5552 return "#";
5553
5554 case TYPE_INCDEC:
5555 if (operands[2] == const1_rtx)
5556 return "inc{l}\t%k0";
5557 else
5558 {
5559 gcc_assert (operands[2] == constm1_rtx);
5560 return "dec{l}\t%k0";
5561 }
5562
5563 default:
5564 /* For most processors, ADD is faster than LEA. This alternative
5565 was added to use ADD as much as possible. */
5566 if (which_alternative == 1)
5567 {
5568 rtx tmp;
5569 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5570 }
5571
5572 if (x86_maybe_negate_const_int (&operands[2], SImode))
5573 return "sub{l}\t{%2, %k0|%k0, %2}";
5574
5575 return "add{l}\t{%2, %k0|%k0, %2}";
5576 }
5577 }
5578 [(set (attr "type")
5579 (cond [(eq_attr "alternative" "2")
5580 (const_string "lea")
5581 (match_operand:SI 2 "incdec_operand" "")
5582 (const_string "incdec")
5583 ]
5584 (const_string "alu")))
5585 (set (attr "length_immediate")
5586 (if_then_else
5587 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5588 (const_string "1")
5589 (const_string "*")))
5590 (set_attr "mode" "SI")])
5591
5592 (define_insn "*addhi_1"
5593 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5594 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5595 (match_operand:HI 2 "general_operand" "rn,rm")))
5596 (clobber (reg:CC FLAGS_REG))]
5597 "TARGET_PARTIAL_REG_STALL
5598 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5599 {
5600 switch (get_attr_type (insn))
5601 {
5602 case TYPE_INCDEC:
5603 if (operands[2] == const1_rtx)
5604 return "inc{w}\t%0";
5605 else
5606 {
5607 gcc_assert (operands[2] == constm1_rtx);
5608 return "dec{w}\t%0";
5609 }
5610
5611 default:
5612 if (x86_maybe_negate_const_int (&operands[2], HImode))
5613 return "sub{w}\t{%2, %0|%0, %2}";
5614
5615 return "add{w}\t{%2, %0|%0, %2}";
5616 }
5617 }
5618 [(set (attr "type")
5619 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5620 (const_string "incdec")
5621 (const_string "alu")))
5622 (set (attr "length_immediate")
5623 (if_then_else
5624 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5625 (const_string "1")
5626 (const_string "*")))
5627 (set_attr "mode" "HI")])
5628
5629 (define_insn "*addhi_1_lea"
5630 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5631 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5632 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5633 (clobber (reg:CC FLAGS_REG))]
5634 "!TARGET_PARTIAL_REG_STALL
5635 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5636 {
5637 switch (get_attr_type (insn))
5638 {
5639 case TYPE_LEA:
5640 return "#";
5641
5642 case TYPE_INCDEC:
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 if (operands[2] == const1_rtx)
5645 return "inc{w}\t%0";
5646 else
5647 {
5648 gcc_assert (operands[2] == constm1_rtx);
5649 return "dec{w}\t%0";
5650 }
5651
5652 default:
5653 /* For most processors, ADD is faster than LEA. This alternative
5654 was added to use ADD as much as possible. */
5655 if (which_alternative == 2)
5656 {
5657 rtx tmp;
5658 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5659 }
5660
5661 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5662 if (x86_maybe_negate_const_int (&operands[2], HImode))
5663 return "sub{w}\t{%2, %0|%0, %2}";
5664
5665 return "add{w}\t{%2, %0|%0, %2}";
5666 }
5667 }
5668 [(set (attr "type")
5669 (cond [(eq_attr "alternative" "3")
5670 (const_string "lea")
5671 (match_operand:HI 2 "incdec_operand" "")
5672 (const_string "incdec")
5673 ]
5674 (const_string "alu")))
5675 (set (attr "length_immediate")
5676 (if_then_else
5677 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5678 (const_string "1")
5679 (const_string "*")))
5680 (set_attr "mode" "HI,HI,HI,SI")])
5681
5682 ;; %%% Potential partial reg stall on alternative 2. What to do?
5683 (define_insn "*addqi_1"
5684 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5685 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5686 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5687 (clobber (reg:CC FLAGS_REG))]
5688 "TARGET_PARTIAL_REG_STALL
5689 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5690 {
5691 int widen = (which_alternative == 2);
5692 switch (get_attr_type (insn))
5693 {
5694 case TYPE_INCDEC:
5695 if (operands[2] == const1_rtx)
5696 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5697 else
5698 {
5699 gcc_assert (operands[2] == constm1_rtx);
5700 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5701 }
5702
5703 default:
5704 if (x86_maybe_negate_const_int (&operands[2], QImode))
5705 {
5706 if (widen)
5707 return "sub{l}\t{%2, %k0|%k0, %2}";
5708 else
5709 return "sub{b}\t{%2, %0|%0, %2}";
5710 }
5711 if (widen)
5712 return "add{l}\t{%k2, %k0|%k0, %k2}";
5713 else
5714 return "add{b}\t{%2, %0|%0, %2}";
5715 }
5716 }
5717 [(set (attr "type")
5718 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5719 (const_string "incdec")
5720 (const_string "alu")))
5721 (set (attr "length_immediate")
5722 (if_then_else
5723 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5724 (const_string "1")
5725 (const_string "*")))
5726 (set_attr "mode" "QI,QI,SI")])
5727
5728 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5729 (define_insn "*addqi_1_lea"
5730 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5731 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5732 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5733 (clobber (reg:CC FLAGS_REG))]
5734 "!TARGET_PARTIAL_REG_STALL
5735 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5736 {
5737 int widen = (which_alternative == 3 || which_alternative == 4);
5738
5739 switch (get_attr_type (insn))
5740 {
5741 case TYPE_LEA:
5742 return "#";
5743
5744 case TYPE_INCDEC:
5745 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746 if (operands[2] == const1_rtx)
5747 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5748 else
5749 {
5750 gcc_assert (operands[2] == constm1_rtx);
5751 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5752 }
5753
5754 default:
5755 /* For most processors, ADD is faster than LEA. These alternatives
5756 were added to use ADD as much as possible. */
5757 if (which_alternative == 2 || which_alternative == 4)
5758 {
5759 rtx tmp;
5760 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5761 }
5762
5763 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5764 if (x86_maybe_negate_const_int (&operands[2], QImode))
5765 {
5766 if (widen)
5767 return "sub{l}\t{%2, %k0|%k0, %2}";
5768 else
5769 return "sub{b}\t{%2, %0|%0, %2}";
5770 }
5771 if (widen)
5772 return "add{l}\t{%k2, %k0|%k0, %k2}";
5773 else
5774 return "add{b}\t{%2, %0|%0, %2}";
5775 }
5776 }
5777 [(set (attr "type")
5778 (cond [(eq_attr "alternative" "5")
5779 (const_string "lea")
5780 (match_operand:QI 2 "incdec_operand" "")
5781 (const_string "incdec")
5782 ]
5783 (const_string "alu")))
5784 (set (attr "length_immediate")
5785 (if_then_else
5786 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5787 (const_string "1")
5788 (const_string "*")))
5789 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5790
5791 (define_insn "*addqi_1_slp"
5792 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5793 (plus:QI (match_dup 0)
5794 (match_operand:QI 1 "general_operand" "qn,qnm")))
5795 (clobber (reg:CC FLAGS_REG))]
5796 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5797 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5798 {
5799 switch (get_attr_type (insn))
5800 {
5801 case TYPE_INCDEC:
5802 if (operands[1] == const1_rtx)
5803 return "inc{b}\t%0";
5804 else
5805 {
5806 gcc_assert (operands[1] == constm1_rtx);
5807 return "dec{b}\t%0";
5808 }
5809
5810 default:
5811 if (x86_maybe_negate_const_int (&operands[1], QImode))
5812 return "sub{b}\t{%1, %0|%0, %1}";
5813
5814 return "add{b}\t{%1, %0|%0, %1}";
5815 }
5816 }
5817 [(set (attr "type")
5818 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5819 (const_string "incdec")
5820 (const_string "alu1")))
5821 (set (attr "memory")
5822 (if_then_else (match_operand 1 "memory_operand" "")
5823 (const_string "load")
5824 (const_string "none")))
5825 (set_attr "mode" "QI")])
5826
5827 ;; Convert lea to the lea pattern to avoid flags dependency.
5828 (define_split
5829 [(set (match_operand 0 "register_operand" "")
5830 (plus (match_operand 1 "register_operand" "")
5831 (match_operand 2 "nonmemory_operand" "")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5834 [(const_int 0)]
5835 {
5836 rtx pat;
5837 enum machine_mode mode = GET_MODE (operands[0]);
5838
5839 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5840 may confuse gen_lowpart. */
5841 if (mode != Pmode)
5842 {
5843 operands[1] = gen_lowpart (Pmode, operands[1]);
5844 operands[2] = gen_lowpart (Pmode, operands[2]);
5845 }
5846
5847 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5848
5849 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5850 operands[0] = gen_lowpart (SImode, operands[0]);
5851
5852 if (TARGET_64BIT && mode != Pmode)
5853 pat = gen_rtx_SUBREG (SImode, pat, 0);
5854
5855 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5856 DONE;
5857 })
5858
5859 ;; Convert lea to the lea pattern to avoid flags dependency.
5860 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5861 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5862 (define_split
5863 [(set (match_operand:DI 0 "register_operand" "")
5864 (plus:DI (match_operand:DI 1 "register_operand" "")
5865 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5866 (clobber (reg:CC FLAGS_REG))]
5867 "TARGET_64BIT && reload_completed
5868 && true_regnum (operands[0]) != true_regnum (operands[1])"
5869 [(set (match_dup 0)
5870 (plus:DI (match_dup 1) (match_dup 2)))])
5871
5872 ;; Convert lea to the lea pattern to avoid flags dependency.
5873 (define_split
5874 [(set (match_operand:DI 0 "register_operand" "")
5875 (zero_extend:DI
5876 (plus:SI (match_operand:SI 1 "register_operand" "")
5877 (match_operand:SI 2 "nonmemory_operand" ""))))
5878 (clobber (reg:CC FLAGS_REG))]
5879 "TARGET_64BIT && reload_completed
5880 && ix86_lea_for_add_ok (insn, operands)"
5881 [(set (match_dup 0)
5882 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5883 {
5884 operands[1] = gen_lowpart (DImode, operands[1]);
5885 operands[2] = gen_lowpart (DImode, operands[2]);
5886 })
5887
5888 (define_insn "*add<mode>_2"
5889 [(set (reg FLAGS_REG)
5890 (compare
5891 (plus:SWI
5892 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5893 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5894 (const_int 0)))
5895 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5896 (plus:SWI (match_dup 1) (match_dup 2)))]
5897 "ix86_match_ccmode (insn, CCGOCmode)
5898 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5899 {
5900 switch (get_attr_type (insn))
5901 {
5902 case TYPE_INCDEC:
5903 if (operands[2] == const1_rtx)
5904 return "inc{<imodesuffix>}\t%0";
5905 else
5906 {
5907 gcc_assert (operands[2] == constm1_rtx);
5908 return "dec{<imodesuffix>}\t%0";
5909 }
5910
5911 default:
5912 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5913 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5914
5915 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5916 }
5917 }
5918 [(set (attr "type")
5919 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5920 (const_string "incdec")
5921 (const_string "alu")))
5922 (set (attr "length_immediate")
5923 (if_then_else
5924 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5925 (const_string "1")
5926 (const_string "*")))
5927 (set_attr "mode" "<MODE>")])
5928
5929 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5930 (define_insn "*addsi_2_zext"
5931 [(set (reg FLAGS_REG)
5932 (compare
5933 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5934 (match_operand:SI 2 "general_operand" "g"))
5935 (const_int 0)))
5936 (set (match_operand:DI 0 "register_operand" "=r")
5937 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5938 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5939 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5940 {
5941 switch (get_attr_type (insn))
5942 {
5943 case TYPE_INCDEC:
5944 if (operands[2] == const1_rtx)
5945 return "inc{l}\t%k0";
5946 else
5947 {
5948 gcc_assert (operands[2] == constm1_rtx);
5949 return "dec{l}\t%k0";
5950 }
5951
5952 default:
5953 if (x86_maybe_negate_const_int (&operands[2], SImode))
5954 return "sub{l}\t{%2, %k0|%k0, %2}";
5955
5956 return "add{l}\t{%2, %k0|%k0, %2}";
5957 }
5958 }
5959 [(set (attr "type")
5960 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5961 (const_string "incdec")
5962 (const_string "alu")))
5963 (set (attr "length_immediate")
5964 (if_then_else
5965 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5966 (const_string "1")
5967 (const_string "*")))
5968 (set_attr "mode" "SI")])
5969
5970 (define_insn "*add<mode>_3"
5971 [(set (reg FLAGS_REG)
5972 (compare
5973 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5974 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5975 (clobber (match_scratch:SWI 0 "=<r>"))]
5976 "ix86_match_ccmode (insn, CCZmode)
5977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5978 {
5979 switch (get_attr_type (insn))
5980 {
5981 case TYPE_INCDEC:
5982 if (operands[2] == const1_rtx)
5983 return "inc{<imodesuffix>}\t%0";
5984 else
5985 {
5986 gcc_assert (operands[2] == constm1_rtx);
5987 return "dec{<imodesuffix>}\t%0";
5988 }
5989
5990 default:
5991 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5992 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5993
5994 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5995 }
5996 }
5997 [(set (attr "type")
5998 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5999 (const_string "incdec")
6000 (const_string "alu")))
6001 (set (attr "length_immediate")
6002 (if_then_else
6003 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6004 (const_string "1")
6005 (const_string "*")))
6006 (set_attr "mode" "<MODE>")])
6007
6008 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6009 (define_insn "*addsi_3_zext"
6010 [(set (reg FLAGS_REG)
6011 (compare
6012 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6013 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6014 (set (match_operand:DI 0 "register_operand" "=r")
6015 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6016 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6017 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6018 {
6019 switch (get_attr_type (insn))
6020 {
6021 case TYPE_INCDEC:
6022 if (operands[2] == const1_rtx)
6023 return "inc{l}\t%k0";
6024 else
6025 {
6026 gcc_assert (operands[2] == constm1_rtx);
6027 return "dec{l}\t%k0";
6028 }
6029
6030 default:
6031 if (x86_maybe_negate_const_int (&operands[2], SImode))
6032 return "sub{l}\t{%2, %k0|%k0, %2}";
6033
6034 return "add{l}\t{%2, %k0|%k0, %2}";
6035 }
6036 }
6037 [(set (attr "type")
6038 (if_then_else (match_operand:SI 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" "SI")])
6047
6048 ; For comparisons against 1, -1 and 128, we may generate better code
6049 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6050 ; is matched then. We can't accept general immediate, because for
6051 ; case of overflows, the result is messed up.
6052 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6053 ; only for comparisons not depending on it.
6054
6055 (define_insn "*adddi_4"
6056 [(set (reg FLAGS_REG)
6057 (compare
6058 (match_operand:DI 1 "nonimmediate_operand" "0")
6059 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6060 (clobber (match_scratch:DI 0 "=rm"))]
6061 "TARGET_64BIT
6062 && ix86_match_ccmode (insn, CCGCmode)"
6063 {
6064 switch (get_attr_type (insn))
6065 {
6066 case TYPE_INCDEC:
6067 if (operands[2] == constm1_rtx)
6068 return "inc{q}\t%0";
6069 else
6070 {
6071 gcc_assert (operands[2] == const1_rtx);
6072 return "dec{q}\t%0";
6073 }
6074
6075 default:
6076 if (x86_maybe_negate_const_int (&operands[2], DImode))
6077 return "add{q}\t{%2, %0|%0, %2}";
6078
6079 return "sub{q}\t{%2, %0|%0, %2}";
6080 }
6081 }
6082 [(set (attr "type")
6083 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6084 (const_string "incdec")
6085 (const_string "alu")))
6086 (set (attr "length_immediate")
6087 (if_then_else
6088 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6089 (const_string "1")
6090 (const_string "*")))
6091 (set_attr "mode" "DI")])
6092
6093 ; For comparisons against 1, -1 and 128, we may generate better code
6094 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6095 ; is matched then. We can't accept general immediate, because for
6096 ; case of overflows, the result is messed up.
6097 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6098 ; only for comparisons not depending on it.
6099
6100 (define_insn "*add<mode>_4"
6101 [(set (reg FLAGS_REG)
6102 (compare
6103 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6104 (match_operand:SWI124 2 "const_int_operand" "n")))
6105 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6106 "ix86_match_ccmode (insn, CCGCmode)"
6107 {
6108 switch (get_attr_type (insn))
6109 {
6110 case TYPE_INCDEC:
6111 if (operands[2] == constm1_rtx)
6112 return "inc{<imodesuffix>}\t%0";
6113 else
6114 {
6115 gcc_assert (operands[2] == const1_rtx);
6116 return "dec{<imodesuffix>}\t%0";
6117 }
6118
6119 default:
6120 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6121 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6122
6123 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6124 }
6125 }
6126 [(set (attr "type")
6127 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6128 (const_string "incdec")
6129 (const_string "alu")))
6130 (set (attr "length_immediate")
6131 (if_then_else
6132 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6133 (const_string "1")
6134 (const_string "*")))
6135 (set_attr "mode" "<MODE>")])
6136
6137 (define_insn "*add<mode>_5"
6138 [(set (reg FLAGS_REG)
6139 (compare
6140 (plus:SWI
6141 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6142 (match_operand:SWI 2 "<general_operand>" "<g>"))
6143 (const_int 0)))
6144 (clobber (match_scratch:SWI 0 "=<r>"))]
6145 "ix86_match_ccmode (insn, CCGOCmode)
6146 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6147 {
6148 switch (get_attr_type (insn))
6149 {
6150 case TYPE_INCDEC:
6151 if (operands[2] == const1_rtx)
6152 return "inc{<imodesuffix>}\t%0";
6153 else
6154 {
6155 gcc_assert (operands[2] == constm1_rtx);
6156 return "dec{<imodesuffix>}\t%0";
6157 }
6158
6159 default:
6160 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6161 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6162
6163 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6164 }
6165 }
6166 [(set (attr "type")
6167 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6168 (const_string "incdec")
6169 (const_string "alu")))
6170 (set (attr "length_immediate")
6171 (if_then_else
6172 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6173 (const_string "1")
6174 (const_string "*")))
6175 (set_attr "mode" "<MODE>")])
6176
6177 (define_insn "*addqi_ext_1_rex64"
6178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6179 (const_int 8)
6180 (const_int 8))
6181 (plus:SI
6182 (zero_extract:SI
6183 (match_operand 1 "ext_register_operand" "0")
6184 (const_int 8)
6185 (const_int 8))
6186 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6187 (clobber (reg:CC FLAGS_REG))]
6188 "TARGET_64BIT"
6189 {
6190 switch (get_attr_type (insn))
6191 {
6192 case TYPE_INCDEC:
6193 if (operands[2] == const1_rtx)
6194 return "inc{b}\t%h0";
6195 else
6196 {
6197 gcc_assert (operands[2] == constm1_rtx);
6198 return "dec{b}\t%h0";
6199 }
6200
6201 default:
6202 return "add{b}\t{%2, %h0|%h0, %2}";
6203 }
6204 }
6205 [(set (attr "type")
6206 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6207 (const_string "incdec")
6208 (const_string "alu")))
6209 (set_attr "modrm" "1")
6210 (set_attr "mode" "QI")])
6211
6212 (define_insn "addqi_ext_1"
6213 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6214 (const_int 8)
6215 (const_int 8))
6216 (plus:SI
6217 (zero_extract:SI
6218 (match_operand 1 "ext_register_operand" "0")
6219 (const_int 8)
6220 (const_int 8))
6221 (match_operand:QI 2 "general_operand" "Qmn")))
6222 (clobber (reg:CC FLAGS_REG))]
6223 "!TARGET_64BIT"
6224 {
6225 switch (get_attr_type (insn))
6226 {
6227 case TYPE_INCDEC:
6228 if (operands[2] == const1_rtx)
6229 return "inc{b}\t%h0";
6230 else
6231 {
6232 gcc_assert (operands[2] == constm1_rtx);
6233 return "dec{b}\t%h0";
6234 }
6235
6236 default:
6237 return "add{b}\t{%2, %h0|%h0, %2}";
6238 }
6239 }
6240 [(set (attr "type")
6241 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6242 (const_string "incdec")
6243 (const_string "alu")))
6244 (set_attr "modrm" "1")
6245 (set_attr "mode" "QI")])
6246
6247 (define_insn "*addqi_ext_2"
6248 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6249 (const_int 8)
6250 (const_int 8))
6251 (plus:SI
6252 (zero_extract:SI
6253 (match_operand 1 "ext_register_operand" "%0")
6254 (const_int 8)
6255 (const_int 8))
6256 (zero_extract:SI
6257 (match_operand 2 "ext_register_operand" "Q")
6258 (const_int 8)
6259 (const_int 8))))
6260 (clobber (reg:CC FLAGS_REG))]
6261 ""
6262 "add{b}\t{%h2, %h0|%h0, %h2}"
6263 [(set_attr "type" "alu")
6264 (set_attr "mode" "QI")])
6265
6266 ;; The lea patterns for non-Pmodes needs to be matched by
6267 ;; several insns converted to real lea by splitters.
6268
6269 (define_insn_and_split "*lea_general_1"
6270 [(set (match_operand 0 "register_operand" "=r")
6271 (plus (plus (match_operand 1 "index_register_operand" "l")
6272 (match_operand 2 "register_operand" "r"))
6273 (match_operand 3 "immediate_operand" "i")))]
6274 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6275 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6276 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6277 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6278 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6279 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6280 || GET_MODE (operands[3]) == VOIDmode)"
6281 "#"
6282 "&& reload_completed"
6283 [(const_int 0)]
6284 {
6285 rtx pat;
6286 operands[0] = gen_lowpart (SImode, operands[0]);
6287 operands[1] = gen_lowpart (Pmode, operands[1]);
6288 operands[2] = gen_lowpart (Pmode, operands[2]);
6289 operands[3] = gen_lowpart (Pmode, operands[3]);
6290 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6291 operands[3]);
6292 if (Pmode != SImode)
6293 pat = gen_rtx_SUBREG (SImode, pat, 0);
6294 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6295 DONE;
6296 }
6297 [(set_attr "type" "lea")
6298 (set_attr "mode" "SI")])
6299
6300 (define_insn_and_split "*lea_general_1_zext"
6301 [(set (match_operand:DI 0 "register_operand" "=r")
6302 (zero_extend:DI
6303 (plus:SI (plus:SI
6304 (match_operand:SI 1 "index_register_operand" "l")
6305 (match_operand:SI 2 "register_operand" "r"))
6306 (match_operand:SI 3 "immediate_operand" "i"))))]
6307 "TARGET_64BIT"
6308 "#"
6309 "&& reload_completed"
6310 [(set (match_dup 0)
6311 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6312 (match_dup 2))
6313 (match_dup 3)) 0)))]
6314 {
6315 operands[1] = gen_lowpart (Pmode, operands[1]);
6316 operands[2] = gen_lowpart (Pmode, operands[2]);
6317 operands[3] = gen_lowpart (Pmode, operands[3]);
6318 }
6319 [(set_attr "type" "lea")
6320 (set_attr "mode" "SI")])
6321
6322 (define_insn_and_split "*lea_general_2"
6323 [(set (match_operand 0 "register_operand" "=r")
6324 (plus (mult (match_operand 1 "index_register_operand" "l")
6325 (match_operand 2 "const248_operand" "i"))
6326 (match_operand 3 "nonmemory_operand" "ri")))]
6327 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6328 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6329 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6330 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6331 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6332 || GET_MODE (operands[3]) == VOIDmode)"
6333 "#"
6334 "&& reload_completed"
6335 [(const_int 0)]
6336 {
6337 rtx pat;
6338 operands[0] = gen_lowpart (SImode, operands[0]);
6339 operands[1] = gen_lowpart (Pmode, operands[1]);
6340 operands[3] = gen_lowpart (Pmode, operands[3]);
6341 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6342 operands[3]);
6343 if (Pmode != SImode)
6344 pat = gen_rtx_SUBREG (SImode, pat, 0);
6345 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6346 DONE;
6347 }
6348 [(set_attr "type" "lea")
6349 (set_attr "mode" "SI")])
6350
6351 (define_insn_and_split "*lea_general_2_zext"
6352 [(set (match_operand:DI 0 "register_operand" "=r")
6353 (zero_extend:DI
6354 (plus:SI (mult:SI
6355 (match_operand:SI 1 "index_register_operand" "l")
6356 (match_operand:SI 2 "const248_operand" "n"))
6357 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6358 "TARGET_64BIT"
6359 "#"
6360 "&& reload_completed"
6361 [(set (match_dup 0)
6362 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6363 (match_dup 2))
6364 (match_dup 3)) 0)))]
6365 {
6366 operands[1] = gen_lowpart (Pmode, operands[1]);
6367 operands[3] = gen_lowpart (Pmode, operands[3]);
6368 }
6369 [(set_attr "type" "lea")
6370 (set_attr "mode" "SI")])
6371
6372 (define_insn_and_split "*lea_general_3"
6373 [(set (match_operand 0 "register_operand" "=r")
6374 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6375 (match_operand 2 "const248_operand" "i"))
6376 (match_operand 3 "register_operand" "r"))
6377 (match_operand 4 "immediate_operand" "i")))]
6378 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6379 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6380 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6381 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6382 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6383 "#"
6384 "&& reload_completed"
6385 [(const_int 0)]
6386 {
6387 rtx pat;
6388 operands[0] = gen_lowpart (SImode, operands[0]);
6389 operands[1] = gen_lowpart (Pmode, operands[1]);
6390 operands[3] = gen_lowpart (Pmode, operands[3]);
6391 operands[4] = gen_lowpart (Pmode, operands[4]);
6392 pat = gen_rtx_PLUS (Pmode,
6393 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6394 operands[2]),
6395 operands[3]),
6396 operands[4]);
6397 if (Pmode != SImode)
6398 pat = gen_rtx_SUBREG (SImode, pat, 0);
6399 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6400 DONE;
6401 }
6402 [(set_attr "type" "lea")
6403 (set_attr "mode" "SI")])
6404
6405 (define_insn_and_split "*lea_general_3_zext"
6406 [(set (match_operand:DI 0 "register_operand" "=r")
6407 (zero_extend:DI
6408 (plus:SI (plus:SI
6409 (mult:SI
6410 (match_operand:SI 1 "index_register_operand" "l")
6411 (match_operand:SI 2 "const248_operand" "n"))
6412 (match_operand:SI 3 "register_operand" "r"))
6413 (match_operand:SI 4 "immediate_operand" "i"))))]
6414 "TARGET_64BIT"
6415 "#"
6416 "&& reload_completed"
6417 [(set (match_dup 0)
6418 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6419 (match_dup 2))
6420 (match_dup 3))
6421 (match_dup 4)) 0)))]
6422 {
6423 operands[1] = gen_lowpart (Pmode, operands[1]);
6424 operands[3] = gen_lowpart (Pmode, operands[3]);
6425 operands[4] = gen_lowpart (Pmode, operands[4]);
6426 }
6427 [(set_attr "type" "lea")
6428 (set_attr "mode" "SI")])
6429 \f
6430 ;; Subtract instructions
6431
6432 (define_expand "sub<mode>3"
6433 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6434 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6435 (match_operand:SDWIM 2 "<general_operand>" "")))]
6436 ""
6437 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6438
6439 (define_insn_and_split "*sub<dwi>3_doubleword"
6440 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6441 (minus:<DWI>
6442 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6443 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6444 (clobber (reg:CC FLAGS_REG))]
6445 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6446 "#"
6447 "reload_completed"
6448 [(parallel [(set (reg:CC FLAGS_REG)
6449 (compare:CC (match_dup 1) (match_dup 2)))
6450 (set (match_dup 0)
6451 (minus:DWIH (match_dup 1) (match_dup 2)))])
6452 (parallel [(set (match_dup 3)
6453 (minus:DWIH
6454 (match_dup 4)
6455 (plus:DWIH
6456 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6457 (match_dup 5))))
6458 (clobber (reg:CC FLAGS_REG))])]
6459 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6460
6461 (define_insn "*sub<mode>_1"
6462 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6463 (minus:SWI
6464 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6465 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6466 (clobber (reg:CC FLAGS_REG))]
6467 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6468 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6469 [(set_attr "type" "alu")
6470 (set_attr "mode" "<MODE>")])
6471
6472 (define_insn "*subsi_1_zext"
6473 [(set (match_operand:DI 0 "register_operand" "=r")
6474 (zero_extend:DI
6475 (minus:SI (match_operand:SI 1 "register_operand" "0")
6476 (match_operand:SI 2 "general_operand" "g"))))
6477 (clobber (reg:CC FLAGS_REG))]
6478 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6479 "sub{l}\t{%2, %k0|%k0, %2}"
6480 [(set_attr "type" "alu")
6481 (set_attr "mode" "SI")])
6482
6483 (define_insn "*subqi_1_slp"
6484 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6485 (minus:QI (match_dup 0)
6486 (match_operand:QI 1 "general_operand" "qn,qm")))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6489 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6490 "sub{b}\t{%1, %0|%0, %1}"
6491 [(set_attr "type" "alu1")
6492 (set_attr "mode" "QI")])
6493
6494 (define_insn "*sub<mode>_2"
6495 [(set (reg FLAGS_REG)
6496 (compare
6497 (minus:SWI
6498 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6499 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6500 (const_int 0)))
6501 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6502 (minus:SWI (match_dup 1) (match_dup 2)))]
6503 "ix86_match_ccmode (insn, CCGOCmode)
6504 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6505 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "<MODE>")])
6508
6509 (define_insn "*subsi_2_zext"
6510 [(set (reg FLAGS_REG)
6511 (compare
6512 (minus:SI (match_operand:SI 1 "register_operand" "0")
6513 (match_operand:SI 2 "general_operand" "g"))
6514 (const_int 0)))
6515 (set (match_operand:DI 0 "register_operand" "=r")
6516 (zero_extend:DI
6517 (minus:SI (match_dup 1)
6518 (match_dup 2))))]
6519 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6520 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6521 "sub{l}\t{%2, %k0|%k0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "mode" "SI")])
6524
6525 (define_insn "*sub<mode>_3"
6526 [(set (reg FLAGS_REG)
6527 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6528 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6529 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6530 (minus:SWI (match_dup 1) (match_dup 2)))]
6531 "ix86_match_ccmode (insn, CCmode)
6532 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6533 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6534 [(set_attr "type" "alu")
6535 (set_attr "mode" "<MODE>")])
6536
6537 (define_insn "*subsi_3_zext"
6538 [(set (reg FLAGS_REG)
6539 (compare (match_operand:SI 1 "register_operand" "0")
6540 (match_operand:SI 2 "general_operand" "g")))
6541 (set (match_operand:DI 0 "register_operand" "=r")
6542 (zero_extend:DI
6543 (minus:SI (match_dup 1)
6544 (match_dup 2))))]
6545 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6546 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6547 "sub{l}\t{%2, %1|%1, %2}"
6548 [(set_attr "type" "alu")
6549 (set_attr "mode" "SI")])
6550 \f
6551 ;; Add with carry and subtract with borrow
6552
6553 (define_expand "<plusminus_insn><mode>3_carry"
6554 [(parallel
6555 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6556 (plusminus:SWI
6557 (match_operand:SWI 1 "nonimmediate_operand" "")
6558 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6559 [(match_operand 3 "flags_reg_operand" "")
6560 (const_int 0)])
6561 (match_operand:SWI 2 "<general_operand>" ""))))
6562 (clobber (reg:CC FLAGS_REG))])]
6563 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6564
6565 (define_insn "*<plusminus_insn><mode>3_carry"
6566 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6567 (plusminus:SWI
6568 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6569 (plus:SWI
6570 (match_operator 3 "ix86_carry_flag_operator"
6571 [(reg FLAGS_REG) (const_int 0)])
6572 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6573 (clobber (reg:CC FLAGS_REG))]
6574 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6575 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6576 [(set_attr "type" "alu")
6577 (set_attr "use_carry" "1")
6578 (set_attr "pent_pair" "pu")
6579 (set_attr "mode" "<MODE>")])
6580
6581 (define_insn "*addsi3_carry_zext"
6582 [(set (match_operand:DI 0 "register_operand" "=r")
6583 (zero_extend:DI
6584 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6585 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6586 [(reg FLAGS_REG) (const_int 0)])
6587 (match_operand:SI 2 "general_operand" "g")))))
6588 (clobber (reg:CC FLAGS_REG))]
6589 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6590 "adc{l}\t{%2, %k0|%k0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "use_carry" "1")
6593 (set_attr "pent_pair" "pu")
6594 (set_attr "mode" "SI")])
6595
6596 (define_insn "*subsi3_carry_zext"
6597 [(set (match_operand:DI 0 "register_operand" "=r")
6598 (zero_extend:DI
6599 (minus:SI (match_operand:SI 1 "register_operand" "0")
6600 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6601 [(reg FLAGS_REG) (const_int 0)])
6602 (match_operand:SI 2 "general_operand" "g")))))
6603 (clobber (reg:CC FLAGS_REG))]
6604 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6605 "sbb{l}\t{%2, %k0|%k0, %2}"
6606 [(set_attr "type" "alu")
6607 (set_attr "pent_pair" "pu")
6608 (set_attr "mode" "SI")])
6609 \f
6610 ;; Overflow setting add and subtract instructions
6611
6612 (define_insn "*add<mode>3_cconly_overflow"
6613 [(set (reg:CCC FLAGS_REG)
6614 (compare:CCC
6615 (plus:SWI
6616 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6617 (match_operand:SWI 2 "<general_operand>" "<g>"))
6618 (match_dup 1)))
6619 (clobber (match_scratch:SWI 0 "=<r>"))]
6620 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6621 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6622 [(set_attr "type" "alu")
6623 (set_attr "mode" "<MODE>")])
6624
6625 (define_insn "*sub<mode>3_cconly_overflow"
6626 [(set (reg:CCC FLAGS_REG)
6627 (compare:CCC
6628 (minus:SWI
6629 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6630 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6631 (match_dup 0)))]
6632 ""
6633 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6634 [(set_attr "type" "icmp")
6635 (set_attr "mode" "<MODE>")])
6636
6637 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6638 [(set (reg:CCC FLAGS_REG)
6639 (compare:CCC
6640 (plusminus:SWI
6641 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6642 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6643 (match_dup 1)))
6644 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6645 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6646 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6647 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "mode" "<MODE>")])
6650
6651 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6652 [(set (reg:CCC FLAGS_REG)
6653 (compare:CCC
6654 (plusminus:SI
6655 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6656 (match_operand:SI 2 "general_operand" "g"))
6657 (match_dup 1)))
6658 (set (match_operand:DI 0 "register_operand" "=r")
6659 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6660 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6661 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6662 [(set_attr "type" "alu")
6663 (set_attr "mode" "SI")])
6664
6665 ;; The patterns that match these are at the end of this file.
6666
6667 (define_expand "<plusminus_insn>xf3"
6668 [(set (match_operand:XF 0 "register_operand" "")
6669 (plusminus:XF
6670 (match_operand:XF 1 "register_operand" "")
6671 (match_operand:XF 2 "register_operand" "")))]
6672 "TARGET_80387")
6673
6674 (define_expand "<plusminus_insn><mode>3"
6675 [(set (match_operand:MODEF 0 "register_operand" "")
6676 (plusminus:MODEF
6677 (match_operand:MODEF 1 "register_operand" "")
6678 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6679 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6680 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6681 \f
6682 ;; Multiply instructions
6683
6684 (define_expand "mul<mode>3"
6685 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6686 (mult:SWIM248
6687 (match_operand:SWIM248 1 "register_operand" "")
6688 (match_operand:SWIM248 2 "<general_operand>" "")))
6689 (clobber (reg:CC FLAGS_REG))])])
6690
6691 (define_expand "mulqi3"
6692 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6693 (mult:QI
6694 (match_operand:QI 1 "register_operand" "")
6695 (match_operand:QI 2 "nonimmediate_operand" "")))
6696 (clobber (reg:CC FLAGS_REG))])]
6697 "TARGET_QIMODE_MATH")
6698
6699 ;; On AMDFAM10
6700 ;; IMUL reg32/64, reg32/64, imm8 Direct
6701 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6702 ;; IMUL reg32/64, reg32/64, imm32 Direct
6703 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6704 ;; IMUL reg32/64, reg32/64 Direct
6705 ;; IMUL reg32/64, mem32/64 Direct
6706 ;;
6707 ;; On BDVER1, all above IMULs use DirectPath
6708
6709 (define_insn "*mul<mode>3_1"
6710 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6711 (mult:SWI48
6712 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6713 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6714 (clobber (reg:CC FLAGS_REG))]
6715 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6716 "@
6717 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6718 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6719 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6720 [(set_attr "type" "imul")
6721 (set_attr "prefix_0f" "0,0,1")
6722 (set (attr "athlon_decode")
6723 (cond [(eq_attr "cpu" "athlon")
6724 (const_string "vector")
6725 (eq_attr "alternative" "1")
6726 (const_string "vector")
6727 (and (eq_attr "alternative" "2")
6728 (match_operand 1 "memory_operand" ""))
6729 (const_string "vector")]
6730 (const_string "direct")))
6731 (set (attr "amdfam10_decode")
6732 (cond [(and (eq_attr "alternative" "0,1")
6733 (match_operand 1 "memory_operand" ""))
6734 (const_string "vector")]
6735 (const_string "direct")))
6736 (set_attr "bdver1_decode" "direct")
6737 (set_attr "mode" "<MODE>")])
6738
6739 (define_insn "*mulsi3_1_zext"
6740 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6741 (zero_extend:DI
6742 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6743 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6744 (clobber (reg:CC FLAGS_REG))]
6745 "TARGET_64BIT
6746 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6747 "@
6748 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6749 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6750 imul{l}\t{%2, %k0|%k0, %2}"
6751 [(set_attr "type" "imul")
6752 (set_attr "prefix_0f" "0,0,1")
6753 (set (attr "athlon_decode")
6754 (cond [(eq_attr "cpu" "athlon")
6755 (const_string "vector")
6756 (eq_attr "alternative" "1")
6757 (const_string "vector")
6758 (and (eq_attr "alternative" "2")
6759 (match_operand 1 "memory_operand" ""))
6760 (const_string "vector")]
6761 (const_string "direct")))
6762 (set (attr "amdfam10_decode")
6763 (cond [(and (eq_attr "alternative" "0,1")
6764 (match_operand 1 "memory_operand" ""))
6765 (const_string "vector")]
6766 (const_string "direct")))
6767 (set_attr "bdver1_decode" "direct")
6768 (set_attr "mode" "SI")])
6769
6770 ;; On AMDFAM10
6771 ;; IMUL reg16, reg16, imm8 VectorPath
6772 ;; IMUL reg16, mem16, imm8 VectorPath
6773 ;; IMUL reg16, reg16, imm16 VectorPath
6774 ;; IMUL reg16, mem16, imm16 VectorPath
6775 ;; IMUL reg16, reg16 Direct
6776 ;; IMUL reg16, mem16 Direct
6777 ;;
6778 ;; On BDVER1, all HI MULs use DoublePath
6779
6780 (define_insn "*mulhi3_1"
6781 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6782 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6783 (match_operand:HI 2 "general_operand" "K,n,mr")))
6784 (clobber (reg:CC FLAGS_REG))]
6785 "TARGET_HIMODE_MATH
6786 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6787 "@
6788 imul{w}\t{%2, %1, %0|%0, %1, %2}
6789 imul{w}\t{%2, %1, %0|%0, %1, %2}
6790 imul{w}\t{%2, %0|%0, %2}"
6791 [(set_attr "type" "imul")
6792 (set_attr "prefix_0f" "0,0,1")
6793 (set (attr "athlon_decode")
6794 (cond [(eq_attr "cpu" "athlon")
6795 (const_string "vector")
6796 (eq_attr "alternative" "1,2")
6797 (const_string "vector")]
6798 (const_string "direct")))
6799 (set (attr "amdfam10_decode")
6800 (cond [(eq_attr "alternative" "0,1")
6801 (const_string "vector")]
6802 (const_string "direct")))
6803 (set_attr "bdver1_decode" "double")
6804 (set_attr "mode" "HI")])
6805
6806 ;;On AMDFAM10 and BDVER1
6807 ;; MUL reg8 Direct
6808 ;; MUL mem8 Direct
6809
6810 (define_insn "*mulqi3_1"
6811 [(set (match_operand:QI 0 "register_operand" "=a")
6812 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6813 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6814 (clobber (reg:CC FLAGS_REG))]
6815 "TARGET_QIMODE_MATH
6816 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6817 "mul{b}\t%2"
6818 [(set_attr "type" "imul")
6819 (set_attr "length_immediate" "0")
6820 (set (attr "athlon_decode")
6821 (if_then_else (eq_attr "cpu" "athlon")
6822 (const_string "vector")
6823 (const_string "direct")))
6824 (set_attr "amdfam10_decode" "direct")
6825 (set_attr "bdver1_decode" "direct")
6826 (set_attr "mode" "QI")])
6827
6828 (define_expand "<u>mul<mode><dwi>3"
6829 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6830 (mult:<DWI>
6831 (any_extend:<DWI>
6832 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6833 (any_extend:<DWI>
6834 (match_operand:DWIH 2 "register_operand" ""))))
6835 (clobber (reg:CC FLAGS_REG))])])
6836
6837 (define_expand "<u>mulqihi3"
6838 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6839 (mult:HI
6840 (any_extend:HI
6841 (match_operand:QI 1 "nonimmediate_operand" ""))
6842 (any_extend:HI
6843 (match_operand:QI 2 "register_operand" ""))))
6844 (clobber (reg:CC FLAGS_REG))])]
6845 "TARGET_QIMODE_MATH")
6846
6847 (define_insn "*<u>mul<mode><dwi>3_1"
6848 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6849 (mult:<DWI>
6850 (any_extend:<DWI>
6851 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6852 (any_extend:<DWI>
6853 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6854 (clobber (reg:CC FLAGS_REG))]
6855 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 "<sgnprefix>mul{<imodesuffix>}\t%2"
6857 [(set_attr "type" "imul")
6858 (set_attr "length_immediate" "0")
6859 (set (attr "athlon_decode")
6860 (if_then_else (eq_attr "cpu" "athlon")
6861 (const_string "vector")
6862 (const_string "double")))
6863 (set_attr "amdfam10_decode" "double")
6864 (set_attr "bdver1_decode" "direct")
6865 (set_attr "mode" "<MODE>")])
6866
6867 (define_insn "*<u>mulqihi3_1"
6868 [(set (match_operand:HI 0 "register_operand" "=a")
6869 (mult:HI
6870 (any_extend:HI
6871 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6872 (any_extend:HI
6873 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6874 (clobber (reg:CC FLAGS_REG))]
6875 "TARGET_QIMODE_MATH
6876 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6877 "<sgnprefix>mul{b}\t%2"
6878 [(set_attr "type" "imul")
6879 (set_attr "length_immediate" "0")
6880 (set (attr "athlon_decode")
6881 (if_then_else (eq_attr "cpu" "athlon")
6882 (const_string "vector")
6883 (const_string "direct")))
6884 (set_attr "amdfam10_decode" "direct")
6885 (set_attr "bdver1_decode" "direct")
6886 (set_attr "mode" "QI")])
6887
6888 (define_expand "<s>mul<mode>3_highpart"
6889 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6890 (truncate:SWI48
6891 (lshiftrt:<DWI>
6892 (mult:<DWI>
6893 (any_extend:<DWI>
6894 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6895 (any_extend:<DWI>
6896 (match_operand:SWI48 2 "register_operand" "")))
6897 (match_dup 4))))
6898 (clobber (match_scratch:SWI48 3 ""))
6899 (clobber (reg:CC FLAGS_REG))])]
6900 ""
6901 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6902
6903 (define_insn "*<s>muldi3_highpart_1"
6904 [(set (match_operand:DI 0 "register_operand" "=d")
6905 (truncate:DI
6906 (lshiftrt:TI
6907 (mult:TI
6908 (any_extend:TI
6909 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6910 (any_extend:TI
6911 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6912 (const_int 64))))
6913 (clobber (match_scratch:DI 3 "=1"))
6914 (clobber (reg:CC FLAGS_REG))]
6915 "TARGET_64BIT
6916 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917 "<sgnprefix>mul{q}\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" "DI")])
6927
6928 (define_insn "*<s>mulsi3_highpart_1"
6929 [(set (match_operand:SI 0 "register_operand" "=d")
6930 (truncate:SI
6931 (lshiftrt:DI
6932 (mult:DI
6933 (any_extend:DI
6934 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6935 (any_extend:DI
6936 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6937 (const_int 32))))
6938 (clobber (match_scratch:SI 3 "=1"))
6939 (clobber (reg:CC FLAGS_REG))]
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 (define_insn "*<s>mulsi3_highpart_zext"
6953 [(set (match_operand:DI 0 "register_operand" "=d")
6954 (zero_extend:DI (truncate:SI
6955 (lshiftrt:DI
6956 (mult:DI (any_extend:DI
6957 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6958 (any_extend:DI
6959 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6960 (const_int 32)))))
6961 (clobber (match_scratch:SI 3 "=1"))
6962 (clobber (reg:CC FLAGS_REG))]
6963 "TARGET_64BIT
6964 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6965 "<sgnprefix>mul{l}\t%2"
6966 [(set_attr "type" "imul")
6967 (set_attr "length_immediate" "0")
6968 (set (attr "athlon_decode")
6969 (if_then_else (eq_attr "cpu" "athlon")
6970 (const_string "vector")
6971 (const_string "double")))
6972 (set_attr "amdfam10_decode" "double")
6973 (set_attr "bdver1_decode" "direct")
6974 (set_attr "mode" "SI")])
6975
6976 ;; The patterns that match these are at the end of this file.
6977
6978 (define_expand "mulxf3"
6979 [(set (match_operand:XF 0 "register_operand" "")
6980 (mult:XF (match_operand:XF 1 "register_operand" "")
6981 (match_operand:XF 2 "register_operand" "")))]
6982 "TARGET_80387")
6983
6984 (define_expand "mul<mode>3"
6985 [(set (match_operand:MODEF 0 "register_operand" "")
6986 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6987 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6988 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6989 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6990 \f
6991 ;; Divide instructions
6992
6993 ;; The patterns that match these are at the end of this file.
6994
6995 (define_expand "divxf3"
6996 [(set (match_operand:XF 0 "register_operand" "")
6997 (div:XF (match_operand:XF 1 "register_operand" "")
6998 (match_operand:XF 2 "register_operand" "")))]
6999 "TARGET_80387")
7000
7001 (define_expand "divdf3"
7002 [(set (match_operand:DF 0 "register_operand" "")
7003 (div:DF (match_operand:DF 1 "register_operand" "")
7004 (match_operand:DF 2 "nonimmediate_operand" "")))]
7005 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7006 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7007
7008 (define_expand "divsf3"
7009 [(set (match_operand:SF 0 "register_operand" "")
7010 (div:SF (match_operand:SF 1 "register_operand" "")
7011 (match_operand:SF 2 "nonimmediate_operand" "")))]
7012 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7013 || TARGET_SSE_MATH"
7014 {
7015 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7016 && flag_finite_math_only && !flag_trapping_math
7017 && flag_unsafe_math_optimizations)
7018 {
7019 ix86_emit_swdivsf (operands[0], operands[1],
7020 operands[2], SFmode);
7021 DONE;
7022 }
7023 })
7024 \f
7025 ;; Divmod instructions.
7026
7027 (define_expand "divmod<mode>4"
7028 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7029 (div:SWIM248
7030 (match_operand:SWIM248 1 "register_operand" "")
7031 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7032 (set (match_operand:SWIM248 3 "register_operand" "")
7033 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7034 (clobber (reg:CC FLAGS_REG))])])
7035
7036 ;; Split with 8bit unsigned divide:
7037 ;; if (dividend an divisor are in [0-255])
7038 ;; use 8bit unsigned integer divide
7039 ;; else
7040 ;; use original integer divide
7041 (define_split
7042 [(set (match_operand:SWI48 0 "register_operand" "")
7043 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7044 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7045 (set (match_operand:SWI48 1 "register_operand" "")
7046 (mod:SWI48 (match_dup 2) (match_dup 3)))
7047 (clobber (reg:CC FLAGS_REG))]
7048 "TARGET_USE_8BIT_IDIV
7049 && TARGET_QIMODE_MATH
7050 && can_create_pseudo_p ()
7051 && !optimize_insn_for_size_p ()"
7052 [(const_int 0)]
7053 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7054
7055 (define_insn_and_split "divmod<mode>4_1"
7056 [(set (match_operand:SWI48 0 "register_operand" "=a")
7057 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7058 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7059 (set (match_operand:SWI48 1 "register_operand" "=&d")
7060 (mod:SWI48 (match_dup 2) (match_dup 3)))
7061 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7062 (clobber (reg:CC FLAGS_REG))]
7063 ""
7064 "#"
7065 "reload_completed"
7066 [(parallel [(set (match_dup 1)
7067 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7068 (clobber (reg:CC FLAGS_REG))])
7069 (parallel [(set (match_dup 0)
7070 (div:SWI48 (match_dup 2) (match_dup 3)))
7071 (set (match_dup 1)
7072 (mod:SWI48 (match_dup 2) (match_dup 3)))
7073 (use (match_dup 1))
7074 (clobber (reg:CC FLAGS_REG))])]
7075 {
7076 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7077
7078 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7079 operands[4] = operands[2];
7080 else
7081 {
7082 /* Avoid use of cltd in favor of a mov+shift. */
7083 emit_move_insn (operands[1], operands[2]);
7084 operands[4] = operands[1];
7085 }
7086 }
7087 [(set_attr "type" "multi")
7088 (set_attr "mode" "<MODE>")])
7089
7090 (define_insn_and_split "*divmod<mode>4"
7091 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7092 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7093 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7094 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7095 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7096 (clobber (reg:CC FLAGS_REG))]
7097 ""
7098 "#"
7099 "reload_completed"
7100 [(parallel [(set (match_dup 1)
7101 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7102 (clobber (reg:CC FLAGS_REG))])
7103 (parallel [(set (match_dup 0)
7104 (div:SWIM248 (match_dup 2) (match_dup 3)))
7105 (set (match_dup 1)
7106 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7107 (use (match_dup 1))
7108 (clobber (reg:CC FLAGS_REG))])]
7109 {
7110 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7111
7112 if (<MODE>mode != HImode
7113 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7114 operands[4] = operands[2];
7115 else
7116 {
7117 /* Avoid use of cltd in favor of a mov+shift. */
7118 emit_move_insn (operands[1], operands[2]);
7119 operands[4] = operands[1];
7120 }
7121 }
7122 [(set_attr "type" "multi")
7123 (set_attr "mode" "<MODE>")])
7124
7125 (define_insn "*divmod<mode>4_noext"
7126 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7127 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7128 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7129 (set (match_operand:SWIM248 1 "register_operand" "=d")
7130 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7131 (use (match_operand:SWIM248 4 "register_operand" "1"))
7132 (clobber (reg:CC FLAGS_REG))]
7133 ""
7134 "idiv{<imodesuffix>}\t%3"
7135 [(set_attr "type" "idiv")
7136 (set_attr "mode" "<MODE>")])
7137
7138 (define_expand "divmodqi4"
7139 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7140 (div:QI
7141 (match_operand:QI 1 "register_operand" "")
7142 (match_operand:QI 2 "nonimmediate_operand" "")))
7143 (set (match_operand:QI 3 "register_operand" "")
7144 (mod:QI (match_dup 1) (match_dup 2)))
7145 (clobber (reg:CC FLAGS_REG))])]
7146 "TARGET_QIMODE_MATH"
7147 {
7148 rtx div, mod, insn;
7149 rtx tmp0, tmp1;
7150
7151 tmp0 = gen_reg_rtx (HImode);
7152 tmp1 = gen_reg_rtx (HImode);
7153
7154 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7155 in AX. */
7156 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7157 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7158
7159 /* Extract remainder from AH. */
7160 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7161 insn = emit_move_insn (operands[3], tmp1);
7162
7163 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7164 set_unique_reg_note (insn, REG_EQUAL, mod);
7165
7166 /* Extract quotient from AL. */
7167 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7168
7169 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7170 set_unique_reg_note (insn, REG_EQUAL, div);
7171
7172 DONE;
7173 })
7174
7175 ;; Divide AX by r/m8, with result stored in
7176 ;; AL <- Quotient
7177 ;; AH <- Remainder
7178 ;; Change div/mod to HImode and extend the second argument to HImode
7179 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7180 ;; combine may fail.
7181 (define_insn "divmodhiqi3"
7182 [(set (match_operand:HI 0 "register_operand" "=a")
7183 (ior:HI
7184 (ashift:HI
7185 (zero_extend:HI
7186 (truncate:QI
7187 (mod:HI (match_operand:HI 1 "register_operand" "0")
7188 (sign_extend:HI
7189 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7190 (const_int 8))
7191 (zero_extend:HI
7192 (truncate:QI
7193 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7194 (clobber (reg:CC FLAGS_REG))]
7195 "TARGET_QIMODE_MATH"
7196 "idiv{b}\t%2"
7197 [(set_attr "type" "idiv")
7198 (set_attr "mode" "QI")])
7199
7200 (define_expand "udivmod<mode>4"
7201 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7202 (udiv:SWIM248
7203 (match_operand:SWIM248 1 "register_operand" "")
7204 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7205 (set (match_operand:SWIM248 3 "register_operand" "")
7206 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7207 (clobber (reg:CC FLAGS_REG))])])
7208
7209 ;; Split with 8bit unsigned divide:
7210 ;; if (dividend an divisor are in [0-255])
7211 ;; use 8bit unsigned integer divide
7212 ;; else
7213 ;; use original integer divide
7214 (define_split
7215 [(set (match_operand:SWI48 0 "register_operand" "")
7216 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7217 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7218 (set (match_operand:SWI48 1 "register_operand" "")
7219 (umod:SWI48 (match_dup 2) (match_dup 3)))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "TARGET_USE_8BIT_IDIV
7222 && TARGET_QIMODE_MATH
7223 && can_create_pseudo_p ()
7224 && !optimize_insn_for_size_p ()"
7225 [(const_int 0)]
7226 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7227
7228 (define_insn_and_split "udivmod<mode>4_1"
7229 [(set (match_operand:SWI48 0 "register_operand" "=a")
7230 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7231 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7232 (set (match_operand:SWI48 1 "register_operand" "=&d")
7233 (umod:SWI48 (match_dup 2) (match_dup 3)))
7234 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7235 (clobber (reg:CC FLAGS_REG))]
7236 ""
7237 "#"
7238 "reload_completed"
7239 [(set (match_dup 1) (const_int 0))
7240 (parallel [(set (match_dup 0)
7241 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7242 (set (match_dup 1)
7243 (umod:SWI48 (match_dup 2) (match_dup 3)))
7244 (use (match_dup 1))
7245 (clobber (reg:CC FLAGS_REG))])]
7246 ""
7247 [(set_attr "type" "multi")
7248 (set_attr "mode" "<MODE>")])
7249
7250 (define_insn_and_split "*udivmod<mode>4"
7251 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7252 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7253 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7254 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7255 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7256 (clobber (reg:CC FLAGS_REG))]
7257 ""
7258 "#"
7259 "reload_completed"
7260 [(set (match_dup 1) (const_int 0))
7261 (parallel [(set (match_dup 0)
7262 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7263 (set (match_dup 1)
7264 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7265 (use (match_dup 1))
7266 (clobber (reg:CC FLAGS_REG))])]
7267 ""
7268 [(set_attr "type" "multi")
7269 (set_attr "mode" "<MODE>")])
7270
7271 (define_insn "*udivmod<mode>4_noext"
7272 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7273 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7274 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7275 (set (match_operand:SWIM248 1 "register_operand" "=d")
7276 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7277 (use (match_operand:SWIM248 4 "register_operand" "1"))
7278 (clobber (reg:CC FLAGS_REG))]
7279 ""
7280 "div{<imodesuffix>}\t%3"
7281 [(set_attr "type" "idiv")
7282 (set_attr "mode" "<MODE>")])
7283
7284 (define_expand "udivmodqi4"
7285 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7286 (udiv:QI
7287 (match_operand:QI 1 "register_operand" "")
7288 (match_operand:QI 2 "nonimmediate_operand" "")))
7289 (set (match_operand:QI 3 "register_operand" "")
7290 (umod:QI (match_dup 1) (match_dup 2)))
7291 (clobber (reg:CC FLAGS_REG))])]
7292 "TARGET_QIMODE_MATH"
7293 {
7294 rtx div, mod, insn;
7295 rtx tmp0, tmp1;
7296
7297 tmp0 = gen_reg_rtx (HImode);
7298 tmp1 = gen_reg_rtx (HImode);
7299
7300 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7301 in AX. */
7302 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7303 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7304
7305 /* Extract remainder from AH. */
7306 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7307 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7308 insn = emit_move_insn (operands[3], tmp1);
7309
7310 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7311 set_unique_reg_note (insn, REG_EQUAL, mod);
7312
7313 /* Extract quotient from AL. */
7314 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7315
7316 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7317 set_unique_reg_note (insn, REG_EQUAL, div);
7318
7319 DONE;
7320 })
7321
7322 (define_insn "udivmodhiqi3"
7323 [(set (match_operand:HI 0 "register_operand" "=a")
7324 (ior:HI
7325 (ashift:HI
7326 (zero_extend:HI
7327 (truncate:QI
7328 (mod:HI (match_operand:HI 1 "register_operand" "0")
7329 (zero_extend:HI
7330 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7331 (const_int 8))
7332 (zero_extend:HI
7333 (truncate:QI
7334 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7335 (clobber (reg:CC FLAGS_REG))]
7336 "TARGET_QIMODE_MATH"
7337 "div{b}\t%2"
7338 [(set_attr "type" "idiv")
7339 (set_attr "mode" "QI")])
7340
7341 ;; We cannot use div/idiv for double division, because it causes
7342 ;; "division by zero" on the overflow and that's not what we expect
7343 ;; from truncate. Because true (non truncating) double division is
7344 ;; never generated, we can't create this insn anyway.
7345 ;
7346 ;(define_insn ""
7347 ; [(set (match_operand:SI 0 "register_operand" "=a")
7348 ; (truncate:SI
7349 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7350 ; (zero_extend:DI
7351 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7352 ; (set (match_operand:SI 3 "register_operand" "=d")
7353 ; (truncate:SI
7354 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7355 ; (clobber (reg:CC FLAGS_REG))]
7356 ; ""
7357 ; "div{l}\t{%2, %0|%0, %2}"
7358 ; [(set_attr "type" "idiv")])
7359 \f
7360 ;;- Logical AND instructions
7361
7362 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7363 ;; Note that this excludes ah.
7364
7365 (define_expand "testsi_ccno_1"
7366 [(set (reg:CCNO FLAGS_REG)
7367 (compare:CCNO
7368 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7369 (match_operand:SI 1 "nonmemory_operand" ""))
7370 (const_int 0)))])
7371
7372 (define_expand "testqi_ccz_1"
7373 [(set (reg:CCZ FLAGS_REG)
7374 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7375 (match_operand:QI 1 "nonmemory_operand" ""))
7376 (const_int 0)))])
7377
7378 (define_expand "testdi_ccno_1"
7379 [(set (reg:CCNO FLAGS_REG)
7380 (compare:CCNO
7381 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7382 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7383 (const_int 0)))]
7384 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7385
7386 (define_insn "*testdi_1"
7387 [(set (reg FLAGS_REG)
7388 (compare
7389 (and:DI
7390 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7391 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7392 (const_int 0)))]
7393 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7394 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7395 "@
7396 test{l}\t{%k1, %k0|%k0, %k1}
7397 test{l}\t{%k1, %k0|%k0, %k1}
7398 test{q}\t{%1, %0|%0, %1}
7399 test{q}\t{%1, %0|%0, %1}
7400 test{q}\t{%1, %0|%0, %1}"
7401 [(set_attr "type" "test")
7402 (set_attr "modrm" "0,1,0,1,1")
7403 (set_attr "mode" "SI,SI,DI,DI,DI")])
7404
7405 (define_insn "*testqi_1_maybe_si"
7406 [(set (reg FLAGS_REG)
7407 (compare
7408 (and:QI
7409 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7410 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7411 (const_int 0)))]
7412 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7413 && ix86_match_ccmode (insn,
7414 CONST_INT_P (operands[1])
7415 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7416 {
7417 if (which_alternative == 3)
7418 {
7419 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7420 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7421 return "test{l}\t{%1, %k0|%k0, %1}";
7422 }
7423 return "test{b}\t{%1, %0|%0, %1}";
7424 }
7425 [(set_attr "type" "test")
7426 (set_attr "modrm" "0,1,1,1")
7427 (set_attr "mode" "QI,QI,QI,SI")
7428 (set_attr "pent_pair" "uv,np,uv,np")])
7429
7430 (define_insn "*test<mode>_1"
7431 [(set (reg FLAGS_REG)
7432 (compare
7433 (and:SWI124
7434 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7435 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7436 (const_int 0)))]
7437 "ix86_match_ccmode (insn, CCNOmode)
7438 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7439 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7440 [(set_attr "type" "test")
7441 (set_attr "modrm" "0,1,1")
7442 (set_attr "mode" "<MODE>")
7443 (set_attr "pent_pair" "uv,np,uv")])
7444
7445 (define_expand "testqi_ext_ccno_0"
7446 [(set (reg:CCNO FLAGS_REG)
7447 (compare:CCNO
7448 (and:SI
7449 (zero_extract:SI
7450 (match_operand 0 "ext_register_operand" "")
7451 (const_int 8)
7452 (const_int 8))
7453 (match_operand 1 "const_int_operand" ""))
7454 (const_int 0)))])
7455
7456 (define_insn "*testqi_ext_0"
7457 [(set (reg FLAGS_REG)
7458 (compare
7459 (and:SI
7460 (zero_extract:SI
7461 (match_operand 0 "ext_register_operand" "Q")
7462 (const_int 8)
7463 (const_int 8))
7464 (match_operand 1 "const_int_operand" "n"))
7465 (const_int 0)))]
7466 "ix86_match_ccmode (insn, CCNOmode)"
7467 "test{b}\t{%1, %h0|%h0, %1}"
7468 [(set_attr "type" "test")
7469 (set_attr "mode" "QI")
7470 (set_attr "length_immediate" "1")
7471 (set_attr "modrm" "1")
7472 (set_attr "pent_pair" "np")])
7473
7474 (define_insn "*testqi_ext_1_rex64"
7475 [(set (reg FLAGS_REG)
7476 (compare
7477 (and:SI
7478 (zero_extract:SI
7479 (match_operand 0 "ext_register_operand" "Q")
7480 (const_int 8)
7481 (const_int 8))
7482 (zero_extend:SI
7483 (match_operand:QI 1 "register_operand" "Q")))
7484 (const_int 0)))]
7485 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7486 "test{b}\t{%1, %h0|%h0, %1}"
7487 [(set_attr "type" "test")
7488 (set_attr "mode" "QI")])
7489
7490 (define_insn "*testqi_ext_1"
7491 [(set (reg FLAGS_REG)
7492 (compare
7493 (and:SI
7494 (zero_extract:SI
7495 (match_operand 0 "ext_register_operand" "Q")
7496 (const_int 8)
7497 (const_int 8))
7498 (zero_extend:SI
7499 (match_operand:QI 1 "general_operand" "Qm")))
7500 (const_int 0)))]
7501 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7502 "test{b}\t{%1, %h0|%h0, %1}"
7503 [(set_attr "type" "test")
7504 (set_attr "mode" "QI")])
7505
7506 (define_insn "*testqi_ext_2"
7507 [(set (reg FLAGS_REG)
7508 (compare
7509 (and:SI
7510 (zero_extract:SI
7511 (match_operand 0 "ext_register_operand" "Q")
7512 (const_int 8)
7513 (const_int 8))
7514 (zero_extract:SI
7515 (match_operand 1 "ext_register_operand" "Q")
7516 (const_int 8)
7517 (const_int 8)))
7518 (const_int 0)))]
7519 "ix86_match_ccmode (insn, CCNOmode)"
7520 "test{b}\t{%h1, %h0|%h0, %h1}"
7521 [(set_attr "type" "test")
7522 (set_attr "mode" "QI")])
7523
7524 (define_insn "*testqi_ext_3_rex64"
7525 [(set (reg FLAGS_REG)
7526 (compare (zero_extract:DI
7527 (match_operand 0 "nonimmediate_operand" "rm")
7528 (match_operand:DI 1 "const_int_operand" "")
7529 (match_operand:DI 2 "const_int_operand" ""))
7530 (const_int 0)))]
7531 "TARGET_64BIT
7532 && ix86_match_ccmode (insn, CCNOmode)
7533 && INTVAL (operands[1]) > 0
7534 && INTVAL (operands[2]) >= 0
7535 /* Ensure that resulting mask is zero or sign extended operand. */
7536 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7537 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7538 && INTVAL (operands[1]) > 32))
7539 && (GET_MODE (operands[0]) == SImode
7540 || GET_MODE (operands[0]) == DImode
7541 || GET_MODE (operands[0]) == HImode
7542 || GET_MODE (operands[0]) == QImode)"
7543 "#")
7544
7545 ;; Combine likes to form bit extractions for some tests. Humor it.
7546 (define_insn "*testqi_ext_3"
7547 [(set (reg FLAGS_REG)
7548 (compare (zero_extract:SI
7549 (match_operand 0 "nonimmediate_operand" "rm")
7550 (match_operand:SI 1 "const_int_operand" "")
7551 (match_operand:SI 2 "const_int_operand" ""))
7552 (const_int 0)))]
7553 "ix86_match_ccmode (insn, CCNOmode)
7554 && INTVAL (operands[1]) > 0
7555 && INTVAL (operands[2]) >= 0
7556 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7557 && (GET_MODE (operands[0]) == SImode
7558 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7559 || GET_MODE (operands[0]) == HImode
7560 || GET_MODE (operands[0]) == QImode)"
7561 "#")
7562
7563 (define_split
7564 [(set (match_operand 0 "flags_reg_operand" "")
7565 (match_operator 1 "compare_operator"
7566 [(zero_extract
7567 (match_operand 2 "nonimmediate_operand" "")
7568 (match_operand 3 "const_int_operand" "")
7569 (match_operand 4 "const_int_operand" ""))
7570 (const_int 0)]))]
7571 "ix86_match_ccmode (insn, CCNOmode)"
7572 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7573 {
7574 rtx val = operands[2];
7575 HOST_WIDE_INT len = INTVAL (operands[3]);
7576 HOST_WIDE_INT pos = INTVAL (operands[4]);
7577 HOST_WIDE_INT mask;
7578 enum machine_mode mode, submode;
7579
7580 mode = GET_MODE (val);
7581 if (MEM_P (val))
7582 {
7583 /* ??? Combine likes to put non-volatile mem extractions in QImode
7584 no matter the size of the test. So find a mode that works. */
7585 if (! MEM_VOLATILE_P (val))
7586 {
7587 mode = smallest_mode_for_size (pos + len, MODE_INT);
7588 val = adjust_address (val, mode, 0);
7589 }
7590 }
7591 else if (GET_CODE (val) == SUBREG
7592 && (submode = GET_MODE (SUBREG_REG (val)),
7593 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7594 && pos + len <= GET_MODE_BITSIZE (submode)
7595 && GET_MODE_CLASS (submode) == MODE_INT)
7596 {
7597 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7598 mode = submode;
7599 val = SUBREG_REG (val);
7600 }
7601 else if (mode == HImode && pos + len <= 8)
7602 {
7603 /* Small HImode tests can be converted to QImode. */
7604 mode = QImode;
7605 val = gen_lowpart (QImode, val);
7606 }
7607
7608 if (len == HOST_BITS_PER_WIDE_INT)
7609 mask = -1;
7610 else
7611 mask = ((HOST_WIDE_INT)1 << len) - 1;
7612 mask <<= pos;
7613
7614 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7615 })
7616
7617 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7618 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7619 ;; this is relatively important trick.
7620 ;; Do the conversion only post-reload to avoid limiting of the register class
7621 ;; to QI regs.
7622 (define_split
7623 [(set (match_operand 0 "flags_reg_operand" "")
7624 (match_operator 1 "compare_operator"
7625 [(and (match_operand 2 "register_operand" "")
7626 (match_operand 3 "const_int_operand" ""))
7627 (const_int 0)]))]
7628 "reload_completed
7629 && QI_REG_P (operands[2])
7630 && GET_MODE (operands[2]) != QImode
7631 && ((ix86_match_ccmode (insn, CCZmode)
7632 && !(INTVAL (operands[3]) & ~(255 << 8)))
7633 || (ix86_match_ccmode (insn, CCNOmode)
7634 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7635 [(set (match_dup 0)
7636 (match_op_dup 1
7637 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7638 (match_dup 3))
7639 (const_int 0)]))]
7640 "operands[2] = gen_lowpart (SImode, operands[2]);
7641 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7642
7643 (define_split
7644 [(set (match_operand 0 "flags_reg_operand" "")
7645 (match_operator 1 "compare_operator"
7646 [(and (match_operand 2 "nonimmediate_operand" "")
7647 (match_operand 3 "const_int_operand" ""))
7648 (const_int 0)]))]
7649 "reload_completed
7650 && GET_MODE (operands[2]) != QImode
7651 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7652 && ((ix86_match_ccmode (insn, CCZmode)
7653 && !(INTVAL (operands[3]) & ~255))
7654 || (ix86_match_ccmode (insn, CCNOmode)
7655 && !(INTVAL (operands[3]) & ~127)))"
7656 [(set (match_dup 0)
7657 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7658 (const_int 0)]))]
7659 "operands[2] = gen_lowpart (QImode, operands[2]);
7660 operands[3] = gen_lowpart (QImode, operands[3]);")
7661
7662 ;; %%% This used to optimize known byte-wide and operations to memory,
7663 ;; and sometimes to QImode registers. If this is considered useful,
7664 ;; it should be done with splitters.
7665
7666 (define_expand "and<mode>3"
7667 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7668 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7669 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7670 ""
7671 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7672
7673 (define_insn "*anddi_1"
7674 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7675 (and:DI
7676 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7677 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7678 (clobber (reg:CC FLAGS_REG))]
7679 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7680 {
7681 switch (get_attr_type (insn))
7682 {
7683 case TYPE_IMOVX:
7684 {
7685 enum machine_mode mode;
7686
7687 gcc_assert (CONST_INT_P (operands[2]));
7688 if (INTVAL (operands[2]) == 0xff)
7689 mode = QImode;
7690 else
7691 {
7692 gcc_assert (INTVAL (operands[2]) == 0xffff);
7693 mode = HImode;
7694 }
7695
7696 operands[1] = gen_lowpart (mode, operands[1]);
7697 if (mode == QImode)
7698 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7699 else
7700 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7701 }
7702
7703 default:
7704 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7705 if (get_attr_mode (insn) == MODE_SI)
7706 return "and{l}\t{%k2, %k0|%k0, %k2}";
7707 else
7708 return "and{q}\t{%2, %0|%0, %2}";
7709 }
7710 }
7711 [(set_attr "type" "alu,alu,alu,imovx")
7712 (set_attr "length_immediate" "*,*,*,0")
7713 (set (attr "prefix_rex")
7714 (if_then_else
7715 (and (eq_attr "type" "imovx")
7716 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7717 (match_operand 1 "ext_QIreg_operand" "")))
7718 (const_string "1")
7719 (const_string "*")))
7720 (set_attr "mode" "SI,DI,DI,SI")])
7721
7722 (define_insn "*andsi_1"
7723 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7724 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7725 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7726 (clobber (reg:CC FLAGS_REG))]
7727 "ix86_binary_operator_ok (AND, SImode, operands)"
7728 {
7729 switch (get_attr_type (insn))
7730 {
7731 case TYPE_IMOVX:
7732 {
7733 enum machine_mode mode;
7734
7735 gcc_assert (CONST_INT_P (operands[2]));
7736 if (INTVAL (operands[2]) == 0xff)
7737 mode = QImode;
7738 else
7739 {
7740 gcc_assert (INTVAL (operands[2]) == 0xffff);
7741 mode = HImode;
7742 }
7743
7744 operands[1] = gen_lowpart (mode, operands[1]);
7745 if (mode == QImode)
7746 return "movz{bl|x}\t{%1, %0|%0, %1}";
7747 else
7748 return "movz{wl|x}\t{%1, %0|%0, %1}";
7749 }
7750
7751 default:
7752 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7753 return "and{l}\t{%2, %0|%0, %2}";
7754 }
7755 }
7756 [(set_attr "type" "alu,alu,imovx")
7757 (set (attr "prefix_rex")
7758 (if_then_else
7759 (and (eq_attr "type" "imovx")
7760 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7761 (match_operand 1 "ext_QIreg_operand" "")))
7762 (const_string "1")
7763 (const_string "*")))
7764 (set_attr "length_immediate" "*,*,0")
7765 (set_attr "mode" "SI")])
7766
7767 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7768 (define_insn "*andsi_1_zext"
7769 [(set (match_operand:DI 0 "register_operand" "=r")
7770 (zero_extend:DI
7771 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7772 (match_operand:SI 2 "general_operand" "g"))))
7773 (clobber (reg:CC FLAGS_REG))]
7774 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7775 "and{l}\t{%2, %k0|%k0, %2}"
7776 [(set_attr "type" "alu")
7777 (set_attr "mode" "SI")])
7778
7779 (define_insn "*andhi_1"
7780 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7781 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7782 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7783 (clobber (reg:CC FLAGS_REG))]
7784 "ix86_binary_operator_ok (AND, HImode, operands)"
7785 {
7786 switch (get_attr_type (insn))
7787 {
7788 case TYPE_IMOVX:
7789 gcc_assert (CONST_INT_P (operands[2]));
7790 gcc_assert (INTVAL (operands[2]) == 0xff);
7791 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7792
7793 default:
7794 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7795
7796 return "and{w}\t{%2, %0|%0, %2}";
7797 }
7798 }
7799 [(set_attr "type" "alu,alu,imovx")
7800 (set_attr "length_immediate" "*,*,0")
7801 (set (attr "prefix_rex")
7802 (if_then_else
7803 (and (eq_attr "type" "imovx")
7804 (match_operand 1 "ext_QIreg_operand" ""))
7805 (const_string "1")
7806 (const_string "*")))
7807 (set_attr "mode" "HI,HI,SI")])
7808
7809 ;; %%% Potential partial reg stall on alternative 2. What to do?
7810 (define_insn "*andqi_1"
7811 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7812 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7813 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7814 (clobber (reg:CC FLAGS_REG))]
7815 "ix86_binary_operator_ok (AND, QImode, operands)"
7816 "@
7817 and{b}\t{%2, %0|%0, %2}
7818 and{b}\t{%2, %0|%0, %2}
7819 and{l}\t{%k2, %k0|%k0, %k2}"
7820 [(set_attr "type" "alu")
7821 (set_attr "mode" "QI,QI,SI")])
7822
7823 (define_insn "*andqi_1_slp"
7824 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7825 (and:QI (match_dup 0)
7826 (match_operand:QI 1 "general_operand" "qn,qmn")))
7827 (clobber (reg:CC FLAGS_REG))]
7828 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7829 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7830 "and{b}\t{%1, %0|%0, %1}"
7831 [(set_attr "type" "alu1")
7832 (set_attr "mode" "QI")])
7833
7834 (define_split
7835 [(set (match_operand 0 "register_operand" "")
7836 (and (match_dup 0)
7837 (const_int -65536)))
7838 (clobber (reg:CC FLAGS_REG))]
7839 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7840 || optimize_function_for_size_p (cfun)"
7841 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7842 "operands[1] = gen_lowpart (HImode, operands[0]);")
7843
7844 (define_split
7845 [(set (match_operand 0 "ext_register_operand" "")
7846 (and (match_dup 0)
7847 (const_int -256)))
7848 (clobber (reg:CC FLAGS_REG))]
7849 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7850 && reload_completed"
7851 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7852 "operands[1] = gen_lowpart (QImode, operands[0]);")
7853
7854 (define_split
7855 [(set (match_operand 0 "ext_register_operand" "")
7856 (and (match_dup 0)
7857 (const_int -65281)))
7858 (clobber (reg:CC FLAGS_REG))]
7859 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7860 && reload_completed"
7861 [(parallel [(set (zero_extract:SI (match_dup 0)
7862 (const_int 8)
7863 (const_int 8))
7864 (xor:SI
7865 (zero_extract:SI (match_dup 0)
7866 (const_int 8)
7867 (const_int 8))
7868 (zero_extract:SI (match_dup 0)
7869 (const_int 8)
7870 (const_int 8))))
7871 (clobber (reg:CC FLAGS_REG))])]
7872 "operands[0] = gen_lowpart (SImode, operands[0]);")
7873
7874 (define_insn "*anddi_2"
7875 [(set (reg FLAGS_REG)
7876 (compare
7877 (and:DI
7878 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7879 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7880 (const_int 0)))
7881 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7882 (and:DI (match_dup 1) (match_dup 2)))]
7883 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7884 && ix86_binary_operator_ok (AND, DImode, operands)"
7885 "@
7886 and{l}\t{%k2, %k0|%k0, %k2}
7887 and{q}\t{%2, %0|%0, %2}
7888 and{q}\t{%2, %0|%0, %2}"
7889 [(set_attr "type" "alu")
7890 (set_attr "mode" "SI,DI,DI")])
7891
7892 (define_insn "*andqi_2_maybe_si"
7893 [(set (reg FLAGS_REG)
7894 (compare (and:QI
7895 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7896 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7897 (const_int 0)))
7898 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7899 (and:QI (match_dup 1) (match_dup 2)))]
7900 "ix86_binary_operator_ok (AND, QImode, operands)
7901 && ix86_match_ccmode (insn,
7902 CONST_INT_P (operands[2])
7903 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7904 {
7905 if (which_alternative == 2)
7906 {
7907 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7908 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7909 return "and{l}\t{%2, %k0|%k0, %2}";
7910 }
7911 return "and{b}\t{%2, %0|%0, %2}";
7912 }
7913 [(set_attr "type" "alu")
7914 (set_attr "mode" "QI,QI,SI")])
7915
7916 (define_insn "*and<mode>_2"
7917 [(set (reg FLAGS_REG)
7918 (compare (and:SWI124
7919 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7920 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7921 (const_int 0)))
7922 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7923 (and:SWI124 (match_dup 1) (match_dup 2)))]
7924 "ix86_match_ccmode (insn, CCNOmode)
7925 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7926 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7927 [(set_attr "type" "alu")
7928 (set_attr "mode" "<MODE>")])
7929
7930 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7931 (define_insn "*andsi_2_zext"
7932 [(set (reg FLAGS_REG)
7933 (compare (and:SI
7934 (match_operand:SI 1 "nonimmediate_operand" "%0")
7935 (match_operand:SI 2 "general_operand" "g"))
7936 (const_int 0)))
7937 (set (match_operand:DI 0 "register_operand" "=r")
7938 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7939 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7940 && ix86_binary_operator_ok (AND, SImode, operands)"
7941 "and{l}\t{%2, %k0|%k0, %2}"
7942 [(set_attr "type" "alu")
7943 (set_attr "mode" "SI")])
7944
7945 (define_insn "*andqi_2_slp"
7946 [(set (reg FLAGS_REG)
7947 (compare (and:QI
7948 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7949 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7950 (const_int 0)))
7951 (set (strict_low_part (match_dup 0))
7952 (and:QI (match_dup 0) (match_dup 1)))]
7953 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7954 && ix86_match_ccmode (insn, CCNOmode)
7955 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7956 "and{b}\t{%1, %0|%0, %1}"
7957 [(set_attr "type" "alu1")
7958 (set_attr "mode" "QI")])
7959
7960 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7961 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7962 ;; for a QImode operand, which of course failed.
7963 (define_insn "andqi_ext_0"
7964 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7965 (const_int 8)
7966 (const_int 8))
7967 (and:SI
7968 (zero_extract:SI
7969 (match_operand 1 "ext_register_operand" "0")
7970 (const_int 8)
7971 (const_int 8))
7972 (match_operand 2 "const_int_operand" "n")))
7973 (clobber (reg:CC FLAGS_REG))]
7974 ""
7975 "and{b}\t{%2, %h0|%h0, %2}"
7976 [(set_attr "type" "alu")
7977 (set_attr "length_immediate" "1")
7978 (set_attr "modrm" "1")
7979 (set_attr "mode" "QI")])
7980
7981 ;; Generated by peephole translating test to and. This shows up
7982 ;; often in fp comparisons.
7983 (define_insn "*andqi_ext_0_cc"
7984 [(set (reg FLAGS_REG)
7985 (compare
7986 (and:SI
7987 (zero_extract:SI
7988 (match_operand 1 "ext_register_operand" "0")
7989 (const_int 8)
7990 (const_int 8))
7991 (match_operand 2 "const_int_operand" "n"))
7992 (const_int 0)))
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_dup 1)
7999 (const_int 8)
8000 (const_int 8))
8001 (match_dup 2)))]
8002 "ix86_match_ccmode (insn, CCNOmode)"
8003 "and{b}\t{%2, %h0|%h0, %2}"
8004 [(set_attr "type" "alu")
8005 (set_attr "length_immediate" "1")
8006 (set_attr "modrm" "1")
8007 (set_attr "mode" "QI")])
8008
8009 (define_insn "*andqi_ext_1_rex64"
8010 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8011 (const_int 8)
8012 (const_int 8))
8013 (and:SI
8014 (zero_extract:SI
8015 (match_operand 1 "ext_register_operand" "0")
8016 (const_int 8)
8017 (const_int 8))
8018 (zero_extend:SI
8019 (match_operand 2 "ext_register_operand" "Q"))))
8020 (clobber (reg:CC FLAGS_REG))]
8021 "TARGET_64BIT"
8022 "and{b}\t{%2, %h0|%h0, %2}"
8023 [(set_attr "type" "alu")
8024 (set_attr "length_immediate" "0")
8025 (set_attr "mode" "QI")])
8026
8027 (define_insn "*andqi_ext_1"
8028 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8029 (const_int 8)
8030 (const_int 8))
8031 (and:SI
8032 (zero_extract:SI
8033 (match_operand 1 "ext_register_operand" "0")
8034 (const_int 8)
8035 (const_int 8))
8036 (zero_extend:SI
8037 (match_operand:QI 2 "general_operand" "Qm"))))
8038 (clobber (reg:CC FLAGS_REG))]
8039 "!TARGET_64BIT"
8040 "and{b}\t{%2, %h0|%h0, %2}"
8041 [(set_attr "type" "alu")
8042 (set_attr "length_immediate" "0")
8043 (set_attr "mode" "QI")])
8044
8045 (define_insn "*andqi_ext_2"
8046 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8047 (const_int 8)
8048 (const_int 8))
8049 (and:SI
8050 (zero_extract:SI
8051 (match_operand 1 "ext_register_operand" "%0")
8052 (const_int 8)
8053 (const_int 8))
8054 (zero_extract:SI
8055 (match_operand 2 "ext_register_operand" "Q")
8056 (const_int 8)
8057 (const_int 8))))
8058 (clobber (reg:CC FLAGS_REG))]
8059 ""
8060 "and{b}\t{%h2, %h0|%h0, %h2}"
8061 [(set_attr "type" "alu")
8062 (set_attr "length_immediate" "0")
8063 (set_attr "mode" "QI")])
8064
8065 ;; Convert wide AND instructions with immediate operand to shorter QImode
8066 ;; equivalents when possible.
8067 ;; Don't do the splitting with memory operands, since it introduces risk
8068 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8069 ;; for size, but that can (should?) be handled by generic code instead.
8070 (define_split
8071 [(set (match_operand 0 "register_operand" "")
8072 (and (match_operand 1 "register_operand" "")
8073 (match_operand 2 "const_int_operand" "")))
8074 (clobber (reg:CC FLAGS_REG))]
8075 "reload_completed
8076 && QI_REG_P (operands[0])
8077 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078 && !(~INTVAL (operands[2]) & ~(255 << 8))
8079 && GET_MODE (operands[0]) != QImode"
8080 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8081 (and:SI (zero_extract:SI (match_dup 1)
8082 (const_int 8) (const_int 8))
8083 (match_dup 2)))
8084 (clobber (reg:CC FLAGS_REG))])]
8085 "operands[0] = gen_lowpart (SImode, operands[0]);
8086 operands[1] = gen_lowpart (SImode, operands[1]);
8087 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8088
8089 ;; Since AND can be encoded with sign extended immediate, this is only
8090 ;; profitable when 7th bit is not set.
8091 (define_split
8092 [(set (match_operand 0 "register_operand" "")
8093 (and (match_operand 1 "general_operand" "")
8094 (match_operand 2 "const_int_operand" "")))
8095 (clobber (reg:CC FLAGS_REG))]
8096 "reload_completed
8097 && ANY_QI_REG_P (operands[0])
8098 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8099 && !(~INTVAL (operands[2]) & ~255)
8100 && !(INTVAL (operands[2]) & 128)
8101 && GET_MODE (operands[0]) != QImode"
8102 [(parallel [(set (strict_low_part (match_dup 0))
8103 (and:QI (match_dup 1)
8104 (match_dup 2)))
8105 (clobber (reg:CC FLAGS_REG))])]
8106 "operands[0] = gen_lowpart (QImode, operands[0]);
8107 operands[1] = gen_lowpart (QImode, operands[1]);
8108 operands[2] = gen_lowpart (QImode, operands[2]);")
8109 \f
8110 ;; Logical inclusive and exclusive OR instructions
8111
8112 ;; %%% This used to optimize known byte-wide and operations to memory.
8113 ;; If this is considered useful, it should be done with splitters.
8114
8115 (define_expand "<code><mode>3"
8116 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8117 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8118 (match_operand:SWIM 2 "<general_operand>" "")))]
8119 ""
8120 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8121
8122 (define_insn "*<code><mode>_1"
8123 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8124 (any_or:SWI248
8125 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8126 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8127 (clobber (reg:CC FLAGS_REG))]
8128 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8129 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8130 [(set_attr "type" "alu")
8131 (set_attr "mode" "<MODE>")])
8132
8133 ;; %%% Potential partial reg stall on alternative 2. What to do?
8134 (define_insn "*<code>qi_1"
8135 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8136 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8137 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8138 (clobber (reg:CC FLAGS_REG))]
8139 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8140 "@
8141 <logic>{b}\t{%2, %0|%0, %2}
8142 <logic>{b}\t{%2, %0|%0, %2}
8143 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8144 [(set_attr "type" "alu")
8145 (set_attr "mode" "QI,QI,SI")])
8146
8147 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8148 (define_insn "*<code>si_1_zext"
8149 [(set (match_operand:DI 0 "register_operand" "=r")
8150 (zero_extend:DI
8151 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8152 (match_operand:SI 2 "general_operand" "g"))))
8153 (clobber (reg:CC FLAGS_REG))]
8154 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8155 "<logic>{l}\t{%2, %k0|%k0, %2}"
8156 [(set_attr "type" "alu")
8157 (set_attr "mode" "SI")])
8158
8159 (define_insn "*<code>si_1_zext_imm"
8160 [(set (match_operand:DI 0 "register_operand" "=r")
8161 (any_or:DI
8162 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8163 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8164 (clobber (reg:CC FLAGS_REG))]
8165 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8166 "<logic>{l}\t{%2, %k0|%k0, %2}"
8167 [(set_attr "type" "alu")
8168 (set_attr "mode" "SI")])
8169
8170 (define_insn "*<code>qi_1_slp"
8171 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8172 (any_or:QI (match_dup 0)
8173 (match_operand:QI 1 "general_operand" "qmn,qn")))
8174 (clobber (reg:CC FLAGS_REG))]
8175 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8176 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8177 "<logic>{b}\t{%1, %0|%0, %1}"
8178 [(set_attr "type" "alu1")
8179 (set_attr "mode" "QI")])
8180
8181 (define_insn "*<code><mode>_2"
8182 [(set (reg FLAGS_REG)
8183 (compare (any_or:SWI
8184 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8185 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8186 (const_int 0)))
8187 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8188 (any_or:SWI (match_dup 1) (match_dup 2)))]
8189 "ix86_match_ccmode (insn, CCNOmode)
8190 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8191 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8192 [(set_attr "type" "alu")
8193 (set_attr "mode" "<MODE>")])
8194
8195 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8196 ;; ??? Special case for immediate operand is missing - it is tricky.
8197 (define_insn "*<code>si_2_zext"
8198 [(set (reg FLAGS_REG)
8199 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8200 (match_operand:SI 2 "general_operand" "g"))
8201 (const_int 0)))
8202 (set (match_operand:DI 0 "register_operand" "=r")
8203 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8204 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8205 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8206 "<logic>{l}\t{%2, %k0|%k0, %2}"
8207 [(set_attr "type" "alu")
8208 (set_attr "mode" "SI")])
8209
8210 (define_insn "*<code>si_2_zext_imm"
8211 [(set (reg FLAGS_REG)
8212 (compare (any_or:SI
8213 (match_operand:SI 1 "nonimmediate_operand" "%0")
8214 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8215 (const_int 0)))
8216 (set (match_operand:DI 0 "register_operand" "=r")
8217 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8218 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8219 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8220 "<logic>{l}\t{%2, %k0|%k0, %2}"
8221 [(set_attr "type" "alu")
8222 (set_attr "mode" "SI")])
8223
8224 (define_insn "*<code>qi_2_slp"
8225 [(set (reg FLAGS_REG)
8226 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8227 (match_operand:QI 1 "general_operand" "qmn,qn"))
8228 (const_int 0)))
8229 (set (strict_low_part (match_dup 0))
8230 (any_or:QI (match_dup 0) (match_dup 1)))]
8231 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232 && ix86_match_ccmode (insn, CCNOmode)
8233 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8234 "<logic>{b}\t{%1, %0|%0, %1}"
8235 [(set_attr "type" "alu1")
8236 (set_attr "mode" "QI")])
8237
8238 (define_insn "*<code><mode>_3"
8239 [(set (reg FLAGS_REG)
8240 (compare (any_or:SWI
8241 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8242 (match_operand:SWI 2 "<general_operand>" "<g>"))
8243 (const_int 0)))
8244 (clobber (match_scratch:SWI 0 "=<r>"))]
8245 "ix86_match_ccmode (insn, CCNOmode)
8246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8247 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8248 [(set_attr "type" "alu")
8249 (set_attr "mode" "<MODE>")])
8250
8251 (define_insn "*<code>qi_ext_0"
8252 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8253 (const_int 8)
8254 (const_int 8))
8255 (any_or:SI
8256 (zero_extract:SI
8257 (match_operand 1 "ext_register_operand" "0")
8258 (const_int 8)
8259 (const_int 8))
8260 (match_operand 2 "const_int_operand" "n")))
8261 (clobber (reg:CC FLAGS_REG))]
8262 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8263 "<logic>{b}\t{%2, %h0|%h0, %2}"
8264 [(set_attr "type" "alu")
8265 (set_attr "length_immediate" "1")
8266 (set_attr "modrm" "1")
8267 (set_attr "mode" "QI")])
8268
8269 (define_insn "*<code>qi_ext_1_rex64"
8270 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8271 (const_int 8)
8272 (const_int 8))
8273 (any_or:SI
8274 (zero_extract:SI
8275 (match_operand 1 "ext_register_operand" "0")
8276 (const_int 8)
8277 (const_int 8))
8278 (zero_extend:SI
8279 (match_operand 2 "ext_register_operand" "Q"))))
8280 (clobber (reg:CC FLAGS_REG))]
8281 "TARGET_64BIT
8282 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8283 "<logic>{b}\t{%2, %h0|%h0, %2}"
8284 [(set_attr "type" "alu")
8285 (set_attr "length_immediate" "0")
8286 (set_attr "mode" "QI")])
8287
8288 (define_insn "*<code>qi_ext_1"
8289 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8290 (const_int 8)
8291 (const_int 8))
8292 (any_or:SI
8293 (zero_extract:SI
8294 (match_operand 1 "ext_register_operand" "0")
8295 (const_int 8)
8296 (const_int 8))
8297 (zero_extend:SI
8298 (match_operand:QI 2 "general_operand" "Qm"))))
8299 (clobber (reg:CC FLAGS_REG))]
8300 "!TARGET_64BIT
8301 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8302 "<logic>{b}\t{%2, %h0|%h0, %2}"
8303 [(set_attr "type" "alu")
8304 (set_attr "length_immediate" "0")
8305 (set_attr "mode" "QI")])
8306
8307 (define_insn "*<code>qi_ext_2"
8308 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8309 (const_int 8)
8310 (const_int 8))
8311 (any_or:SI
8312 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8313 (const_int 8)
8314 (const_int 8))
8315 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8316 (const_int 8)
8317 (const_int 8))))
8318 (clobber (reg:CC FLAGS_REG))]
8319 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8320 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "length_immediate" "0")
8323 (set_attr "mode" "QI")])
8324
8325 (define_split
8326 [(set (match_operand 0 "register_operand" "")
8327 (any_or (match_operand 1 "register_operand" "")
8328 (match_operand 2 "const_int_operand" "")))
8329 (clobber (reg:CC FLAGS_REG))]
8330 "reload_completed
8331 && QI_REG_P (operands[0])
8332 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8333 && !(INTVAL (operands[2]) & ~(255 << 8))
8334 && GET_MODE (operands[0]) != QImode"
8335 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8336 (any_or:SI (zero_extract:SI (match_dup 1)
8337 (const_int 8) (const_int 8))
8338 (match_dup 2)))
8339 (clobber (reg:CC FLAGS_REG))])]
8340 "operands[0] = gen_lowpart (SImode, operands[0]);
8341 operands[1] = gen_lowpart (SImode, operands[1]);
8342 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8343
8344 ;; Since OR can be encoded with sign extended immediate, this is only
8345 ;; profitable when 7th bit is set.
8346 (define_split
8347 [(set (match_operand 0 "register_operand" "")
8348 (any_or (match_operand 1 "general_operand" "")
8349 (match_operand 2 "const_int_operand" "")))
8350 (clobber (reg:CC FLAGS_REG))]
8351 "reload_completed
8352 && ANY_QI_REG_P (operands[0])
8353 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8354 && !(INTVAL (operands[2]) & ~255)
8355 && (INTVAL (operands[2]) & 128)
8356 && GET_MODE (operands[0]) != QImode"
8357 [(parallel [(set (strict_low_part (match_dup 0))
8358 (any_or:QI (match_dup 1)
8359 (match_dup 2)))
8360 (clobber (reg:CC FLAGS_REG))])]
8361 "operands[0] = gen_lowpart (QImode, operands[0]);
8362 operands[1] = gen_lowpart (QImode, operands[1]);
8363 operands[2] = gen_lowpart (QImode, operands[2]);")
8364
8365 (define_expand "xorqi_cc_ext_1"
8366 [(parallel [
8367 (set (reg:CCNO FLAGS_REG)
8368 (compare:CCNO
8369 (xor:SI
8370 (zero_extract:SI
8371 (match_operand 1 "ext_register_operand" "")
8372 (const_int 8)
8373 (const_int 8))
8374 (match_operand:QI 2 "general_operand" ""))
8375 (const_int 0)))
8376 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8377 (const_int 8)
8378 (const_int 8))
8379 (xor:SI
8380 (zero_extract:SI
8381 (match_dup 1)
8382 (const_int 8)
8383 (const_int 8))
8384 (match_dup 2)))])])
8385
8386 (define_insn "*xorqi_cc_ext_1_rex64"
8387 [(set (reg FLAGS_REG)
8388 (compare
8389 (xor:SI
8390 (zero_extract:SI
8391 (match_operand 1 "ext_register_operand" "0")
8392 (const_int 8)
8393 (const_int 8))
8394 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8395 (const_int 0)))
8396 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8397 (const_int 8)
8398 (const_int 8))
8399 (xor:SI
8400 (zero_extract:SI
8401 (match_dup 1)
8402 (const_int 8)
8403 (const_int 8))
8404 (match_dup 2)))]
8405 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8406 "xor{b}\t{%2, %h0|%h0, %2}"
8407 [(set_attr "type" "alu")
8408 (set_attr "modrm" "1")
8409 (set_attr "mode" "QI")])
8410
8411 (define_insn "*xorqi_cc_ext_1"
8412 [(set (reg FLAGS_REG)
8413 (compare
8414 (xor:SI
8415 (zero_extract:SI
8416 (match_operand 1 "ext_register_operand" "0")
8417 (const_int 8)
8418 (const_int 8))
8419 (match_operand:QI 2 "general_operand" "qmn"))
8420 (const_int 0)))
8421 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8422 (const_int 8)
8423 (const_int 8))
8424 (xor:SI
8425 (zero_extract:SI
8426 (match_dup 1)
8427 (const_int 8)
8428 (const_int 8))
8429 (match_dup 2)))]
8430 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8431 "xor{b}\t{%2, %h0|%h0, %2}"
8432 [(set_attr "type" "alu")
8433 (set_attr "modrm" "1")
8434 (set_attr "mode" "QI")])
8435 \f
8436 ;; Negation instructions
8437
8438 (define_expand "neg<mode>2"
8439 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8440 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8441 ""
8442 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8443
8444 (define_insn_and_split "*neg<dwi>2_doubleword"
8445 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8446 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8447 (clobber (reg:CC FLAGS_REG))]
8448 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8449 "#"
8450 "reload_completed"
8451 [(parallel
8452 [(set (reg:CCZ FLAGS_REG)
8453 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8454 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8455 (parallel
8456 [(set (match_dup 2)
8457 (plus:DWIH (match_dup 3)
8458 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8459 (const_int 0))))
8460 (clobber (reg:CC FLAGS_REG))])
8461 (parallel
8462 [(set (match_dup 2)
8463 (neg:DWIH (match_dup 2)))
8464 (clobber (reg:CC FLAGS_REG))])]
8465 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8466
8467 (define_insn "*neg<mode>2_1"
8468 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8469 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8470 (clobber (reg:CC FLAGS_REG))]
8471 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8472 "neg{<imodesuffix>}\t%0"
8473 [(set_attr "type" "negnot")
8474 (set_attr "mode" "<MODE>")])
8475
8476 ;; Combine is quite creative about this pattern.
8477 (define_insn "*negsi2_1_zext"
8478 [(set (match_operand:DI 0 "register_operand" "=r")
8479 (lshiftrt:DI
8480 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8481 (const_int 32)))
8482 (const_int 32)))
8483 (clobber (reg:CC FLAGS_REG))]
8484 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8485 "neg{l}\t%k0"
8486 [(set_attr "type" "negnot")
8487 (set_attr "mode" "SI")])
8488
8489 ;; The problem with neg is that it does not perform (compare x 0),
8490 ;; it really performs (compare 0 x), which leaves us with the zero
8491 ;; flag being the only useful item.
8492
8493 (define_insn "*neg<mode>2_cmpz"
8494 [(set (reg:CCZ FLAGS_REG)
8495 (compare:CCZ
8496 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8497 (const_int 0)))
8498 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8499 (neg:SWI (match_dup 1)))]
8500 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8501 "neg{<imodesuffix>}\t%0"
8502 [(set_attr "type" "negnot")
8503 (set_attr "mode" "<MODE>")])
8504
8505 (define_insn "*negsi2_cmpz_zext"
8506 [(set (reg:CCZ FLAGS_REG)
8507 (compare:CCZ
8508 (lshiftrt:DI
8509 (neg:DI (ashift:DI
8510 (match_operand:DI 1 "register_operand" "0")
8511 (const_int 32)))
8512 (const_int 32))
8513 (const_int 0)))
8514 (set (match_operand:DI 0 "register_operand" "=r")
8515 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8516 (const_int 32)))
8517 (const_int 32)))]
8518 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8519 "neg{l}\t%k0"
8520 [(set_attr "type" "negnot")
8521 (set_attr "mode" "SI")])
8522
8523 ;; Changing of sign for FP values is doable using integer unit too.
8524
8525 (define_expand "<code><mode>2"
8526 [(set (match_operand:X87MODEF 0 "register_operand" "")
8527 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8528 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8529 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8530
8531 (define_insn "*absneg<mode>2_mixed"
8532 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8533 (match_operator:MODEF 3 "absneg_operator"
8534 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8535 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8538 "#")
8539
8540 (define_insn "*absneg<mode>2_sse"
8541 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8542 (match_operator:MODEF 3 "absneg_operator"
8543 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8544 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8547 "#")
8548
8549 (define_insn "*absneg<mode>2_i387"
8550 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8551 (match_operator:X87MODEF 3 "absneg_operator"
8552 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8553 (use (match_operand 2 "" ""))
8554 (clobber (reg:CC FLAGS_REG))]
8555 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8556 "#")
8557
8558 (define_expand "<code>tf2"
8559 [(set (match_operand:TF 0 "register_operand" "")
8560 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8561 "TARGET_SSE2"
8562 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8563
8564 (define_insn "*absnegtf2_sse"
8565 [(set (match_operand:TF 0 "register_operand" "=x,x")
8566 (match_operator:TF 3 "absneg_operator"
8567 [(match_operand:TF 1 "register_operand" "0,x")]))
8568 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8569 (clobber (reg:CC FLAGS_REG))]
8570 "TARGET_SSE2"
8571 "#")
8572
8573 ;; Splitters for fp abs and neg.
8574
8575 (define_split
8576 [(set (match_operand 0 "fp_register_operand" "")
8577 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8578 (use (match_operand 2 "" ""))
8579 (clobber (reg:CC FLAGS_REG))]
8580 "reload_completed"
8581 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8582
8583 (define_split
8584 [(set (match_operand 0 "register_operand" "")
8585 (match_operator 3 "absneg_operator"
8586 [(match_operand 1 "register_operand" "")]))
8587 (use (match_operand 2 "nonimmediate_operand" ""))
8588 (clobber (reg:CC FLAGS_REG))]
8589 "reload_completed && SSE_REG_P (operands[0])"
8590 [(set (match_dup 0) (match_dup 3))]
8591 {
8592 enum machine_mode mode = GET_MODE (operands[0]);
8593 enum machine_mode vmode = GET_MODE (operands[2]);
8594 rtx tmp;
8595
8596 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8597 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8598 if (operands_match_p (operands[0], operands[2]))
8599 {
8600 tmp = operands[1];
8601 operands[1] = operands[2];
8602 operands[2] = tmp;
8603 }
8604 if (GET_CODE (operands[3]) == ABS)
8605 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8606 else
8607 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8608 operands[3] = tmp;
8609 })
8610
8611 (define_split
8612 [(set (match_operand:SF 0 "register_operand" "")
8613 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8614 (use (match_operand:V4SF 2 "" ""))
8615 (clobber (reg:CC FLAGS_REG))]
8616 "reload_completed"
8617 [(parallel [(set (match_dup 0) (match_dup 1))
8618 (clobber (reg:CC FLAGS_REG))])]
8619 {
8620 rtx tmp;
8621 operands[0] = gen_lowpart (SImode, operands[0]);
8622 if (GET_CODE (operands[1]) == ABS)
8623 {
8624 tmp = gen_int_mode (0x7fffffff, SImode);
8625 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8626 }
8627 else
8628 {
8629 tmp = gen_int_mode (0x80000000, SImode);
8630 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8631 }
8632 operands[1] = tmp;
8633 })
8634
8635 (define_split
8636 [(set (match_operand:DF 0 "register_operand" "")
8637 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8638 (use (match_operand 2 "" ""))
8639 (clobber (reg:CC FLAGS_REG))]
8640 "reload_completed"
8641 [(parallel [(set (match_dup 0) (match_dup 1))
8642 (clobber (reg:CC FLAGS_REG))])]
8643 {
8644 rtx tmp;
8645 if (TARGET_64BIT)
8646 {
8647 tmp = gen_lowpart (DImode, operands[0]);
8648 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8649 operands[0] = tmp;
8650
8651 if (GET_CODE (operands[1]) == ABS)
8652 tmp = const0_rtx;
8653 else
8654 tmp = gen_rtx_NOT (DImode, tmp);
8655 }
8656 else
8657 {
8658 operands[0] = gen_highpart (SImode, operands[0]);
8659 if (GET_CODE (operands[1]) == ABS)
8660 {
8661 tmp = gen_int_mode (0x7fffffff, SImode);
8662 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8663 }
8664 else
8665 {
8666 tmp = gen_int_mode (0x80000000, SImode);
8667 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8668 }
8669 }
8670 operands[1] = tmp;
8671 })
8672
8673 (define_split
8674 [(set (match_operand:XF 0 "register_operand" "")
8675 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8676 (use (match_operand 2 "" ""))
8677 (clobber (reg:CC FLAGS_REG))]
8678 "reload_completed"
8679 [(parallel [(set (match_dup 0) (match_dup 1))
8680 (clobber (reg:CC FLAGS_REG))])]
8681 {
8682 rtx tmp;
8683 operands[0] = gen_rtx_REG (SImode,
8684 true_regnum (operands[0])
8685 + (TARGET_64BIT ? 1 : 2));
8686 if (GET_CODE (operands[1]) == ABS)
8687 {
8688 tmp = GEN_INT (0x7fff);
8689 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8690 }
8691 else
8692 {
8693 tmp = GEN_INT (0x8000);
8694 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8695 }
8696 operands[1] = tmp;
8697 })
8698
8699 ;; Conditionalize these after reload. If they match before reload, we
8700 ;; lose the clobber and ability to use integer instructions.
8701
8702 (define_insn "*<code><mode>2_1"
8703 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8704 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8705 "TARGET_80387
8706 && (reload_completed
8707 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8708 "f<absneg_mnemonic>"
8709 [(set_attr "type" "fsgn")
8710 (set_attr "mode" "<MODE>")])
8711
8712 (define_insn "*<code>extendsfdf2"
8713 [(set (match_operand:DF 0 "register_operand" "=f")
8714 (absneg:DF (float_extend:DF
8715 (match_operand:SF 1 "register_operand" "0"))))]
8716 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8717 "f<absneg_mnemonic>"
8718 [(set_attr "type" "fsgn")
8719 (set_attr "mode" "DF")])
8720
8721 (define_insn "*<code>extendsfxf2"
8722 [(set (match_operand:XF 0 "register_operand" "=f")
8723 (absneg:XF (float_extend:XF
8724 (match_operand:SF 1 "register_operand" "0"))))]
8725 "TARGET_80387"
8726 "f<absneg_mnemonic>"
8727 [(set_attr "type" "fsgn")
8728 (set_attr "mode" "XF")])
8729
8730 (define_insn "*<code>extenddfxf2"
8731 [(set (match_operand:XF 0 "register_operand" "=f")
8732 (absneg:XF (float_extend:XF
8733 (match_operand:DF 1 "register_operand" "0"))))]
8734 "TARGET_80387"
8735 "f<absneg_mnemonic>"
8736 [(set_attr "type" "fsgn")
8737 (set_attr "mode" "XF")])
8738
8739 ;; Copysign instructions
8740
8741 (define_mode_iterator CSGNMODE [SF DF TF])
8742 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8743
8744 (define_expand "copysign<mode>3"
8745 [(match_operand:CSGNMODE 0 "register_operand" "")
8746 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8747 (match_operand:CSGNMODE 2 "register_operand" "")]
8748 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8749 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8750 "ix86_expand_copysign (operands); DONE;")
8751
8752 (define_insn_and_split "copysign<mode>3_const"
8753 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8754 (unspec:CSGNMODE
8755 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8756 (match_operand:CSGNMODE 2 "register_operand" "0")
8757 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8758 UNSPEC_COPYSIGN))]
8759 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8760 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8761 "#"
8762 "&& reload_completed"
8763 [(const_int 0)]
8764 "ix86_split_copysign_const (operands); DONE;")
8765
8766 (define_insn "copysign<mode>3_var"
8767 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8768 (unspec:CSGNMODE
8769 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8770 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8771 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8772 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8773 UNSPEC_COPYSIGN))
8774 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8775 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8776 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8777 "#")
8778
8779 (define_split
8780 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8781 (unspec:CSGNMODE
8782 [(match_operand:CSGNMODE 2 "register_operand" "")
8783 (match_operand:CSGNMODE 3 "register_operand" "")
8784 (match_operand:<CSGNVMODE> 4 "" "")
8785 (match_operand:<CSGNVMODE> 5 "" "")]
8786 UNSPEC_COPYSIGN))
8787 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8788 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8789 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8790 && reload_completed"
8791 [(const_int 0)]
8792 "ix86_split_copysign_var (operands); DONE;")
8793 \f
8794 ;; One complement instructions
8795
8796 (define_expand "one_cmpl<mode>2"
8797 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8798 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8799 ""
8800 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8801
8802 (define_insn "*one_cmpl<mode>2_1"
8803 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8804 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8805 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8806 "not{<imodesuffix>}\t%0"
8807 [(set_attr "type" "negnot")
8808 (set_attr "mode" "<MODE>")])
8809
8810 ;; %%% Potential partial reg stall on alternative 1. What to do?
8811 (define_insn "*one_cmplqi2_1"
8812 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8813 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8814 "ix86_unary_operator_ok (NOT, QImode, operands)"
8815 "@
8816 not{b}\t%0
8817 not{l}\t%k0"
8818 [(set_attr "type" "negnot")
8819 (set_attr "mode" "QI,SI")])
8820
8821 ;; ??? Currently never generated - xor is used instead.
8822 (define_insn "*one_cmplsi2_1_zext"
8823 [(set (match_operand:DI 0 "register_operand" "=r")
8824 (zero_extend:DI
8825 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8826 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8827 "not{l}\t%k0"
8828 [(set_attr "type" "negnot")
8829 (set_attr "mode" "SI")])
8830
8831 (define_insn "*one_cmpl<mode>2_2"
8832 [(set (reg FLAGS_REG)
8833 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8834 (const_int 0)))
8835 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8836 (not:SWI (match_dup 1)))]
8837 "ix86_match_ccmode (insn, CCNOmode)
8838 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8839 "#"
8840 [(set_attr "type" "alu1")
8841 (set_attr "mode" "<MODE>")])
8842
8843 (define_split
8844 [(set (match_operand 0 "flags_reg_operand" "")
8845 (match_operator 2 "compare_operator"
8846 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8847 (const_int 0)]))
8848 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8849 (not:SWI (match_dup 3)))]
8850 "ix86_match_ccmode (insn, CCNOmode)"
8851 [(parallel [(set (match_dup 0)
8852 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8853 (const_int 0)]))
8854 (set (match_dup 1)
8855 (xor:SWI (match_dup 3) (const_int -1)))])])
8856
8857 ;; ??? Currently never generated - xor is used instead.
8858 (define_insn "*one_cmplsi2_2_zext"
8859 [(set (reg FLAGS_REG)
8860 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8861 (const_int 0)))
8862 (set (match_operand:DI 0 "register_operand" "=r")
8863 (zero_extend:DI (not:SI (match_dup 1))))]
8864 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8865 && ix86_unary_operator_ok (NOT, SImode, operands)"
8866 "#"
8867 [(set_attr "type" "alu1")
8868 (set_attr "mode" "SI")])
8869
8870 (define_split
8871 [(set (match_operand 0 "flags_reg_operand" "")
8872 (match_operator 2 "compare_operator"
8873 [(not:SI (match_operand:SI 3 "register_operand" ""))
8874 (const_int 0)]))
8875 (set (match_operand:DI 1 "register_operand" "")
8876 (zero_extend:DI (not:SI (match_dup 3))))]
8877 "ix86_match_ccmode (insn, CCNOmode)"
8878 [(parallel [(set (match_dup 0)
8879 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8880 (const_int 0)]))
8881 (set (match_dup 1)
8882 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8883 \f
8884 ;; Shift instructions
8885
8886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8889 ;; from the assembler input.
8890 ;;
8891 ;; This instruction shifts the target reg/mem as usual, but instead of
8892 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8893 ;; is a left shift double, bits are taken from the high order bits of
8894 ;; reg, else if the insn is a shift right double, bits are taken from the
8895 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8897 ;;
8898 ;; Since sh[lr]d does not change the `reg' operand, that is done
8899 ;; separately, making all shifts emit pairs of shift double and normal
8900 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8901 ;; support a 63 bit shift, each shift where the count is in a reg expands
8902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8903 ;;
8904 ;; If the shift count is a constant, we need never emit more than one
8905 ;; shift pair, instead using moves and sign extension for counts greater
8906 ;; than 31.
8907
8908 (define_expand "ashl<mode>3"
8909 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8910 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8911 (match_operand:QI 2 "nonmemory_operand" "")))]
8912 ""
8913 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8914
8915 (define_insn "*ashl<mode>3_doubleword"
8916 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8917 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8918 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8919 (clobber (reg:CC FLAGS_REG))]
8920 ""
8921 "#"
8922 [(set_attr "type" "multi")])
8923
8924 (define_split
8925 [(set (match_operand:DWI 0 "register_operand" "")
8926 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8927 (match_operand:QI 2 "nonmemory_operand" "")))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8930 [(const_int 0)]
8931 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8932
8933 ;; By default we don't ask for a scratch register, because when DWImode
8934 ;; values are manipulated, registers are already at a premium. But if
8935 ;; we have one handy, we won't turn it away.
8936
8937 (define_peephole2
8938 [(match_scratch:DWIH 3 "r")
8939 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8940 (ashift:<DWI>
8941 (match_operand:<DWI> 1 "nonmemory_operand" "")
8942 (match_operand:QI 2 "nonmemory_operand" "")))
8943 (clobber (reg:CC FLAGS_REG))])
8944 (match_dup 3)]
8945 "TARGET_CMOVE"
8946 [(const_int 0)]
8947 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8948
8949 (define_insn "x86_64_shld"
8950 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8951 (ior:DI (ashift:DI (match_dup 0)
8952 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8953 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8954 (minus:QI (const_int 64) (match_dup 2)))))
8955 (clobber (reg:CC FLAGS_REG))]
8956 "TARGET_64BIT"
8957 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8958 [(set_attr "type" "ishift")
8959 (set_attr "prefix_0f" "1")
8960 (set_attr "mode" "DI")
8961 (set_attr "athlon_decode" "vector")
8962 (set_attr "amdfam10_decode" "vector")
8963 (set_attr "bdver1_decode" "vector")])
8964
8965 (define_insn "x86_shld"
8966 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8967 (ior:SI (ashift:SI (match_dup 0)
8968 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8969 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8970 (minus:QI (const_int 32) (match_dup 2)))))
8971 (clobber (reg:CC FLAGS_REG))]
8972 ""
8973 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8974 [(set_attr "type" "ishift")
8975 (set_attr "prefix_0f" "1")
8976 (set_attr "mode" "SI")
8977 (set_attr "pent_pair" "np")
8978 (set_attr "athlon_decode" "vector")
8979 (set_attr "amdfam10_decode" "vector")
8980 (set_attr "bdver1_decode" "vector")])
8981
8982 (define_expand "x86_shift<mode>_adj_1"
8983 [(set (reg:CCZ FLAGS_REG)
8984 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8985 (match_dup 4))
8986 (const_int 0)))
8987 (set (match_operand:SWI48 0 "register_operand" "")
8988 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8989 (match_operand:SWI48 1 "register_operand" "")
8990 (match_dup 0)))
8991 (set (match_dup 1)
8992 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8993 (match_operand:SWI48 3 "register_operand" "r")
8994 (match_dup 1)))]
8995 "TARGET_CMOVE"
8996 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8997
8998 (define_expand "x86_shift<mode>_adj_2"
8999 [(use (match_operand:SWI48 0 "register_operand" ""))
9000 (use (match_operand:SWI48 1 "register_operand" ""))
9001 (use (match_operand:QI 2 "register_operand" ""))]
9002 ""
9003 {
9004 rtx label = gen_label_rtx ();
9005 rtx tmp;
9006
9007 emit_insn (gen_testqi_ccz_1 (operands[2],
9008 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9009
9010 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9011 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9012 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9013 gen_rtx_LABEL_REF (VOIDmode, label),
9014 pc_rtx);
9015 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9016 JUMP_LABEL (tmp) = label;
9017
9018 emit_move_insn (operands[0], operands[1]);
9019 ix86_expand_clear (operands[1]);
9020
9021 emit_label (label);
9022 LABEL_NUSES (label) = 1;
9023
9024 DONE;
9025 })
9026
9027 ;; Avoid useless masking of count operand.
9028 (define_insn_and_split "*ashl<mode>3_mask"
9029 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9030 (ashift:SWI48
9031 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9032 (subreg:QI
9033 (and:SI
9034 (match_operand:SI 2 "nonimmediate_operand" "c")
9035 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9036 (clobber (reg:CC FLAGS_REG))]
9037 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9038 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9039 == GET_MODE_BITSIZE (<MODE>mode)-1"
9040 "#"
9041 "&& 1"
9042 [(parallel [(set (match_dup 0)
9043 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9044 (clobber (reg:CC FLAGS_REG))])]
9045 {
9046 if (can_create_pseudo_p ())
9047 operands [2] = force_reg (SImode, operands[2]);
9048
9049 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9050 }
9051 [(set_attr "type" "ishift")
9052 (set_attr "mode" "<MODE>")])
9053
9054 (define_insn "*ashl<mode>3_1"
9055 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9056 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9057 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
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 return "#";
9065
9066 case TYPE_ALU:
9067 gcc_assert (operands[2] == const1_rtx);
9068 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9069 return "add{<imodesuffix>}\t%0, %0";
9070
9071 default:
9072 if (operands[2] == const1_rtx
9073 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9074 return "sal{<imodesuffix>}\t%0";
9075 else
9076 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9077 }
9078 }
9079 [(set (attr "type")
9080 (cond [(eq_attr "alternative" "1")
9081 (const_string "lea")
9082 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9083 (const_int 0))
9084 (match_operand 0 "register_operand" ""))
9085 (match_operand 2 "const1_operand" ""))
9086 (const_string "alu")
9087 ]
9088 (const_string "ishift")))
9089 (set (attr "length_immediate")
9090 (if_then_else
9091 (ior (eq_attr "type" "alu")
9092 (and (eq_attr "type" "ishift")
9093 (and (match_operand 2 "const1_operand" "")
9094 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9095 (const_int 0)))))
9096 (const_string "0")
9097 (const_string "*")))
9098 (set_attr "mode" "<MODE>")])
9099
9100 (define_insn "*ashlsi3_1_zext"
9101 [(set (match_operand:DI 0 "register_operand" "=r,r")
9102 (zero_extend:DI
9103 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9104 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9105 (clobber (reg:CC FLAGS_REG))]
9106 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9107 {
9108 switch (get_attr_type (insn))
9109 {
9110 case TYPE_LEA:
9111 return "#";
9112
9113 case TYPE_ALU:
9114 gcc_assert (operands[2] == const1_rtx);
9115 return "add{l}\t%k0, %k0";
9116
9117 default:
9118 if (operands[2] == const1_rtx
9119 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9120 return "sal{l}\t%k0";
9121 else
9122 return "sal{l}\t{%2, %k0|%k0, %2}";
9123 }
9124 }
9125 [(set (attr "type")
9126 (cond [(eq_attr "alternative" "1")
9127 (const_string "lea")
9128 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9129 (const_int 0))
9130 (match_operand 2 "const1_operand" ""))
9131 (const_string "alu")
9132 ]
9133 (const_string "ishift")))
9134 (set (attr "length_immediate")
9135 (if_then_else
9136 (ior (eq_attr "type" "alu")
9137 (and (eq_attr "type" "ishift")
9138 (and (match_operand 2 "const1_operand" "")
9139 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9140 (const_int 0)))))
9141 (const_string "0")
9142 (const_string "*")))
9143 (set_attr "mode" "SI")])
9144
9145 (define_insn "*ashlhi3_1"
9146 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9147 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9148 (match_operand:QI 2 "nonmemory_operand" "cI")))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "TARGET_PARTIAL_REG_STALL
9151 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9152 {
9153 switch (get_attr_type (insn))
9154 {
9155 case TYPE_ALU:
9156 gcc_assert (operands[2] == const1_rtx);
9157 return "add{w}\t%0, %0";
9158
9159 default:
9160 if (operands[2] == const1_rtx
9161 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9162 return "sal{w}\t%0";
9163 else
9164 return "sal{w}\t{%2, %0|%0, %2}";
9165 }
9166 }
9167 [(set (attr "type")
9168 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9169 (const_int 0))
9170 (match_operand 0 "register_operand" ""))
9171 (match_operand 2 "const1_operand" ""))
9172 (const_string "alu")
9173 ]
9174 (const_string "ishift")))
9175 (set (attr "length_immediate")
9176 (if_then_else
9177 (ior (eq_attr "type" "alu")
9178 (and (eq_attr "type" "ishift")
9179 (and (match_operand 2 "const1_operand" "")
9180 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9181 (const_int 0)))))
9182 (const_string "0")
9183 (const_string "*")))
9184 (set_attr "mode" "HI")])
9185
9186 (define_insn "*ashlhi3_1_lea"
9187 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9188 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9189 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9190 (clobber (reg:CC FLAGS_REG))]
9191 "!TARGET_PARTIAL_REG_STALL
9192 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9193 {
9194 switch (get_attr_type (insn))
9195 {
9196 case TYPE_LEA:
9197 return "#";
9198
9199 case TYPE_ALU:
9200 gcc_assert (operands[2] == const1_rtx);
9201 return "add{w}\t%0, %0";
9202
9203 default:
9204 if (operands[2] == const1_rtx
9205 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9206 return "sal{w}\t%0";
9207 else
9208 return "sal{w}\t{%2, %0|%0, %2}";
9209 }
9210 }
9211 [(set (attr "type")
9212 (cond [(eq_attr "alternative" "1")
9213 (const_string "lea")
9214 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9215 (const_int 0))
9216 (match_operand 0 "register_operand" ""))
9217 (match_operand 2 "const1_operand" ""))
9218 (const_string "alu")
9219 ]
9220 (const_string "ishift")))
9221 (set (attr "length_immediate")
9222 (if_then_else
9223 (ior (eq_attr "type" "alu")
9224 (and (eq_attr "type" "ishift")
9225 (and (match_operand 2 "const1_operand" "")
9226 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9227 (const_int 0)))))
9228 (const_string "0")
9229 (const_string "*")))
9230 (set_attr "mode" "HI,SI")])
9231
9232 (define_insn "*ashlqi3_1"
9233 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9234 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9235 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9236 (clobber (reg:CC FLAGS_REG))]
9237 "TARGET_PARTIAL_REG_STALL
9238 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9239 {
9240 switch (get_attr_type (insn))
9241 {
9242 case TYPE_ALU:
9243 gcc_assert (operands[2] == const1_rtx);
9244 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9245 return "add{l}\t%k0, %k0";
9246 else
9247 return "add{b}\t%0, %0";
9248
9249 default:
9250 if (operands[2] == const1_rtx
9251 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9252 {
9253 if (get_attr_mode (insn) == MODE_SI)
9254 return "sal{l}\t%k0";
9255 else
9256 return "sal{b}\t%0";
9257 }
9258 else
9259 {
9260 if (get_attr_mode (insn) == MODE_SI)
9261 return "sal{l}\t{%2, %k0|%k0, %2}";
9262 else
9263 return "sal{b}\t{%2, %0|%0, %2}";
9264 }
9265 }
9266 }
9267 [(set (attr "type")
9268 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9269 (const_int 0))
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 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9281 (const_int 0)))))
9282 (const_string "0")
9283 (const_string "*")))
9284 (set_attr "mode" "QI,SI")])
9285
9286 ;; %%% Potential partial reg stall on alternative 2. What to do?
9287 (define_insn "*ashlqi3_1_lea"
9288 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9289 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9290 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9291 (clobber (reg:CC FLAGS_REG))]
9292 "!TARGET_PARTIAL_REG_STALL
9293 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9294 {
9295 switch (get_attr_type (insn))
9296 {
9297 case TYPE_LEA:
9298 return "#";
9299
9300 case TYPE_ALU:
9301 gcc_assert (operands[2] == const1_rtx);
9302 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9303 return "add{l}\t%k0, %k0";
9304 else
9305 return "add{b}\t%0, %0";
9306
9307 default:
9308 if (operands[2] == const1_rtx
9309 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9310 {
9311 if (get_attr_mode (insn) == MODE_SI)
9312 return "sal{l}\t%k0";
9313 else
9314 return "sal{b}\t%0";
9315 }
9316 else
9317 {
9318 if (get_attr_mode (insn) == MODE_SI)
9319 return "sal{l}\t{%2, %k0|%k0, %2}";
9320 else
9321 return "sal{b}\t{%2, %0|%0, %2}";
9322 }
9323 }
9324 }
9325 [(set (attr "type")
9326 (cond [(eq_attr "alternative" "2")
9327 (const_string "lea")
9328 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9329 (const_int 0))
9330 (match_operand 0 "register_operand" ""))
9331 (match_operand 2 "const1_operand" ""))
9332 (const_string "alu")
9333 ]
9334 (const_string "ishift")))
9335 (set (attr "length_immediate")
9336 (if_then_else
9337 (ior (eq_attr "type" "alu")
9338 (and (eq_attr "type" "ishift")
9339 (and (match_operand 2 "const1_operand" "")
9340 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9341 (const_int 0)))))
9342 (const_string "0")
9343 (const_string "*")))
9344 (set_attr "mode" "QI,SI,SI")])
9345
9346 (define_insn "*ashlqi3_1_slp"
9347 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9348 (ashift:QI (match_dup 0)
9349 (match_operand:QI 1 "nonmemory_operand" "cI")))
9350 (clobber (reg:CC FLAGS_REG))]
9351 "(optimize_function_for_size_p (cfun)
9352 || !TARGET_PARTIAL_FLAG_REG_STALL
9353 || (operands[1] == const1_rtx
9354 && (TARGET_SHIFT1
9355 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9356 {
9357 switch (get_attr_type (insn))
9358 {
9359 case TYPE_ALU:
9360 gcc_assert (operands[1] == const1_rtx);
9361 return "add{b}\t%0, %0";
9362
9363 default:
9364 if (operands[1] == const1_rtx
9365 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9366 return "sal{b}\t%0";
9367 else
9368 return "sal{b}\t{%1, %0|%0, %1}";
9369 }
9370 }
9371 [(set (attr "type")
9372 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9373 (const_int 0))
9374 (match_operand 0 "register_operand" ""))
9375 (match_operand 1 "const1_operand" ""))
9376 (const_string "alu")
9377 ]
9378 (const_string "ishift1")))
9379 (set (attr "length_immediate")
9380 (if_then_else
9381 (ior (eq_attr "type" "alu")
9382 (and (eq_attr "type" "ishift1")
9383 (and (match_operand 1 "const1_operand" "")
9384 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9385 (const_int 0)))))
9386 (const_string "0")
9387 (const_string "*")))
9388 (set_attr "mode" "QI")])
9389
9390 ;; Convert lea to the lea pattern to avoid flags dependency.
9391 (define_split
9392 [(set (match_operand 0 "register_operand" "")
9393 (ashift (match_operand 1 "index_register_operand" "")
9394 (match_operand:QI 2 "const_int_operand" "")))
9395 (clobber (reg:CC FLAGS_REG))]
9396 "reload_completed
9397 && true_regnum (operands[0]) != true_regnum (operands[1])"
9398 [(const_int 0)]
9399 {
9400 rtx pat;
9401 enum machine_mode mode = GET_MODE (operands[0]);
9402
9403 if (mode != Pmode)
9404 operands[1] = gen_lowpart (Pmode, operands[1]);
9405 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9406
9407 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9408
9409 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9410 operands[0] = gen_lowpart (SImode, operands[0]);
9411
9412 if (TARGET_64BIT && mode != Pmode)
9413 pat = gen_rtx_SUBREG (SImode, pat, 0);
9414
9415 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9416 DONE;
9417 })
9418
9419 ;; Convert lea to the lea pattern to avoid flags dependency.
9420 (define_split
9421 [(set (match_operand:DI 0 "register_operand" "")
9422 (zero_extend:DI
9423 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9424 (match_operand:QI 2 "const_int_operand" ""))))
9425 (clobber (reg:CC FLAGS_REG))]
9426 "TARGET_64BIT && reload_completed
9427 && true_regnum (operands[0]) != true_regnum (operands[1])"
9428 [(set (match_dup 0)
9429 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9430 {
9431 operands[1] = gen_lowpart (DImode, operands[1]);
9432 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9433 })
9434
9435 ;; This pattern can't accept a variable shift count, since shifts by
9436 ;; zero don't affect the flags. We assume that shifts by constant
9437 ;; zero are optimized away.
9438 (define_insn "*ashl<mode>3_cmp"
9439 [(set (reg FLAGS_REG)
9440 (compare
9441 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9442 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9443 (const_int 0)))
9444 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9445 (ashift:SWI (match_dup 1) (match_dup 2)))]
9446 "(optimize_function_for_size_p (cfun)
9447 || !TARGET_PARTIAL_FLAG_REG_STALL
9448 || (operands[2] == const1_rtx
9449 && (TARGET_SHIFT1
9450 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9451 && ix86_match_ccmode (insn, CCGOCmode)
9452 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9453 {
9454 switch (get_attr_type (insn))
9455 {
9456 case TYPE_ALU:
9457 gcc_assert (operands[2] == const1_rtx);
9458 return "add{<imodesuffix>}\t%0, %0";
9459
9460 default:
9461 if (operands[2] == const1_rtx
9462 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9463 return "sal{<imodesuffix>}\t%0";
9464 else
9465 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9466 }
9467 }
9468 [(set (attr "type")
9469 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9470 (const_int 0))
9471 (match_operand 0 "register_operand" ""))
9472 (match_operand 2 "const1_operand" ""))
9473 (const_string "alu")
9474 ]
9475 (const_string "ishift")))
9476 (set (attr "length_immediate")
9477 (if_then_else
9478 (ior (eq_attr "type" "alu")
9479 (and (eq_attr "type" "ishift")
9480 (and (match_operand 2 "const1_operand" "")
9481 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9482 (const_int 0)))))
9483 (const_string "0")
9484 (const_string "*")))
9485 (set_attr "mode" "<MODE>")])
9486
9487 (define_insn "*ashlsi3_cmp_zext"
9488 [(set (reg FLAGS_REG)
9489 (compare
9490 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9491 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9492 (const_int 0)))
9493 (set (match_operand:DI 0 "register_operand" "=r")
9494 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9495 "TARGET_64BIT
9496 && (optimize_function_for_size_p (cfun)
9497 || !TARGET_PARTIAL_FLAG_REG_STALL
9498 || (operands[2] == const1_rtx
9499 && (TARGET_SHIFT1
9500 || TARGET_DOUBLE_WITH_ADD)))
9501 && ix86_match_ccmode (insn, CCGOCmode)
9502 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9503 {
9504 switch (get_attr_type (insn))
9505 {
9506 case TYPE_ALU:
9507 gcc_assert (operands[2] == const1_rtx);
9508 return "add{l}\t%k0, %k0";
9509
9510 default:
9511 if (operands[2] == const1_rtx
9512 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513 return "sal{l}\t%k0";
9514 else
9515 return "sal{l}\t{%2, %k0|%k0, %2}";
9516 }
9517 }
9518 [(set (attr "type")
9519 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9520 (const_int 0))
9521 (match_operand 2 "const1_operand" ""))
9522 (const_string "alu")
9523 ]
9524 (const_string "ishift")))
9525 (set (attr "length_immediate")
9526 (if_then_else
9527 (ior (eq_attr "type" "alu")
9528 (and (eq_attr "type" "ishift")
9529 (and (match_operand 2 "const1_operand" "")
9530 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9531 (const_int 0)))))
9532 (const_string "0")
9533 (const_string "*")))
9534 (set_attr "mode" "SI")])
9535
9536 (define_insn "*ashl<mode>3_cconly"
9537 [(set (reg FLAGS_REG)
9538 (compare
9539 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9540 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9541 (const_int 0)))
9542 (clobber (match_scratch:SWI 0 "=<r>"))]
9543 "(optimize_function_for_size_p (cfun)
9544 || !TARGET_PARTIAL_FLAG_REG_STALL
9545 || (operands[2] == const1_rtx
9546 && (TARGET_SHIFT1
9547 || TARGET_DOUBLE_WITH_ADD)))
9548 && ix86_match_ccmode (insn, CCGOCmode)"
9549 {
9550 switch (get_attr_type (insn))
9551 {
9552 case TYPE_ALU:
9553 gcc_assert (operands[2] == const1_rtx);
9554 return "add{<imodesuffix>}\t%0, %0";
9555
9556 default:
9557 if (operands[2] == const1_rtx
9558 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9559 return "sal{<imodesuffix>}\t%0";
9560 else
9561 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9562 }
9563 }
9564 [(set (attr "type")
9565 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9566 (const_int 0))
9567 (match_operand 0 "register_operand" ""))
9568 (match_operand 2 "const1_operand" ""))
9569 (const_string "alu")
9570 ]
9571 (const_string "ishift")))
9572 (set (attr "length_immediate")
9573 (if_then_else
9574 (ior (eq_attr "type" "alu")
9575 (and (eq_attr "type" "ishift")
9576 (and (match_operand 2 "const1_operand" "")
9577 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9578 (const_int 0)))))
9579 (const_string "0")
9580 (const_string "*")))
9581 (set_attr "mode" "<MODE>")])
9582
9583 ;; See comment above `ashl<mode>3' about how this works.
9584
9585 (define_expand "<shiftrt_insn><mode>3"
9586 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9587 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9588 (match_operand:QI 2 "nonmemory_operand" "")))]
9589 ""
9590 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9591
9592 ;; Avoid useless masking of count operand.
9593 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9594 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9595 (any_shiftrt:SWI48
9596 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9597 (subreg:QI
9598 (and:SI
9599 (match_operand:SI 2 "nonimmediate_operand" "c")
9600 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9601 (clobber (reg:CC FLAGS_REG))]
9602 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9603 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9604 == GET_MODE_BITSIZE (<MODE>mode)-1"
9605 "#"
9606 "&& 1"
9607 [(parallel [(set (match_dup 0)
9608 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9609 (clobber (reg:CC FLAGS_REG))])]
9610 {
9611 if (can_create_pseudo_p ())
9612 operands [2] = force_reg (SImode, operands[2]);
9613
9614 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9615 }
9616 [(set_attr "type" "ishift")
9617 (set_attr "mode" "<MODE>")])
9618
9619 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9620 [(set (match_operand:DWI 0 "register_operand" "=r")
9621 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9622 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9623 (clobber (reg:CC FLAGS_REG))]
9624 ""
9625 "#"
9626 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9627 [(const_int 0)]
9628 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9629 [(set_attr "type" "multi")])
9630
9631 ;; By default we don't ask for a scratch register, because when DWImode
9632 ;; values are manipulated, registers are already at a premium. But if
9633 ;; we have one handy, we won't turn it away.
9634
9635 (define_peephole2
9636 [(match_scratch:DWIH 3 "r")
9637 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9638 (any_shiftrt:<DWI>
9639 (match_operand:<DWI> 1 "register_operand" "")
9640 (match_operand:QI 2 "nonmemory_operand" "")))
9641 (clobber (reg:CC FLAGS_REG))])
9642 (match_dup 3)]
9643 "TARGET_CMOVE"
9644 [(const_int 0)]
9645 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9646
9647 (define_insn "x86_64_shrd"
9648 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9649 (ior:DI (ashiftrt:DI (match_dup 0)
9650 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9651 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9652 (minus:QI (const_int 64) (match_dup 2)))))
9653 (clobber (reg:CC FLAGS_REG))]
9654 "TARGET_64BIT"
9655 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9656 [(set_attr "type" "ishift")
9657 (set_attr "prefix_0f" "1")
9658 (set_attr "mode" "DI")
9659 (set_attr "athlon_decode" "vector")
9660 (set_attr "amdfam10_decode" "vector")
9661 (set_attr "bdver1_decode" "vector")])
9662
9663 (define_insn "x86_shrd"
9664 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9665 (ior:SI (ashiftrt:SI (match_dup 0)
9666 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9667 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9668 (minus:QI (const_int 32) (match_dup 2)))))
9669 (clobber (reg:CC FLAGS_REG))]
9670 ""
9671 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9672 [(set_attr "type" "ishift")
9673 (set_attr "prefix_0f" "1")
9674 (set_attr "mode" "SI")
9675 (set_attr "pent_pair" "np")
9676 (set_attr "athlon_decode" "vector")
9677 (set_attr "amdfam10_decode" "vector")
9678 (set_attr "bdver1_decode" "vector")])
9679
9680 (define_insn "ashrdi3_cvt"
9681 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9682 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9683 (match_operand:QI 2 "const_int_operand" "")))
9684 (clobber (reg:CC FLAGS_REG))]
9685 "TARGET_64BIT && INTVAL (operands[2]) == 63
9686 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9687 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9688 "@
9689 {cqto|cqo}
9690 sar{q}\t{%2, %0|%0, %2}"
9691 [(set_attr "type" "imovx,ishift")
9692 (set_attr "prefix_0f" "0,*")
9693 (set_attr "length_immediate" "0,*")
9694 (set_attr "modrm" "0,1")
9695 (set_attr "mode" "DI")])
9696
9697 (define_insn "ashrsi3_cvt"
9698 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9699 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9700 (match_operand:QI 2 "const_int_operand" "")))
9701 (clobber (reg:CC FLAGS_REG))]
9702 "INTVAL (operands[2]) == 31
9703 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9704 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9705 "@
9706 {cltd|cdq}
9707 sar{l}\t{%2, %0|%0, %2}"
9708 [(set_attr "type" "imovx,ishift")
9709 (set_attr "prefix_0f" "0,*")
9710 (set_attr "length_immediate" "0,*")
9711 (set_attr "modrm" "0,1")
9712 (set_attr "mode" "SI")])
9713
9714 (define_insn "*ashrsi3_cvt_zext"
9715 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9716 (zero_extend:DI
9717 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9718 (match_operand:QI 2 "const_int_operand" ""))))
9719 (clobber (reg:CC FLAGS_REG))]
9720 "TARGET_64BIT && INTVAL (operands[2]) == 31
9721 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9722 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9723 "@
9724 {cltd|cdq}
9725 sar{l}\t{%2, %k0|%k0, %2}"
9726 [(set_attr "type" "imovx,ishift")
9727 (set_attr "prefix_0f" "0,*")
9728 (set_attr "length_immediate" "0,*")
9729 (set_attr "modrm" "0,1")
9730 (set_attr "mode" "SI")])
9731
9732 (define_expand "x86_shift<mode>_adj_3"
9733 [(use (match_operand:SWI48 0 "register_operand" ""))
9734 (use (match_operand:SWI48 1 "register_operand" ""))
9735 (use (match_operand:QI 2 "register_operand" ""))]
9736 ""
9737 {
9738 rtx label = gen_label_rtx ();
9739 rtx tmp;
9740
9741 emit_insn (gen_testqi_ccz_1 (operands[2],
9742 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9743
9744 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9745 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9746 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9747 gen_rtx_LABEL_REF (VOIDmode, label),
9748 pc_rtx);
9749 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9750 JUMP_LABEL (tmp) = label;
9751
9752 emit_move_insn (operands[0], operands[1]);
9753 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9754 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9755 emit_label (label);
9756 LABEL_NUSES (label) = 1;
9757
9758 DONE;
9759 })
9760
9761 (define_insn "*<shiftrt_insn><mode>3_1"
9762 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9763 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9764 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9765 (clobber (reg:CC FLAGS_REG))]
9766 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9767 {
9768 if (operands[2] == const1_rtx
9769 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9770 return "<shiftrt>{<imodesuffix>}\t%0";
9771 else
9772 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9773 }
9774 [(set_attr "type" "ishift")
9775 (set (attr "length_immediate")
9776 (if_then_else
9777 (and (match_operand 2 "const1_operand" "")
9778 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9779 (const_int 0)))
9780 (const_string "0")
9781 (const_string "*")))
9782 (set_attr "mode" "<MODE>")])
9783
9784 (define_insn "*<shiftrt_insn>si3_1_zext"
9785 [(set (match_operand:DI 0 "register_operand" "=r")
9786 (zero_extend:DI
9787 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9788 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9789 (clobber (reg:CC FLAGS_REG))]
9790 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9791 {
9792 if (operands[2] == const1_rtx
9793 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9794 return "<shiftrt>{l}\t%k0";
9795 else
9796 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9797 }
9798 [(set_attr "type" "ishift")
9799 (set (attr "length_immediate")
9800 (if_then_else
9801 (and (match_operand 2 "const1_operand" "")
9802 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9803 (const_int 0)))
9804 (const_string "0")
9805 (const_string "*")))
9806 (set_attr "mode" "SI")])
9807
9808 (define_insn "*<shiftrt_insn>qi3_1_slp"
9809 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9810 (any_shiftrt:QI (match_dup 0)
9811 (match_operand:QI 1 "nonmemory_operand" "cI")))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "(optimize_function_for_size_p (cfun)
9814 || !TARGET_PARTIAL_REG_STALL
9815 || (operands[1] == const1_rtx
9816 && TARGET_SHIFT1))"
9817 {
9818 if (operands[1] == const1_rtx
9819 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9820 return "<shiftrt>{b}\t%0";
9821 else
9822 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9823 }
9824 [(set_attr "type" "ishift1")
9825 (set (attr "length_immediate")
9826 (if_then_else
9827 (and (match_operand 1 "const1_operand" "")
9828 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9829 (const_int 0)))
9830 (const_string "0")
9831 (const_string "*")))
9832 (set_attr "mode" "QI")])
9833
9834 ;; This pattern can't accept a variable shift count, since shifts by
9835 ;; zero don't affect the flags. We assume that shifts by constant
9836 ;; zero are optimized away.
9837 (define_insn "*<shiftrt_insn><mode>3_cmp"
9838 [(set (reg FLAGS_REG)
9839 (compare
9840 (any_shiftrt:SWI
9841 (match_operand:SWI 1 "nonimmediate_operand" "0")
9842 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9843 (const_int 0)))
9844 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9845 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9846 "(optimize_function_for_size_p (cfun)
9847 || !TARGET_PARTIAL_FLAG_REG_STALL
9848 || (operands[2] == const1_rtx
9849 && TARGET_SHIFT1))
9850 && ix86_match_ccmode (insn, CCGOCmode)
9851 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9852 {
9853 if (operands[2] == const1_rtx
9854 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9855 return "<shiftrt>{<imodesuffix>}\t%0";
9856 else
9857 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9858 }
9859 [(set_attr "type" "ishift")
9860 (set (attr "length_immediate")
9861 (if_then_else
9862 (and (match_operand 2 "const1_operand" "")
9863 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9864 (const_int 0)))
9865 (const_string "0")
9866 (const_string "*")))
9867 (set_attr "mode" "<MODE>")])
9868
9869 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9870 [(set (reg FLAGS_REG)
9871 (compare
9872 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9873 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9874 (const_int 0)))
9875 (set (match_operand:DI 0 "register_operand" "=r")
9876 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9877 "TARGET_64BIT
9878 && (optimize_function_for_size_p (cfun)
9879 || !TARGET_PARTIAL_FLAG_REG_STALL
9880 || (operands[2] == const1_rtx
9881 && TARGET_SHIFT1))
9882 && ix86_match_ccmode (insn, CCGOCmode)
9883 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9884 {
9885 if (operands[2] == const1_rtx
9886 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887 return "<shiftrt>{l}\t%k0";
9888 else
9889 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9890 }
9891 [(set_attr "type" "ishift")
9892 (set (attr "length_immediate")
9893 (if_then_else
9894 (and (match_operand 2 "const1_operand" "")
9895 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9896 (const_int 0)))
9897 (const_string "0")
9898 (const_string "*")))
9899 (set_attr "mode" "SI")])
9900
9901 (define_insn "*<shiftrt_insn><mode>3_cconly"
9902 [(set (reg FLAGS_REG)
9903 (compare
9904 (any_shiftrt:SWI
9905 (match_operand:SWI 1 "register_operand" "0")
9906 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9907 (const_int 0)))
9908 (clobber (match_scratch:SWI 0 "=<r>"))]
9909 "(optimize_function_for_size_p (cfun)
9910 || !TARGET_PARTIAL_FLAG_REG_STALL
9911 || (operands[2] == const1_rtx
9912 && TARGET_SHIFT1))
9913 && ix86_match_ccmode (insn, CCGOCmode)"
9914 {
9915 if (operands[2] == const1_rtx
9916 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9917 return "<shiftrt>{<imodesuffix>}\t%0";
9918 else
9919 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9920 }
9921 [(set_attr "type" "ishift")
9922 (set (attr "length_immediate")
9923 (if_then_else
9924 (and (match_operand 2 "const1_operand" "")
9925 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9926 (const_int 0)))
9927 (const_string "0")
9928 (const_string "*")))
9929 (set_attr "mode" "<MODE>")])
9930 \f
9931 ;; Rotate instructions
9932
9933 (define_expand "<rotate_insn>ti3"
9934 [(set (match_operand:TI 0 "register_operand" "")
9935 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9936 (match_operand:QI 2 "nonmemory_operand" "")))]
9937 "TARGET_64BIT"
9938 {
9939 if (const_1_to_63_operand (operands[2], VOIDmode))
9940 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9941 (operands[0], operands[1], operands[2]));
9942 else
9943 FAIL;
9944
9945 DONE;
9946 })
9947
9948 (define_expand "<rotate_insn>di3"
9949 [(set (match_operand:DI 0 "shiftdi_operand" "")
9950 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9951 (match_operand:QI 2 "nonmemory_operand" "")))]
9952 ""
9953 {
9954 if (TARGET_64BIT)
9955 ix86_expand_binary_operator (<CODE>, DImode, operands);
9956 else if (const_1_to_31_operand (operands[2], VOIDmode))
9957 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9958 (operands[0], operands[1], operands[2]));
9959 else
9960 FAIL;
9961
9962 DONE;
9963 })
9964
9965 (define_expand "<rotate_insn><mode>3"
9966 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9967 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9968 (match_operand:QI 2 "nonmemory_operand" "")))]
9969 ""
9970 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9971
9972 ;; Avoid useless masking of count operand.
9973 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9974 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9975 (any_rotate:SWI48
9976 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9977 (subreg:QI
9978 (and:SI
9979 (match_operand:SI 2 "nonimmediate_operand" "c")
9980 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9981 (clobber (reg:CC FLAGS_REG))]
9982 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9983 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9984 == GET_MODE_BITSIZE (<MODE>mode)-1"
9985 "#"
9986 "&& 1"
9987 [(parallel [(set (match_dup 0)
9988 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9989 (clobber (reg:CC FLAGS_REG))])]
9990 {
9991 if (can_create_pseudo_p ())
9992 operands [2] = force_reg (SImode, operands[2]);
9993
9994 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9995 }
9996 [(set_attr "type" "rotate")
9997 (set_attr "mode" "<MODE>")])
9998
9999 ;; Implement rotation using two double-precision
10000 ;; shift instructions and a scratch register.
10001
10002 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10003 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10004 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10005 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10006 (clobber (reg:CC FLAGS_REG))
10007 (clobber (match_scratch:DWIH 3 "=&r"))]
10008 ""
10009 "#"
10010 "reload_completed"
10011 [(set (match_dup 3) (match_dup 4))
10012 (parallel
10013 [(set (match_dup 4)
10014 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10015 (lshiftrt:DWIH (match_dup 5)
10016 (minus:QI (match_dup 6) (match_dup 2)))))
10017 (clobber (reg:CC FLAGS_REG))])
10018 (parallel
10019 [(set (match_dup 5)
10020 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10021 (lshiftrt:DWIH (match_dup 3)
10022 (minus:QI (match_dup 6) (match_dup 2)))))
10023 (clobber (reg:CC FLAGS_REG))])]
10024 {
10025 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10026
10027 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10028 })
10029
10030 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10031 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10032 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10033 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10034 (clobber (reg:CC FLAGS_REG))
10035 (clobber (match_scratch:DWIH 3 "=&r"))]
10036 ""
10037 "#"
10038 "reload_completed"
10039 [(set (match_dup 3) (match_dup 4))
10040 (parallel
10041 [(set (match_dup 4)
10042 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10043 (ashift:DWIH (match_dup 5)
10044 (minus:QI (match_dup 6) (match_dup 2)))))
10045 (clobber (reg:CC FLAGS_REG))])
10046 (parallel
10047 [(set (match_dup 5)
10048 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10049 (ashift:DWIH (match_dup 3)
10050 (minus:QI (match_dup 6) (match_dup 2)))))
10051 (clobber (reg:CC FLAGS_REG))])]
10052 {
10053 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10054
10055 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10056 })
10057
10058 (define_insn "*<rotate_insn><mode>3_1"
10059 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10060 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10061 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10062 (clobber (reg:CC FLAGS_REG))]
10063 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10064 {
10065 if (operands[2] == const1_rtx
10066 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10067 return "<rotate>{<imodesuffix>}\t%0";
10068 else
10069 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10070 }
10071 [(set_attr "type" "rotate")
10072 (set (attr "length_immediate")
10073 (if_then_else
10074 (and (match_operand 2 "const1_operand" "")
10075 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10076 (const_int 0)))
10077 (const_string "0")
10078 (const_string "*")))
10079 (set_attr "mode" "<MODE>")])
10080
10081 (define_insn "*<rotate_insn>si3_1_zext"
10082 [(set (match_operand:DI 0 "register_operand" "=r")
10083 (zero_extend:DI
10084 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10085 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10086 (clobber (reg:CC FLAGS_REG))]
10087 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10088 {
10089 if (operands[2] == const1_rtx
10090 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10091 return "<rotate>{l}\t%k0";
10092 else
10093 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10094 }
10095 [(set_attr "type" "rotate")
10096 (set (attr "length_immediate")
10097 (if_then_else
10098 (and (match_operand 2 "const1_operand" "")
10099 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10100 (const_int 0)))
10101 (const_string "0")
10102 (const_string "*")))
10103 (set_attr "mode" "SI")])
10104
10105 (define_insn "*<rotate_insn>qi3_1_slp"
10106 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10107 (any_rotate:QI (match_dup 0)
10108 (match_operand:QI 1 "nonmemory_operand" "cI")))
10109 (clobber (reg:CC FLAGS_REG))]
10110 "(optimize_function_for_size_p (cfun)
10111 || !TARGET_PARTIAL_REG_STALL
10112 || (operands[1] == const1_rtx
10113 && TARGET_SHIFT1))"
10114 {
10115 if (operands[1] == const1_rtx
10116 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10117 return "<rotate>{b}\t%0";
10118 else
10119 return "<rotate>{b}\t{%1, %0|%0, %1}";
10120 }
10121 [(set_attr "type" "rotate1")
10122 (set (attr "length_immediate")
10123 (if_then_else
10124 (and (match_operand 1 "const1_operand" "")
10125 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10126 (const_int 0)))
10127 (const_string "0")
10128 (const_string "*")))
10129 (set_attr "mode" "QI")])
10130
10131 (define_split
10132 [(set (match_operand:HI 0 "register_operand" "")
10133 (any_rotate:HI (match_dup 0) (const_int 8)))
10134 (clobber (reg:CC FLAGS_REG))]
10135 "reload_completed
10136 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10137 [(parallel [(set (strict_low_part (match_dup 0))
10138 (bswap:HI (match_dup 0)))
10139 (clobber (reg:CC FLAGS_REG))])])
10140 \f
10141 ;; Bit set / bit test instructions
10142
10143 (define_expand "extv"
10144 [(set (match_operand:SI 0 "register_operand" "")
10145 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10146 (match_operand:SI 2 "const8_operand" "")
10147 (match_operand:SI 3 "const8_operand" "")))]
10148 ""
10149 {
10150 /* Handle extractions from %ah et al. */
10151 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10152 FAIL;
10153
10154 /* From mips.md: extract_bit_field doesn't verify that our source
10155 matches the predicate, so check it again here. */
10156 if (! ext_register_operand (operands[1], VOIDmode))
10157 FAIL;
10158 })
10159
10160 (define_expand "extzv"
10161 [(set (match_operand:SI 0 "register_operand" "")
10162 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10163 (match_operand:SI 2 "const8_operand" "")
10164 (match_operand:SI 3 "const8_operand" "")))]
10165 ""
10166 {
10167 /* Handle extractions from %ah et al. */
10168 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10169 FAIL;
10170
10171 /* From mips.md: extract_bit_field doesn't verify that our source
10172 matches the predicate, so check it again here. */
10173 if (! ext_register_operand (operands[1], VOIDmode))
10174 FAIL;
10175 })
10176
10177 (define_expand "insv"
10178 [(set (zero_extract (match_operand 0 "register_operand" "")
10179 (match_operand 1 "const_int_operand" "")
10180 (match_operand 2 "const_int_operand" ""))
10181 (match_operand 3 "register_operand" ""))]
10182 ""
10183 {
10184 rtx (*gen_mov_insv_1) (rtx, rtx);
10185
10186 if (ix86_expand_pinsr (operands))
10187 DONE;
10188
10189 /* Handle insertions to %ah et al. */
10190 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10191 FAIL;
10192
10193 /* From mips.md: insert_bit_field doesn't verify that our source
10194 matches the predicate, so check it again here. */
10195 if (! ext_register_operand (operands[0], VOIDmode))
10196 FAIL;
10197
10198 gen_mov_insv_1 = (TARGET_64BIT
10199 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10200
10201 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10202 DONE;
10203 })
10204
10205 ;; %%% bts, btr, btc, bt.
10206 ;; In general these instructions are *slow* when applied to memory,
10207 ;; since they enforce atomic operation. When applied to registers,
10208 ;; it depends on the cpu implementation. They're never faster than
10209 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10210 ;; no point. But in 64-bit, we can't hold the relevant immediates
10211 ;; within the instruction itself, so operating on bits in the high
10212 ;; 32-bits of a register becomes easier.
10213 ;;
10214 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10215 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10216 ;; negdf respectively, so they can never be disabled entirely.
10217
10218 (define_insn "*btsq"
10219 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10220 (const_int 1)
10221 (match_operand:DI 1 "const_0_to_63_operand" ""))
10222 (const_int 1))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10225 "bts{q}\t{%1, %0|%0, %1}"
10226 [(set_attr "type" "alu1")
10227 (set_attr "prefix_0f" "1")
10228 (set_attr "mode" "DI")])
10229
10230 (define_insn "*btrq"
10231 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10232 (const_int 1)
10233 (match_operand:DI 1 "const_0_to_63_operand" ""))
10234 (const_int 0))
10235 (clobber (reg:CC FLAGS_REG))]
10236 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10237 "btr{q}\t{%1, %0|%0, %1}"
10238 [(set_attr "type" "alu1")
10239 (set_attr "prefix_0f" "1")
10240 (set_attr "mode" "DI")])
10241
10242 (define_insn "*btcq"
10243 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10244 (const_int 1)
10245 (match_operand:DI 1 "const_0_to_63_operand" ""))
10246 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10247 (clobber (reg:CC FLAGS_REG))]
10248 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10249 "btc{q}\t{%1, %0|%0, %1}"
10250 [(set_attr "type" "alu1")
10251 (set_attr "prefix_0f" "1")
10252 (set_attr "mode" "DI")])
10253
10254 ;; Allow Nocona to avoid these instructions if a register is available.
10255
10256 (define_peephole2
10257 [(match_scratch:DI 2 "r")
10258 (parallel [(set (zero_extract:DI
10259 (match_operand:DI 0 "register_operand" "")
10260 (const_int 1)
10261 (match_operand:DI 1 "const_0_to_63_operand" ""))
10262 (const_int 1))
10263 (clobber (reg:CC FLAGS_REG))])]
10264 "TARGET_64BIT && !TARGET_USE_BT"
10265 [(const_int 0)]
10266 {
10267 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10268 rtx op1;
10269
10270 if (HOST_BITS_PER_WIDE_INT >= 64)
10271 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10272 else if (i < HOST_BITS_PER_WIDE_INT)
10273 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10274 else
10275 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10276
10277 op1 = immed_double_const (lo, hi, DImode);
10278 if (i >= 31)
10279 {
10280 emit_move_insn (operands[2], op1);
10281 op1 = operands[2];
10282 }
10283
10284 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10285 DONE;
10286 })
10287
10288 (define_peephole2
10289 [(match_scratch:DI 2 "r")
10290 (parallel [(set (zero_extract:DI
10291 (match_operand:DI 0 "register_operand" "")
10292 (const_int 1)
10293 (match_operand:DI 1 "const_0_to_63_operand" ""))
10294 (const_int 0))
10295 (clobber (reg:CC FLAGS_REG))])]
10296 "TARGET_64BIT && !TARGET_USE_BT"
10297 [(const_int 0)]
10298 {
10299 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10300 rtx op1;
10301
10302 if (HOST_BITS_PER_WIDE_INT >= 64)
10303 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10304 else if (i < HOST_BITS_PER_WIDE_INT)
10305 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10306 else
10307 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10308
10309 op1 = immed_double_const (~lo, ~hi, DImode);
10310 if (i >= 32)
10311 {
10312 emit_move_insn (operands[2], op1);
10313 op1 = operands[2];
10314 }
10315
10316 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10317 DONE;
10318 })
10319
10320 (define_peephole2
10321 [(match_scratch:DI 2 "r")
10322 (parallel [(set (zero_extract:DI
10323 (match_operand:DI 0 "register_operand" "")
10324 (const_int 1)
10325 (match_operand:DI 1 "const_0_to_63_operand" ""))
10326 (not:DI (zero_extract:DI
10327 (match_dup 0) (const_int 1) (match_dup 1))))
10328 (clobber (reg:CC FLAGS_REG))])]
10329 "TARGET_64BIT && !TARGET_USE_BT"
10330 [(const_int 0)]
10331 {
10332 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10333 rtx op1;
10334
10335 if (HOST_BITS_PER_WIDE_INT >= 64)
10336 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10337 else if (i < HOST_BITS_PER_WIDE_INT)
10338 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10339 else
10340 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10341
10342 op1 = immed_double_const (lo, hi, DImode);
10343 if (i >= 31)
10344 {
10345 emit_move_insn (operands[2], op1);
10346 op1 = operands[2];
10347 }
10348
10349 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10350 DONE;
10351 })
10352
10353 (define_insn "*bt<mode>"
10354 [(set (reg:CCC FLAGS_REG)
10355 (compare:CCC
10356 (zero_extract:SWI48
10357 (match_operand:SWI48 0 "register_operand" "r")
10358 (const_int 1)
10359 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10360 (const_int 0)))]
10361 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10362 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10363 [(set_attr "type" "alu1")
10364 (set_attr "prefix_0f" "1")
10365 (set_attr "mode" "<MODE>")])
10366 \f
10367 ;; Store-flag instructions.
10368
10369 ;; For all sCOND expanders, also expand the compare or test insn that
10370 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10371
10372 (define_insn_and_split "*setcc_di_1"
10373 [(set (match_operand:DI 0 "register_operand" "=q")
10374 (match_operator:DI 1 "ix86_comparison_operator"
10375 [(reg FLAGS_REG) (const_int 0)]))]
10376 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10377 "#"
10378 "&& reload_completed"
10379 [(set (match_dup 2) (match_dup 1))
10380 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10381 {
10382 PUT_MODE (operands[1], QImode);
10383 operands[2] = gen_lowpart (QImode, operands[0]);
10384 })
10385
10386 (define_insn_and_split "*setcc_si_1_and"
10387 [(set (match_operand:SI 0 "register_operand" "=q")
10388 (match_operator:SI 1 "ix86_comparison_operator"
10389 [(reg FLAGS_REG) (const_int 0)]))
10390 (clobber (reg:CC FLAGS_REG))]
10391 "!TARGET_PARTIAL_REG_STALL
10392 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10393 "#"
10394 "&& reload_completed"
10395 [(set (match_dup 2) (match_dup 1))
10396 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10397 (clobber (reg:CC FLAGS_REG))])]
10398 {
10399 PUT_MODE (operands[1], QImode);
10400 operands[2] = gen_lowpart (QImode, operands[0]);
10401 })
10402
10403 (define_insn_and_split "*setcc_si_1_movzbl"
10404 [(set (match_operand:SI 0 "register_operand" "=q")
10405 (match_operator:SI 1 "ix86_comparison_operator"
10406 [(reg FLAGS_REG) (const_int 0)]))]
10407 "!TARGET_PARTIAL_REG_STALL
10408 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10409 "#"
10410 "&& reload_completed"
10411 [(set (match_dup 2) (match_dup 1))
10412 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10413 {
10414 PUT_MODE (operands[1], QImode);
10415 operands[2] = gen_lowpart (QImode, operands[0]);
10416 })
10417
10418 (define_insn "*setcc_qi"
10419 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10420 (match_operator:QI 1 "ix86_comparison_operator"
10421 [(reg FLAGS_REG) (const_int 0)]))]
10422 ""
10423 "set%C1\t%0"
10424 [(set_attr "type" "setcc")
10425 (set_attr "mode" "QI")])
10426
10427 (define_insn "*setcc_qi_slp"
10428 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10429 (match_operator:QI 1 "ix86_comparison_operator"
10430 [(reg FLAGS_REG) (const_int 0)]))]
10431 ""
10432 "set%C1\t%0"
10433 [(set_attr "type" "setcc")
10434 (set_attr "mode" "QI")])
10435
10436 ;; In general it is not safe to assume too much about CCmode registers,
10437 ;; so simplify-rtx stops when it sees a second one. Under certain
10438 ;; conditions this is safe on x86, so help combine not create
10439 ;;
10440 ;; seta %al
10441 ;; testb %al, %al
10442 ;; sete %al
10443
10444 (define_split
10445 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10446 (ne:QI (match_operator 1 "ix86_comparison_operator"
10447 [(reg FLAGS_REG) (const_int 0)])
10448 (const_int 0)))]
10449 ""
10450 [(set (match_dup 0) (match_dup 1))]
10451 "PUT_MODE (operands[1], QImode);")
10452
10453 (define_split
10454 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10455 (ne:QI (match_operator 1 "ix86_comparison_operator"
10456 [(reg FLAGS_REG) (const_int 0)])
10457 (const_int 0)))]
10458 ""
10459 [(set (match_dup 0) (match_dup 1))]
10460 "PUT_MODE (operands[1], QImode);")
10461
10462 (define_split
10463 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10464 (eq:QI (match_operator 1 "ix86_comparison_operator"
10465 [(reg FLAGS_REG) (const_int 0)])
10466 (const_int 0)))]
10467 ""
10468 [(set (match_dup 0) (match_dup 1))]
10469 {
10470 rtx new_op1 = copy_rtx (operands[1]);
10471 operands[1] = new_op1;
10472 PUT_MODE (new_op1, QImode);
10473 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10474 GET_MODE (XEXP (new_op1, 0))));
10475
10476 /* Make sure that (a) the CCmode we have for the flags is strong
10477 enough for the reversed compare or (b) we have a valid FP compare. */
10478 if (! ix86_comparison_operator (new_op1, VOIDmode))
10479 FAIL;
10480 })
10481
10482 (define_split
10483 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10484 (eq:QI (match_operator 1 "ix86_comparison_operator"
10485 [(reg FLAGS_REG) (const_int 0)])
10486 (const_int 0)))]
10487 ""
10488 [(set (match_dup 0) (match_dup 1))]
10489 {
10490 rtx new_op1 = copy_rtx (operands[1]);
10491 operands[1] = new_op1;
10492 PUT_MODE (new_op1, QImode);
10493 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10494 GET_MODE (XEXP (new_op1, 0))));
10495
10496 /* Make sure that (a) the CCmode we have for the flags is strong
10497 enough for the reversed compare or (b) we have a valid FP compare. */
10498 if (! ix86_comparison_operator (new_op1, VOIDmode))
10499 FAIL;
10500 })
10501
10502 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10503 ;; subsequent logical operations are used to imitate conditional moves.
10504 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10505 ;; it directly.
10506
10507 (define_insn "setcc_<mode>_sse"
10508 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10509 (match_operator:MODEF 3 "sse_comparison_operator"
10510 [(match_operand:MODEF 1 "register_operand" "0,x")
10511 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10512 "SSE_FLOAT_MODE_P (<MODE>mode)"
10513 "@
10514 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10515 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10516 [(set_attr "isa" "noavx,avx")
10517 (set_attr "type" "ssecmp")
10518 (set_attr "length_immediate" "1")
10519 (set_attr "prefix" "orig,vex")
10520 (set_attr "mode" "<MODE>")])
10521 \f
10522 ;; Basic conditional jump instructions.
10523 ;; We ignore the overflow flag for signed branch instructions.
10524
10525 (define_insn "*jcc_1"
10526 [(set (pc)
10527 (if_then_else (match_operator 1 "ix86_comparison_operator"
10528 [(reg FLAGS_REG) (const_int 0)])
10529 (label_ref (match_operand 0 "" ""))
10530 (pc)))]
10531 ""
10532 "%+j%C1\t%l0"
10533 [(set_attr "type" "ibr")
10534 (set_attr "modrm" "0")
10535 (set (attr "length")
10536 (if_then_else (and (ge (minus (match_dup 0) (pc))
10537 (const_int -126))
10538 (lt (minus (match_dup 0) (pc))
10539 (const_int 128)))
10540 (const_int 2)
10541 (const_int 6)))])
10542
10543 (define_insn "*jcc_2"
10544 [(set (pc)
10545 (if_then_else (match_operator 1 "ix86_comparison_operator"
10546 [(reg FLAGS_REG) (const_int 0)])
10547 (pc)
10548 (label_ref (match_operand 0 "" ""))))]
10549 ""
10550 "%+j%c1\t%l0"
10551 [(set_attr "type" "ibr")
10552 (set_attr "modrm" "0")
10553 (set (attr "length")
10554 (if_then_else (and (ge (minus (match_dup 0) (pc))
10555 (const_int -126))
10556 (lt (minus (match_dup 0) (pc))
10557 (const_int 128)))
10558 (const_int 2)
10559 (const_int 6)))])
10560
10561 ;; In general it is not safe to assume too much about CCmode registers,
10562 ;; so simplify-rtx stops when it sees a second one. Under certain
10563 ;; conditions this is safe on x86, so help combine not create
10564 ;;
10565 ;; seta %al
10566 ;; testb %al, %al
10567 ;; je Lfoo
10568
10569 (define_split
10570 [(set (pc)
10571 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10572 [(reg FLAGS_REG) (const_int 0)])
10573 (const_int 0))
10574 (label_ref (match_operand 1 "" ""))
10575 (pc)))]
10576 ""
10577 [(set (pc)
10578 (if_then_else (match_dup 0)
10579 (label_ref (match_dup 1))
10580 (pc)))]
10581 "PUT_MODE (operands[0], VOIDmode);")
10582
10583 (define_split
10584 [(set (pc)
10585 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10586 [(reg FLAGS_REG) (const_int 0)])
10587 (const_int 0))
10588 (label_ref (match_operand 1 "" ""))
10589 (pc)))]
10590 ""
10591 [(set (pc)
10592 (if_then_else (match_dup 0)
10593 (label_ref (match_dup 1))
10594 (pc)))]
10595 {
10596 rtx new_op0 = copy_rtx (operands[0]);
10597 operands[0] = new_op0;
10598 PUT_MODE (new_op0, VOIDmode);
10599 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10600 GET_MODE (XEXP (new_op0, 0))));
10601
10602 /* Make sure that (a) the CCmode we have for the flags is strong
10603 enough for the reversed compare or (b) we have a valid FP compare. */
10604 if (! ix86_comparison_operator (new_op0, VOIDmode))
10605 FAIL;
10606 })
10607
10608 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10609 ;; pass generates from shift insn with QImode operand. Actually, the mode
10610 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10611 ;; appropriate modulo of the bit offset value.
10612
10613 (define_insn_and_split "*jcc_bt<mode>"
10614 [(set (pc)
10615 (if_then_else (match_operator 0 "bt_comparison_operator"
10616 [(zero_extract:SWI48
10617 (match_operand:SWI48 1 "register_operand" "r")
10618 (const_int 1)
10619 (zero_extend:SI
10620 (match_operand:QI 2 "register_operand" "r")))
10621 (const_int 0)])
10622 (label_ref (match_operand 3 "" ""))
10623 (pc)))
10624 (clobber (reg:CC FLAGS_REG))]
10625 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10626 "#"
10627 "&& 1"
10628 [(set (reg:CCC FLAGS_REG)
10629 (compare:CCC
10630 (zero_extract:SWI48
10631 (match_dup 1)
10632 (const_int 1)
10633 (match_dup 2))
10634 (const_int 0)))
10635 (set (pc)
10636 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10637 (label_ref (match_dup 3))
10638 (pc)))]
10639 {
10640 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10641
10642 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10643 })
10644
10645 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10646 ;; also for DImode, this is what combine produces.
10647 (define_insn_and_split "*jcc_bt<mode>_mask"
10648 [(set (pc)
10649 (if_then_else (match_operator 0 "bt_comparison_operator"
10650 [(zero_extract:SWI48
10651 (match_operand:SWI48 1 "register_operand" "r")
10652 (const_int 1)
10653 (and:SI
10654 (match_operand:SI 2 "register_operand" "r")
10655 (match_operand:SI 3 "const_int_operand" "n")))])
10656 (label_ref (match_operand 4 "" ""))
10657 (pc)))
10658 (clobber (reg:CC FLAGS_REG))]
10659 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10660 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10661 == GET_MODE_BITSIZE (<MODE>mode)-1"
10662 "#"
10663 "&& 1"
10664 [(set (reg:CCC FLAGS_REG)
10665 (compare:CCC
10666 (zero_extract:SWI48
10667 (match_dup 1)
10668 (const_int 1)
10669 (match_dup 2))
10670 (const_int 0)))
10671 (set (pc)
10672 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10673 (label_ref (match_dup 4))
10674 (pc)))]
10675 {
10676 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10677
10678 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10679 })
10680
10681 (define_insn_and_split "*jcc_btsi_1"
10682 [(set (pc)
10683 (if_then_else (match_operator 0 "bt_comparison_operator"
10684 [(and:SI
10685 (lshiftrt:SI
10686 (match_operand:SI 1 "register_operand" "r")
10687 (match_operand:QI 2 "register_operand" "r"))
10688 (const_int 1))
10689 (const_int 0)])
10690 (label_ref (match_operand 3 "" ""))
10691 (pc)))
10692 (clobber (reg:CC FLAGS_REG))]
10693 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10694 "#"
10695 "&& 1"
10696 [(set (reg:CCC FLAGS_REG)
10697 (compare:CCC
10698 (zero_extract:SI
10699 (match_dup 1)
10700 (const_int 1)
10701 (match_dup 2))
10702 (const_int 0)))
10703 (set (pc)
10704 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10705 (label_ref (match_dup 3))
10706 (pc)))]
10707 {
10708 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10709
10710 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10711 })
10712
10713 ;; avoid useless masking of bit offset operand
10714 (define_insn_and_split "*jcc_btsi_mask_1"
10715 [(set (pc)
10716 (if_then_else
10717 (match_operator 0 "bt_comparison_operator"
10718 [(and:SI
10719 (lshiftrt:SI
10720 (match_operand:SI 1 "register_operand" "r")
10721 (subreg:QI
10722 (and:SI
10723 (match_operand:SI 2 "register_operand" "r")
10724 (match_operand:SI 3 "const_int_operand" "n")) 0))
10725 (const_int 1))
10726 (const_int 0)])
10727 (label_ref (match_operand 4 "" ""))
10728 (pc)))
10729 (clobber (reg:CC FLAGS_REG))]
10730 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10731 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10732 "#"
10733 "&& 1"
10734 [(set (reg:CCC FLAGS_REG)
10735 (compare:CCC
10736 (zero_extract:SI
10737 (match_dup 1)
10738 (const_int 1)
10739 (match_dup 2))
10740 (const_int 0)))
10741 (set (pc)
10742 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10743 (label_ref (match_dup 4))
10744 (pc)))]
10745 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10746
10747 ;; Define combination compare-and-branch fp compare instructions to help
10748 ;; combine.
10749
10750 (define_insn "*fp_jcc_1_387"
10751 [(set (pc)
10752 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10753 [(match_operand 1 "register_operand" "f")
10754 (match_operand 2 "nonimmediate_operand" "fm")])
10755 (label_ref (match_operand 3 "" ""))
10756 (pc)))
10757 (clobber (reg:CCFP FPSR_REG))
10758 (clobber (reg:CCFP FLAGS_REG))
10759 (clobber (match_scratch:HI 4 "=a"))]
10760 "TARGET_80387
10761 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10762 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10763 && SELECT_CC_MODE (GET_CODE (operands[0]),
10764 operands[1], operands[2]) == CCFPmode
10765 && !TARGET_CMOVE"
10766 "#")
10767
10768 (define_insn "*fp_jcc_1r_387"
10769 [(set (pc)
10770 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10771 [(match_operand 1 "register_operand" "f")
10772 (match_operand 2 "nonimmediate_operand" "fm")])
10773 (pc)
10774 (label_ref (match_operand 3 "" ""))))
10775 (clobber (reg:CCFP FPSR_REG))
10776 (clobber (reg:CCFP FLAGS_REG))
10777 (clobber (match_scratch:HI 4 "=a"))]
10778 "TARGET_80387
10779 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10780 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10781 && SELECT_CC_MODE (GET_CODE (operands[0]),
10782 operands[1], operands[2]) == CCFPmode
10783 && !TARGET_CMOVE"
10784 "#")
10785
10786 (define_insn "*fp_jcc_2_387"
10787 [(set (pc)
10788 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10789 [(match_operand 1 "register_operand" "f")
10790 (match_operand 2 "register_operand" "f")])
10791 (label_ref (match_operand 3 "" ""))
10792 (pc)))
10793 (clobber (reg:CCFP FPSR_REG))
10794 (clobber (reg:CCFP FLAGS_REG))
10795 (clobber (match_scratch:HI 4 "=a"))]
10796 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10797 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10798 && !TARGET_CMOVE"
10799 "#")
10800
10801 (define_insn "*fp_jcc_2r_387"
10802 [(set (pc)
10803 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10804 [(match_operand 1 "register_operand" "f")
10805 (match_operand 2 "register_operand" "f")])
10806 (pc)
10807 (label_ref (match_operand 3 "" ""))))
10808 (clobber (reg:CCFP FPSR_REG))
10809 (clobber (reg:CCFP FLAGS_REG))
10810 (clobber (match_scratch:HI 4 "=a"))]
10811 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10812 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10813 && !TARGET_CMOVE"
10814 "#")
10815
10816 (define_insn "*fp_jcc_3_387"
10817 [(set (pc)
10818 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10819 [(match_operand 1 "register_operand" "f")
10820 (match_operand 2 "const0_operand" "")])
10821 (label_ref (match_operand 3 "" ""))
10822 (pc)))
10823 (clobber (reg:CCFP FPSR_REG))
10824 (clobber (reg:CCFP FLAGS_REG))
10825 (clobber (match_scratch:HI 4 "=a"))]
10826 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10827 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10828 && SELECT_CC_MODE (GET_CODE (operands[0]),
10829 operands[1], operands[2]) == CCFPmode
10830 && !TARGET_CMOVE"
10831 "#")
10832
10833 (define_split
10834 [(set (pc)
10835 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10836 [(match_operand 1 "register_operand" "")
10837 (match_operand 2 "nonimmediate_operand" "")])
10838 (match_operand 3 "" "")
10839 (match_operand 4 "" "")))
10840 (clobber (reg:CCFP FPSR_REG))
10841 (clobber (reg:CCFP FLAGS_REG))]
10842 "reload_completed"
10843 [(const_int 0)]
10844 {
10845 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10846 operands[3], operands[4], NULL_RTX, NULL_RTX);
10847 DONE;
10848 })
10849
10850 (define_split
10851 [(set (pc)
10852 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10853 [(match_operand 1 "register_operand" "")
10854 (match_operand 2 "general_operand" "")])
10855 (match_operand 3 "" "")
10856 (match_operand 4 "" "")))
10857 (clobber (reg:CCFP FPSR_REG))
10858 (clobber (reg:CCFP FLAGS_REG))
10859 (clobber (match_scratch:HI 5 "=a"))]
10860 "reload_completed"
10861 [(const_int 0)]
10862 {
10863 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10864 operands[3], operands[4], operands[5], NULL_RTX);
10865 DONE;
10866 })
10867
10868 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10869 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10870 ;; with a precedence over other operators and is always put in the first
10871 ;; place. Swap condition and operands to match ficom instruction.
10872
10873 (define_insn "*fp_jcc_4_<mode>_387"
10874 [(set (pc)
10875 (if_then_else
10876 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10877 [(match_operator 1 "float_operator"
10878 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10879 (match_operand 3 "register_operand" "f,f")])
10880 (label_ref (match_operand 4 "" ""))
10881 (pc)))
10882 (clobber (reg:CCFP FPSR_REG))
10883 (clobber (reg:CCFP FLAGS_REG))
10884 (clobber (match_scratch:HI 5 "=a,a"))]
10885 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10886 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10887 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10888 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10889 && !TARGET_CMOVE"
10890 "#")
10891
10892 (define_split
10893 [(set (pc)
10894 (if_then_else
10895 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10896 [(match_operator 1 "float_operator"
10897 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10898 (match_operand 3 "register_operand" "")])
10899 (match_operand 4 "" "")
10900 (match_operand 5 "" "")))
10901 (clobber (reg:CCFP FPSR_REG))
10902 (clobber (reg:CCFP FLAGS_REG))
10903 (clobber (match_scratch:HI 6 "=a"))]
10904 "reload_completed"
10905 [(const_int 0)]
10906 {
10907 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10908
10909 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10910 operands[3], operands[7],
10911 operands[4], operands[5], operands[6], NULL_RTX);
10912 DONE;
10913 })
10914
10915 ;; %%% Kill this when reload knows how to do it.
10916 (define_split
10917 [(set (pc)
10918 (if_then_else
10919 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10920 [(match_operator 1 "float_operator"
10921 [(match_operand:X87MODEI12 2 "register_operand" "")])
10922 (match_operand 3 "register_operand" "")])
10923 (match_operand 4 "" "")
10924 (match_operand 5 "" "")))
10925 (clobber (reg:CCFP FPSR_REG))
10926 (clobber (reg:CCFP FLAGS_REG))
10927 (clobber (match_scratch:HI 6 "=a"))]
10928 "reload_completed"
10929 [(const_int 0)]
10930 {
10931 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10932 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10933
10934 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10935 operands[3], operands[7],
10936 operands[4], operands[5], operands[6], operands[2]);
10937 DONE;
10938 })
10939 \f
10940 ;; Unconditional and other jump instructions
10941
10942 (define_insn "jump"
10943 [(set (pc)
10944 (label_ref (match_operand 0 "" "")))]
10945 ""
10946 "jmp\t%l0"
10947 [(set_attr "type" "ibr")
10948 (set (attr "length")
10949 (if_then_else (and (ge (minus (match_dup 0) (pc))
10950 (const_int -126))
10951 (lt (minus (match_dup 0) (pc))
10952 (const_int 128)))
10953 (const_int 2)
10954 (const_int 5)))
10955 (set_attr "modrm" "0")])
10956
10957 (define_expand "indirect_jump"
10958 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10959 ""
10960 "")
10961
10962 (define_insn "*indirect_jump"
10963 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10964 ""
10965 "jmp\t%A0"
10966 [(set_attr "type" "ibr")
10967 (set_attr "length_immediate" "0")])
10968
10969 (define_expand "tablejump"
10970 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10971 (use (label_ref (match_operand 1 "" "")))])]
10972 ""
10973 {
10974 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10975 relative. Convert the relative address to an absolute address. */
10976 if (flag_pic)
10977 {
10978 rtx op0, op1;
10979 enum rtx_code code;
10980
10981 /* We can't use @GOTOFF for text labels on VxWorks;
10982 see gotoff_operand. */
10983 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10984 {
10985 code = PLUS;
10986 op0 = operands[0];
10987 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10988 }
10989 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10990 {
10991 code = PLUS;
10992 op0 = operands[0];
10993 op1 = pic_offset_table_rtx;
10994 }
10995 else
10996 {
10997 code = MINUS;
10998 op0 = pic_offset_table_rtx;
10999 op1 = operands[0];
11000 }
11001
11002 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11003 OPTAB_DIRECT);
11004 }
11005 })
11006
11007 (define_insn "*tablejump_1"
11008 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11009 (use (label_ref (match_operand 1 "" "")))]
11010 ""
11011 "jmp\t%A0"
11012 [(set_attr "type" "ibr")
11013 (set_attr "length_immediate" "0")])
11014 \f
11015 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11016
11017 (define_peephole2
11018 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11019 (set (match_operand:QI 1 "register_operand" "")
11020 (match_operator:QI 2 "ix86_comparison_operator"
11021 [(reg FLAGS_REG) (const_int 0)]))
11022 (set (match_operand 3 "q_regs_operand" "")
11023 (zero_extend (match_dup 1)))]
11024 "(peep2_reg_dead_p (3, operands[1])
11025 || operands_match_p (operands[1], operands[3]))
11026 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11027 [(set (match_dup 4) (match_dup 0))
11028 (set (strict_low_part (match_dup 5))
11029 (match_dup 2))]
11030 {
11031 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11032 operands[5] = gen_lowpart (QImode, operands[3]);
11033 ix86_expand_clear (operands[3]);
11034 })
11035
11036 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11037
11038 (define_peephole2
11039 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11040 (set (match_operand:QI 1 "register_operand" "")
11041 (match_operator:QI 2 "ix86_comparison_operator"
11042 [(reg FLAGS_REG) (const_int 0)]))
11043 (parallel [(set (match_operand 3 "q_regs_operand" "")
11044 (zero_extend (match_dup 1)))
11045 (clobber (reg:CC FLAGS_REG))])]
11046 "(peep2_reg_dead_p (3, operands[1])
11047 || operands_match_p (operands[1], operands[3]))
11048 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11049 [(set (match_dup 4) (match_dup 0))
11050 (set (strict_low_part (match_dup 5))
11051 (match_dup 2))]
11052 {
11053 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11054 operands[5] = gen_lowpart (QImode, operands[3]);
11055 ix86_expand_clear (operands[3]);
11056 })
11057 \f
11058 ;; Call instructions.
11059
11060 ;; The predicates normally associated with named expanders are not properly
11061 ;; checked for calls. This is a bug in the generic code, but it isn't that
11062 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11063
11064 ;; P6 processors will jump to the address after the decrement when %esp
11065 ;; is used as a call operand, so they will execute return address as a code.
11066 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11067
11068 ;; Register constraint for call instruction.
11069 (define_mode_attr c [(SI "l") (DI "r")])
11070
11071 ;; Call subroutine returning no value.
11072
11073 (define_expand "call"
11074 [(call (match_operand:QI 0 "" "")
11075 (match_operand 1 "" ""))
11076 (use (match_operand 2 "" ""))]
11077 ""
11078 {
11079 ix86_expand_call (NULL, operands[0], operands[1],
11080 operands[2], NULL, false);
11081 DONE;
11082 })
11083
11084 (define_expand "sibcall"
11085 [(call (match_operand:QI 0 "" "")
11086 (match_operand 1 "" ""))
11087 (use (match_operand 2 "" ""))]
11088 ""
11089 {
11090 ix86_expand_call (NULL, operands[0], operands[1],
11091 operands[2], NULL, true);
11092 DONE;
11093 })
11094
11095 (define_insn_and_split "*call_vzeroupper"
11096 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11097 (match_operand 1 "" ""))
11098 (unspec [(match_operand 2 "const_int_operand" "")]
11099 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11100 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11101 "#"
11102 "&& reload_completed"
11103 [(const_int 0)]
11104 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11105 [(set_attr "type" "call")])
11106
11107 (define_insn "*call"
11108 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11109 (match_operand 1 "" ""))]
11110 "!SIBLING_CALL_P (insn)"
11111 "* return ix86_output_call_insn (insn, operands[0]);"
11112 [(set_attr "type" "call")])
11113
11114 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11115 [(parallel
11116 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11117 (match_operand 1 "" ""))
11118 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11119 (clobber (reg:TI XMM6_REG))
11120 (clobber (reg:TI XMM7_REG))
11121 (clobber (reg:TI XMM8_REG))
11122 (clobber (reg:TI XMM9_REG))
11123 (clobber (reg:TI XMM10_REG))
11124 (clobber (reg:TI XMM11_REG))
11125 (clobber (reg:TI XMM12_REG))
11126 (clobber (reg:TI XMM13_REG))
11127 (clobber (reg:TI XMM14_REG))
11128 (clobber (reg:TI XMM15_REG))
11129 (clobber (reg:DI SI_REG))
11130 (clobber (reg:DI DI_REG))])
11131 (unspec [(match_operand 2 "const_int_operand" "")]
11132 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11133 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11134 "#"
11135 "&& reload_completed"
11136 [(const_int 0)]
11137 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11138 [(set_attr "type" "call")])
11139
11140 (define_insn "*call_rex64_ms_sysv"
11141 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11142 (match_operand 1 "" ""))
11143 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11144 (clobber (reg:TI XMM6_REG))
11145 (clobber (reg:TI XMM7_REG))
11146 (clobber (reg:TI XMM8_REG))
11147 (clobber (reg:TI XMM9_REG))
11148 (clobber (reg:TI XMM10_REG))
11149 (clobber (reg:TI XMM11_REG))
11150 (clobber (reg:TI XMM12_REG))
11151 (clobber (reg:TI XMM13_REG))
11152 (clobber (reg:TI XMM14_REG))
11153 (clobber (reg:TI XMM15_REG))
11154 (clobber (reg:DI SI_REG))
11155 (clobber (reg:DI DI_REG))]
11156 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11157 "* return ix86_output_call_insn (insn, operands[0]);"
11158 [(set_attr "type" "call")])
11159
11160 (define_insn_and_split "*sibcall_vzeroupper"
11161 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11162 (match_operand 1 "" ""))
11163 (unspec [(match_operand 2 "const_int_operand" "")]
11164 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11165 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11166 "#"
11167 "&& reload_completed"
11168 [(const_int 0)]
11169 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11170 [(set_attr "type" "call")])
11171
11172 (define_insn "*sibcall"
11173 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11174 (match_operand 1 "" ""))]
11175 "SIBLING_CALL_P (insn)"
11176 "* return ix86_output_call_insn (insn, operands[0]);"
11177 [(set_attr "type" "call")])
11178
11179 (define_expand "call_pop"
11180 [(parallel [(call (match_operand:QI 0 "" "")
11181 (match_operand:SI 1 "" ""))
11182 (set (reg:SI SP_REG)
11183 (plus:SI (reg:SI SP_REG)
11184 (match_operand:SI 3 "" "")))])]
11185 "!TARGET_64BIT"
11186 {
11187 ix86_expand_call (NULL, operands[0], operands[1],
11188 operands[2], operands[3], false);
11189 DONE;
11190 })
11191
11192 (define_insn_and_split "*call_pop_vzeroupper"
11193 [(parallel
11194 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11195 (match_operand:SI 1 "" ""))
11196 (set (reg:SI SP_REG)
11197 (plus:SI (reg:SI SP_REG)
11198 (match_operand:SI 2 "immediate_operand" "i")))])
11199 (unspec [(match_operand 3 "const_int_operand" "")]
11200 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11201 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11202 "#"
11203 "&& reload_completed"
11204 [(const_int 0)]
11205 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11206 [(set_attr "type" "call")])
11207
11208 (define_insn "*call_pop"
11209 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11210 (match_operand 1 "" ""))
11211 (set (reg:SI SP_REG)
11212 (plus:SI (reg:SI SP_REG)
11213 (match_operand:SI 2 "immediate_operand" "i")))]
11214 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11215 "* return ix86_output_call_insn (insn, operands[0]);"
11216 [(set_attr "type" "call")])
11217
11218 (define_insn_and_split "*sibcall_pop_vzeroupper"
11219 [(parallel
11220 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11221 (match_operand 1 "" ""))
11222 (set (reg:SI SP_REG)
11223 (plus:SI (reg:SI SP_REG)
11224 (match_operand:SI 2 "immediate_operand" "i")))])
11225 (unspec [(match_operand 3 "const_int_operand" "")]
11226 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11227 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11228 "#"
11229 "&& reload_completed"
11230 [(const_int 0)]
11231 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11232 [(set_attr "type" "call")])
11233
11234 (define_insn "*sibcall_pop"
11235 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11236 (match_operand 1 "" ""))
11237 (set (reg:SI SP_REG)
11238 (plus:SI (reg:SI SP_REG)
11239 (match_operand:SI 2 "immediate_operand" "i")))]
11240 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11241 "* return ix86_output_call_insn (insn, operands[0]);"
11242 [(set_attr "type" "call")])
11243
11244 ;; Call subroutine, returning value in operand 0
11245
11246 (define_expand "call_value"
11247 [(set (match_operand 0 "" "")
11248 (call (match_operand:QI 1 "" "")
11249 (match_operand 2 "" "")))
11250 (use (match_operand 3 "" ""))]
11251 ""
11252 {
11253 ix86_expand_call (operands[0], operands[1], operands[2],
11254 operands[3], NULL, false);
11255 DONE;
11256 })
11257
11258 (define_expand "sibcall_value"
11259 [(set (match_operand 0 "" "")
11260 (call (match_operand:QI 1 "" "")
11261 (match_operand 2 "" "")))
11262 (use (match_operand 3 "" ""))]
11263 ""
11264 {
11265 ix86_expand_call (operands[0], operands[1], operands[2],
11266 operands[3], NULL, true);
11267 DONE;
11268 })
11269
11270 (define_insn_and_split "*call_value_vzeroupper"
11271 [(set (match_operand 0 "" "")
11272 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11273 (match_operand 2 "" "")))
11274 (unspec [(match_operand 3 "const_int_operand" "")]
11275 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11276 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11277 "#"
11278 "&& reload_completed"
11279 [(const_int 0)]
11280 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11281 [(set_attr "type" "callv")])
11282
11283 (define_insn "*call_value"
11284 [(set (match_operand 0 "" "")
11285 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11286 (match_operand 2 "" "")))]
11287 "!SIBLING_CALL_P (insn)"
11288 "* return ix86_output_call_insn (insn, operands[1]);"
11289 [(set_attr "type" "callv")])
11290
11291 (define_insn_and_split "*sibcall_value_vzeroupper"
11292 [(set (match_operand 0 "" "")
11293 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11294 (match_operand 2 "" "")))
11295 (unspec [(match_operand 3 "const_int_operand" "")]
11296 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11297 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11298 "#"
11299 "&& reload_completed"
11300 [(const_int 0)]
11301 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11302 [(set_attr "type" "callv")])
11303
11304 (define_insn "*sibcall_value"
11305 [(set (match_operand 0 "" "")
11306 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11307 (match_operand 2 "" "")))]
11308 "SIBLING_CALL_P (insn)"
11309 "* return ix86_output_call_insn (insn, operands[1]);"
11310 [(set_attr "type" "callv")])
11311
11312 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11313 [(parallel
11314 [(set (match_operand 0 "" "")
11315 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11316 (match_operand 2 "" "")))
11317 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11318 (clobber (reg:TI XMM6_REG))
11319 (clobber (reg:TI XMM7_REG))
11320 (clobber (reg:TI XMM8_REG))
11321 (clobber (reg:TI XMM9_REG))
11322 (clobber (reg:TI XMM10_REG))
11323 (clobber (reg:TI XMM11_REG))
11324 (clobber (reg:TI XMM12_REG))
11325 (clobber (reg:TI XMM13_REG))
11326 (clobber (reg:TI XMM14_REG))
11327 (clobber (reg:TI XMM15_REG))
11328 (clobber (reg:DI SI_REG))
11329 (clobber (reg:DI DI_REG))])
11330 (unspec [(match_operand 3 "const_int_operand" "")]
11331 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11332 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11333 "#"
11334 "&& reload_completed"
11335 [(const_int 0)]
11336 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11337 [(set_attr "type" "callv")])
11338
11339 (define_insn "*call_value_rex64_ms_sysv"
11340 [(set (match_operand 0 "" "")
11341 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11342 (match_operand 2 "" "")))
11343 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11344 (clobber (reg:TI XMM6_REG))
11345 (clobber (reg:TI XMM7_REG))
11346 (clobber (reg:TI XMM8_REG))
11347 (clobber (reg:TI XMM9_REG))
11348 (clobber (reg:TI XMM10_REG))
11349 (clobber (reg:TI XMM11_REG))
11350 (clobber (reg:TI XMM12_REG))
11351 (clobber (reg:TI XMM13_REG))
11352 (clobber (reg:TI XMM14_REG))
11353 (clobber (reg:TI XMM15_REG))
11354 (clobber (reg:DI SI_REG))
11355 (clobber (reg:DI DI_REG))]
11356 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11357 "* return ix86_output_call_insn (insn, operands[1]);"
11358 [(set_attr "type" "callv")])
11359
11360 (define_expand "call_value_pop"
11361 [(parallel [(set (match_operand 0 "" "")
11362 (call (match_operand:QI 1 "" "")
11363 (match_operand:SI 2 "" "")))
11364 (set (reg:SI SP_REG)
11365 (plus:SI (reg:SI SP_REG)
11366 (match_operand:SI 4 "" "")))])]
11367 "!TARGET_64BIT"
11368 {
11369 ix86_expand_call (operands[0], operands[1], operands[2],
11370 operands[3], operands[4], false);
11371 DONE;
11372 })
11373
11374 (define_insn_and_split "*call_value_pop_vzeroupper"
11375 [(parallel
11376 [(set (match_operand 0 "" "")
11377 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11378 (match_operand 2 "" "")))
11379 (set (reg:SI SP_REG)
11380 (plus:SI (reg:SI SP_REG)
11381 (match_operand:SI 3 "immediate_operand" "i")))])
11382 (unspec [(match_operand 4 "const_int_operand" "")]
11383 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11384 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11385 "#"
11386 "&& reload_completed"
11387 [(const_int 0)]
11388 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11389 [(set_attr "type" "callv")])
11390
11391 (define_insn "*call_value_pop"
11392 [(set (match_operand 0 "" "")
11393 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11394 (match_operand 2 "" "")))
11395 (set (reg:SI SP_REG)
11396 (plus:SI (reg:SI SP_REG)
11397 (match_operand:SI 3 "immediate_operand" "i")))]
11398 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11399 "* return ix86_output_call_insn (insn, operands[1]);"
11400 [(set_attr "type" "callv")])
11401
11402 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11403 [(parallel
11404 [(set (match_operand 0 "" "")
11405 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11406 (match_operand 2 "" "")))
11407 (set (reg:SI SP_REG)
11408 (plus:SI (reg:SI SP_REG)
11409 (match_operand:SI 3 "immediate_operand" "i")))])
11410 (unspec [(match_operand 4 "const_int_operand" "")]
11411 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11412 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11413 "#"
11414 "&& reload_completed"
11415 [(const_int 0)]
11416 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11417 [(set_attr "type" "callv")])
11418
11419 (define_insn "*sibcall_value_pop"
11420 [(set (match_operand 0 "" "")
11421 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11422 (match_operand 2 "" "")))
11423 (set (reg:SI SP_REG)
11424 (plus:SI (reg:SI SP_REG)
11425 (match_operand:SI 3 "immediate_operand" "i")))]
11426 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11427 "* return ix86_output_call_insn (insn, operands[1]);"
11428 [(set_attr "type" "callv")])
11429
11430 ;; Call subroutine returning any type.
11431
11432 (define_expand "untyped_call"
11433 [(parallel [(call (match_operand 0 "" "")
11434 (const_int 0))
11435 (match_operand 1 "" "")
11436 (match_operand 2 "" "")])]
11437 ""
11438 {
11439 int i;
11440
11441 /* In order to give reg-stack an easier job in validating two
11442 coprocessor registers as containing a possible return value,
11443 simply pretend the untyped call returns a complex long double
11444 value.
11445
11446 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11447 and should have the default ABI. */
11448
11449 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11450 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11451 operands[0], const0_rtx,
11452 GEN_INT ((TARGET_64BIT
11453 ? (ix86_abi == SYSV_ABI
11454 ? X86_64_SSE_REGPARM_MAX
11455 : X86_64_MS_SSE_REGPARM_MAX)
11456 : X86_32_SSE_REGPARM_MAX)
11457 - 1),
11458 NULL, false);
11459
11460 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11461 {
11462 rtx set = XVECEXP (operands[2], 0, i);
11463 emit_move_insn (SET_DEST (set), SET_SRC (set));
11464 }
11465
11466 /* The optimizer does not know that the call sets the function value
11467 registers we stored in the result block. We avoid problems by
11468 claiming that all hard registers are used and clobbered at this
11469 point. */
11470 emit_insn (gen_blockage ());
11471
11472 DONE;
11473 })
11474 \f
11475 ;; Prologue and epilogue instructions
11476
11477 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11478 ;; all of memory. This blocks insns from being moved across this point.
11479
11480 (define_insn "blockage"
11481 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11482 ""
11483 ""
11484 [(set_attr "length" "0")])
11485
11486 ;; Do not schedule instructions accessing memory across this point.
11487
11488 (define_expand "memory_blockage"
11489 [(set (match_dup 0)
11490 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11491 ""
11492 {
11493 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11494 MEM_VOLATILE_P (operands[0]) = 1;
11495 })
11496
11497 (define_insn "*memory_blockage"
11498 [(set (match_operand:BLK 0 "" "")
11499 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11500 ""
11501 ""
11502 [(set_attr "length" "0")])
11503
11504 ;; As USE insns aren't meaningful after reload, this is used instead
11505 ;; to prevent deleting instructions setting registers for PIC code
11506 (define_insn "prologue_use"
11507 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11508 ""
11509 ""
11510 [(set_attr "length" "0")])
11511
11512 ;; Insn emitted into the body of a function to return from a function.
11513 ;; This is only done if the function's epilogue is known to be simple.
11514 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11515
11516 (define_expand "return"
11517 [(return)]
11518 "ix86_can_use_return_insn_p ()"
11519 {
11520 if (crtl->args.pops_args)
11521 {
11522 rtx popc = GEN_INT (crtl->args.pops_args);
11523 emit_jump_insn (gen_return_pop_internal (popc));
11524 DONE;
11525 }
11526 })
11527
11528 (define_insn "return_internal"
11529 [(return)]
11530 "reload_completed"
11531 "ret"
11532 [(set_attr "length" "1")
11533 (set_attr "atom_unit" "jeu")
11534 (set_attr "length_immediate" "0")
11535 (set_attr "modrm" "0")])
11536
11537 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11538 ;; instruction Athlon and K8 have.
11539
11540 (define_insn "return_internal_long"
11541 [(return)
11542 (unspec [(const_int 0)] UNSPEC_REP)]
11543 "reload_completed"
11544 "rep\;ret"
11545 [(set_attr "length" "2")
11546 (set_attr "atom_unit" "jeu")
11547 (set_attr "length_immediate" "0")
11548 (set_attr "prefix_rep" "1")
11549 (set_attr "modrm" "0")])
11550
11551 (define_insn "return_pop_internal"
11552 [(return)
11553 (use (match_operand:SI 0 "const_int_operand" ""))]
11554 "reload_completed"
11555 "ret\t%0"
11556 [(set_attr "length" "3")
11557 (set_attr "atom_unit" "jeu")
11558 (set_attr "length_immediate" "2")
11559 (set_attr "modrm" "0")])
11560
11561 (define_insn "return_indirect_internal"
11562 [(return)
11563 (use (match_operand:SI 0 "register_operand" "r"))]
11564 "reload_completed"
11565 "jmp\t%A0"
11566 [(set_attr "type" "ibr")
11567 (set_attr "length_immediate" "0")])
11568
11569 (define_insn "nop"
11570 [(const_int 0)]
11571 ""
11572 "nop"
11573 [(set_attr "length" "1")
11574 (set_attr "length_immediate" "0")
11575 (set_attr "modrm" "0")])
11576
11577 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11578 (define_insn "nops"
11579 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11580 UNSPECV_NOPS)]
11581 "reload_completed"
11582 {
11583 int num = INTVAL (operands[0]);
11584
11585 gcc_assert (num >= 1 && num <= 8);
11586
11587 while (num--)
11588 fputs ("\tnop\n", asm_out_file);
11589
11590 return "";
11591 }
11592 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11593 (set_attr "length_immediate" "0")
11594 (set_attr "modrm" "0")])
11595
11596 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11597 ;; branch prediction penalty for the third jump in a 16-byte
11598 ;; block on K8.
11599
11600 (define_insn "pad"
11601 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11602 ""
11603 {
11604 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11605 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11606 #else
11607 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11608 The align insn is used to avoid 3 jump instructions in the row to improve
11609 branch prediction and the benefits hardly outweigh the cost of extra 8
11610 nops on the average inserted by full alignment pseudo operation. */
11611 #endif
11612 return "";
11613 }
11614 [(set_attr "length" "16")])
11615
11616 (define_expand "prologue"
11617 [(const_int 0)]
11618 ""
11619 "ix86_expand_prologue (); DONE;")
11620
11621 (define_insn "set_got"
11622 [(set (match_operand:SI 0 "register_operand" "=r")
11623 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11624 (clobber (reg:CC FLAGS_REG))]
11625 "!TARGET_64BIT"
11626 "* return output_set_got (operands[0], NULL_RTX);"
11627 [(set_attr "type" "multi")
11628 (set_attr "length" "12")])
11629
11630 (define_insn "set_got_labelled"
11631 [(set (match_operand:SI 0 "register_operand" "=r")
11632 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11633 UNSPEC_SET_GOT))
11634 (clobber (reg:CC FLAGS_REG))]
11635 "!TARGET_64BIT"
11636 "* return output_set_got (operands[0], operands[1]);"
11637 [(set_attr "type" "multi")
11638 (set_attr "length" "12")])
11639
11640 (define_insn "set_got_rex64"
11641 [(set (match_operand:DI 0 "register_operand" "=r")
11642 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11643 "TARGET_64BIT"
11644 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11645 [(set_attr "type" "lea")
11646 (set_attr "length_address" "4")
11647 (set_attr "mode" "DI")])
11648
11649 (define_insn "set_rip_rex64"
11650 [(set (match_operand:DI 0 "register_operand" "=r")
11651 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11652 "TARGET_64BIT"
11653 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11654 [(set_attr "type" "lea")
11655 (set_attr "length_address" "4")
11656 (set_attr "mode" "DI")])
11657
11658 (define_insn "set_got_offset_rex64"
11659 [(set (match_operand:DI 0 "register_operand" "=r")
11660 (unspec:DI
11661 [(label_ref (match_operand 1 "" ""))]
11662 UNSPEC_SET_GOT_OFFSET))]
11663 "TARGET_64BIT"
11664 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11665 [(set_attr "type" "imov")
11666 (set_attr "length_immediate" "0")
11667 (set_attr "length_address" "8")
11668 (set_attr "mode" "DI")])
11669
11670 (define_expand "epilogue"
11671 [(const_int 0)]
11672 ""
11673 "ix86_expand_epilogue (1); DONE;")
11674
11675 (define_expand "sibcall_epilogue"
11676 [(const_int 0)]
11677 ""
11678 "ix86_expand_epilogue (0); DONE;")
11679
11680 (define_expand "eh_return"
11681 [(use (match_operand 0 "register_operand" ""))]
11682 ""
11683 {
11684 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11685
11686 /* Tricky bit: we write the address of the handler to which we will
11687 be returning into someone else's stack frame, one word below the
11688 stack address we wish to restore. */
11689 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11690 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11691 tmp = gen_rtx_MEM (Pmode, tmp);
11692 emit_move_insn (tmp, ra);
11693
11694 emit_jump_insn (gen_eh_return_internal ());
11695 emit_barrier ();
11696 DONE;
11697 })
11698
11699 (define_insn_and_split "eh_return_internal"
11700 [(eh_return)]
11701 ""
11702 "#"
11703 "epilogue_completed"
11704 [(const_int 0)]
11705 "ix86_expand_epilogue (2); DONE;")
11706
11707 (define_insn "leave"
11708 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11709 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11710 (clobber (mem:BLK (scratch)))]
11711 "!TARGET_64BIT"
11712 "leave"
11713 [(set_attr "type" "leave")])
11714
11715 (define_insn "leave_rex64"
11716 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11717 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11718 (clobber (mem:BLK (scratch)))]
11719 "TARGET_64BIT"
11720 "leave"
11721 [(set_attr "type" "leave")])
11722 \f
11723 ;; Handle -fsplit-stack.
11724
11725 (define_expand "split_stack_prologue"
11726 [(const_int 0)]
11727 ""
11728 {
11729 ix86_expand_split_stack_prologue ();
11730 DONE;
11731 })
11732
11733 ;; In order to support the call/return predictor, we use a return
11734 ;; instruction which the middle-end doesn't see.
11735 (define_insn "split_stack_return"
11736 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11737 UNSPECV_SPLIT_STACK_RETURN)]
11738 ""
11739 {
11740 if (operands[0] == const0_rtx)
11741 return "ret";
11742 else
11743 return "ret\t%0";
11744 }
11745 [(set_attr "atom_unit" "jeu")
11746 (set_attr "modrm" "0")
11747 (set (attr "length")
11748 (if_then_else (match_operand:SI 0 "const0_operand" "")
11749 (const_int 1)
11750 (const_int 3)))
11751 (set (attr "length_immediate")
11752 (if_then_else (match_operand:SI 0 "const0_operand" "")
11753 (const_int 0)
11754 (const_int 2)))])
11755
11756 ;; If there are operand 0 bytes available on the stack, jump to
11757 ;; operand 1.
11758
11759 (define_expand "split_stack_space_check"
11760 [(set (pc) (if_then_else
11761 (ltu (minus (reg SP_REG)
11762 (match_operand 0 "register_operand" ""))
11763 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11764 (label_ref (match_operand 1 "" ""))
11765 (pc)))]
11766 ""
11767 {
11768 rtx reg, size, limit;
11769
11770 reg = gen_reg_rtx (Pmode);
11771 size = force_reg (Pmode, operands[0]);
11772 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11773 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11774 UNSPEC_STACK_CHECK);
11775 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11776 ix86_expand_branch (GEU, reg, limit, operands[1]);
11777
11778 DONE;
11779 })
11780 \f
11781 ;; Bit manipulation instructions.
11782
11783 (define_expand "ffs<mode>2"
11784 [(set (match_dup 2) (const_int -1))
11785 (parallel [(set (reg:CCZ FLAGS_REG)
11786 (compare:CCZ
11787 (match_operand:SWI48 1 "nonimmediate_operand" "")
11788 (const_int 0)))
11789 (set (match_operand:SWI48 0 "register_operand" "")
11790 (ctz:SWI48 (match_dup 1)))])
11791 (set (match_dup 0) (if_then_else:SWI48
11792 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11793 (match_dup 2)
11794 (match_dup 0)))
11795 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11796 (clobber (reg:CC FLAGS_REG))])]
11797 ""
11798 {
11799 if (<MODE>mode == SImode && !TARGET_CMOVE)
11800 {
11801 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11802 DONE;
11803 }
11804 operands[2] = gen_reg_rtx (<MODE>mode);
11805 })
11806
11807 (define_insn_and_split "ffssi2_no_cmove"
11808 [(set (match_operand:SI 0 "register_operand" "=r")
11809 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11810 (clobber (match_scratch:SI 2 "=&q"))
11811 (clobber (reg:CC FLAGS_REG))]
11812 "!TARGET_CMOVE"
11813 "#"
11814 "&& reload_completed"
11815 [(parallel [(set (reg:CCZ FLAGS_REG)
11816 (compare:CCZ (match_dup 1) (const_int 0)))
11817 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11818 (set (strict_low_part (match_dup 3))
11819 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11820 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11821 (clobber (reg:CC FLAGS_REG))])
11822 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11823 (clobber (reg:CC FLAGS_REG))])
11824 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11825 (clobber (reg:CC FLAGS_REG))])]
11826 {
11827 operands[3] = gen_lowpart (QImode, operands[2]);
11828 ix86_expand_clear (operands[2]);
11829 })
11830
11831 (define_insn "*ffs<mode>_1"
11832 [(set (reg:CCZ FLAGS_REG)
11833 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11834 (const_int 0)))
11835 (set (match_operand:SWI48 0 "register_operand" "=r")
11836 (ctz:SWI48 (match_dup 1)))]
11837 ""
11838 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11839 [(set_attr "type" "alu1")
11840 (set_attr "prefix_0f" "1")
11841 (set_attr "mode" "<MODE>")])
11842
11843 (define_insn "ctz<mode>2"
11844 [(set (match_operand:SWI248 0 "register_operand" "=r")
11845 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11846 (clobber (reg:CC FLAGS_REG))]
11847 ""
11848 {
11849 if (TARGET_BMI)
11850 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11851 else
11852 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11853 }
11854 [(set_attr "type" "alu1")
11855 (set_attr "prefix_0f" "1")
11856 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11857 (set_attr "mode" "<MODE>")])
11858
11859 (define_expand "clz<mode>2"
11860 [(parallel
11861 [(set (match_operand:SWI248 0 "register_operand" "")
11862 (minus:SWI248
11863 (match_dup 2)
11864 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11865 (clobber (reg:CC FLAGS_REG))])
11866 (parallel
11867 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11868 (clobber (reg:CC FLAGS_REG))])]
11869 ""
11870 {
11871 if (TARGET_ABM)
11872 {
11873 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11874 DONE;
11875 }
11876 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11877 })
11878
11879 (define_insn "clz<mode>2_abm"
11880 [(set (match_operand:SWI248 0 "register_operand" "=r")
11881 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11882 (clobber (reg:CC FLAGS_REG))]
11883 "TARGET_ABM || TARGET_BMI"
11884 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11885 [(set_attr "prefix_rep" "1")
11886 (set_attr "type" "bitmanip")
11887 (set_attr "mode" "<MODE>")])
11888
11889 ;; BMI instructions.
11890 (define_insn "*bmi_andn_<mode>"
11891 [(set (match_operand:SWI48 0 "register_operand" "=r")
11892 (and:SWI48
11893 (not:SWI48
11894 (match_operand:SWI48 1 "register_operand" "r"))
11895 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11896 (clobber (reg:CC FLAGS_REG))]
11897 "TARGET_BMI"
11898 "andn\t{%2, %1, %0|%0, %1, %2}"
11899 [(set_attr "type" "bitmanip")
11900 (set_attr "mode" "<MODE>")])
11901
11902 (define_insn "bmi_bextr_<mode>"
11903 [(set (match_operand:SWI48 0 "register_operand" "=r")
11904 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11905 (match_operand:SWI48 2 "register_operand" "r")]
11906 UNSPEC_BEXTR))
11907 (clobber (reg:CC FLAGS_REG))]
11908 "TARGET_BMI"
11909 "bextr\t{%2, %1, %0|%0, %1, %2}"
11910 [(set_attr "type" "bitmanip")
11911 (set_attr "mode" "<MODE>")])
11912
11913 (define_insn "*bmi_blsi_<mode>"
11914 [(set (match_operand:SWI48 0 "register_operand" "=r")
11915 (and:SWI48
11916 (neg:SWI48
11917 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11918 (match_dup 1)))
11919 (clobber (reg:CC FLAGS_REG))]
11920 "TARGET_BMI"
11921 "blsi\t{%1, %0|%0, %1}"
11922 [(set_attr "type" "bitmanip")
11923 (set_attr "mode" "<MODE>")])
11924
11925 (define_insn "*bmi_blsmsk_<mode>"
11926 [(set (match_operand:SWI48 0 "register_operand" "=r")
11927 (xor:SWI48
11928 (plus:SWI48
11929 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11930 (const_int -1))
11931 (match_dup 1)))
11932 (clobber (reg:CC FLAGS_REG))]
11933 "TARGET_BMI"
11934 "blsmsk\t{%1, %0|%0, %1}"
11935 [(set_attr "type" "bitmanip")
11936 (set_attr "mode" "<MODE>")])
11937
11938 (define_insn "*bmi_blsr_<mode>"
11939 [(set (match_operand:SWI48 0 "register_operand" "=r")
11940 (and:SWI48
11941 (plus:SWI48
11942 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11943 (const_int -1))
11944 (match_dup 1)))
11945 (clobber (reg:CC FLAGS_REG))]
11946 "TARGET_BMI"
11947 "blsr\t{%1, %0|%0, %1}"
11948 [(set_attr "type" "bitmanip")
11949 (set_attr "mode" "<MODE>")])
11950
11951 ;; TBM instructions.
11952 (define_insn "tbm_bextri_<mode>"
11953 [(set (match_operand:SWI48 0 "register_operand" "=r")
11954 (zero_extract:SWI48
11955 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11956 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11957 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11958 (clobber (reg:CC FLAGS_REG))]
11959 "TARGET_TBM"
11960 {
11961 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11962 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11963 }
11964 [(set_attr "type" "bitmanip")
11965 (set_attr "mode" "<MODE>")])
11966
11967 (define_insn "*tbm_blcfill_<mode>"
11968 [(set (match_operand:SWI48 0 "register_operand" "=r")
11969 (and:SWI48
11970 (plus:SWI48
11971 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11972 (const_int 1))
11973 (match_dup 1)))
11974 (clobber (reg:CC FLAGS_REG))]
11975 "TARGET_TBM"
11976 "blcfill\t{%1, %0|%0, %1}"
11977 [(set_attr "type" "bitmanip")
11978 (set_attr "mode" "<MODE>")])
11979
11980 (define_insn "*tbm_blci_<mode>"
11981 [(set (match_operand:SWI48 0 "register_operand" "=r")
11982 (ior:SWI48
11983 (not:SWI48
11984 (plus:SWI48
11985 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11986 (const_int 1)))
11987 (match_dup 1)))
11988 (clobber (reg:CC FLAGS_REG))]
11989 "TARGET_TBM"
11990 "blci\t{%1, %0|%0, %1}"
11991 [(set_attr "type" "bitmanip")
11992 (set_attr "mode" "<MODE>")])
11993
11994 (define_insn "*tbm_blcic_<mode>"
11995 [(set (match_operand:SWI48 0 "register_operand" "=r")
11996 (and:SWI48
11997 (plus:SWI48
11998 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11999 (const_int 1))
12000 (not:SWI48
12001 (match_dup 1))))
12002 (clobber (reg:CC FLAGS_REG))]
12003 "TARGET_TBM"
12004 "blcic\t{%1, %0|%0, %1}"
12005 [(set_attr "type" "bitmanip")
12006 (set_attr "mode" "<MODE>")])
12007
12008 (define_insn "*tbm_blcmsk_<mode>"
12009 [(set (match_operand:SWI48 0 "register_operand" "=r")
12010 (xor:SWI48
12011 (plus:SWI48
12012 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12013 (const_int 1))
12014 (match_dup 1)))
12015 (clobber (reg:CC FLAGS_REG))]
12016 "TARGET_TBM"
12017 "blcmsk\t{%1, %0|%0, %1}"
12018 [(set_attr "type" "bitmanip")
12019 (set_attr "mode" "<MODE>")])
12020
12021 (define_insn "*tbm_blcs_<mode>"
12022 [(set (match_operand:SWI48 0 "register_operand" "=r")
12023 (ior:SWI48
12024 (plus:SWI48
12025 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12026 (const_int 1))
12027 (match_dup 1)))
12028 (clobber (reg:CC FLAGS_REG))]
12029 "TARGET_TBM"
12030 "blcs\t{%1, %0|%0, %1}"
12031 [(set_attr "type" "bitmanip")
12032 (set_attr "mode" "<MODE>")])
12033
12034 (define_insn "*tbm_blsfill_<mode>"
12035 [(set (match_operand:SWI48 0 "register_operand" "=r")
12036 (ior:SWI48
12037 (plus:SWI48
12038 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12039 (const_int -1))
12040 (match_dup 1)))
12041 (clobber (reg:CC FLAGS_REG))]
12042 "TARGET_TBM"
12043 "blsfill\t{%1, %0|%0, %1}"
12044 [(set_attr "type" "bitmanip")
12045 (set_attr "mode" "<MODE>")])
12046
12047 (define_insn "*tbm_blsic_<mode>"
12048 [(set (match_operand:SWI48 0 "register_operand" "=r")
12049 (ior:SWI48
12050 (plus:SWI48
12051 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12052 (const_int -1))
12053 (not:SWI48
12054 (match_dup 1))))
12055 (clobber (reg:CC FLAGS_REG))]
12056 "TARGET_TBM"
12057 "blsic\t{%1, %0|%0, %1}"
12058 [(set_attr "type" "bitmanip")
12059 (set_attr "mode" "<MODE>")])
12060
12061 (define_insn "*tbm_t1mskc_<mode>"
12062 [(set (match_operand:SWI48 0 "register_operand" "=r")
12063 (ior:SWI48
12064 (plus:SWI48
12065 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12066 (const_int 1))
12067 (not:SWI48
12068 (match_dup 1))))
12069 (clobber (reg:CC FLAGS_REG))]
12070 "TARGET_TBM"
12071 "t1mskc\t{%1, %0|%0, %1}"
12072 [(set_attr "type" "bitmanip")
12073 (set_attr "mode" "<MODE>")])
12074
12075 (define_insn "*tbm_tzmsk_<mode>"
12076 [(set (match_operand:SWI48 0 "register_operand" "=r")
12077 (and:SWI48
12078 (plus:SWI48
12079 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12080 (const_int -1))
12081 (not:SWI48
12082 (match_dup 1))))
12083 (clobber (reg:CC FLAGS_REG))]
12084 "TARGET_TBM"
12085 "tzmsk\t{%1, %0|%0, %1}"
12086 [(set_attr "type" "bitmanip")
12087 (set_attr "mode" "<MODE>")])
12088
12089 (define_insn "bsr_rex64"
12090 [(set (match_operand:DI 0 "register_operand" "=r")
12091 (minus:DI (const_int 63)
12092 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12093 (clobber (reg:CC FLAGS_REG))]
12094 "TARGET_64BIT"
12095 "bsr{q}\t{%1, %0|%0, %1}"
12096 [(set_attr "type" "alu1")
12097 (set_attr "prefix_0f" "1")
12098 (set_attr "mode" "DI")])
12099
12100 (define_insn "bsr"
12101 [(set (match_operand:SI 0 "register_operand" "=r")
12102 (minus:SI (const_int 31)
12103 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12104 (clobber (reg:CC FLAGS_REG))]
12105 ""
12106 "bsr{l}\t{%1, %0|%0, %1}"
12107 [(set_attr "type" "alu1")
12108 (set_attr "prefix_0f" "1")
12109 (set_attr "mode" "SI")])
12110
12111 (define_insn "*bsrhi"
12112 [(set (match_operand:HI 0 "register_operand" "=r")
12113 (minus:HI (const_int 15)
12114 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12115 (clobber (reg:CC FLAGS_REG))]
12116 ""
12117 "bsr{w}\t{%1, %0|%0, %1}"
12118 [(set_attr "type" "alu1")
12119 (set_attr "prefix_0f" "1")
12120 (set_attr "mode" "HI")])
12121
12122 (define_insn "popcount<mode>2"
12123 [(set (match_operand:SWI248 0 "register_operand" "=r")
12124 (popcount:SWI248
12125 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12126 (clobber (reg:CC FLAGS_REG))]
12127 "TARGET_POPCNT"
12128 {
12129 #if TARGET_MACHO
12130 return "popcnt\t{%1, %0|%0, %1}";
12131 #else
12132 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12133 #endif
12134 }
12135 [(set_attr "prefix_rep" "1")
12136 (set_attr "type" "bitmanip")
12137 (set_attr "mode" "<MODE>")])
12138
12139 (define_insn "*popcount<mode>2_cmp"
12140 [(set (reg FLAGS_REG)
12141 (compare
12142 (popcount:SWI248
12143 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12144 (const_int 0)))
12145 (set (match_operand:SWI248 0 "register_operand" "=r")
12146 (popcount:SWI248 (match_dup 1)))]
12147 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12148 {
12149 #if TARGET_MACHO
12150 return "popcnt\t{%1, %0|%0, %1}";
12151 #else
12152 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12153 #endif
12154 }
12155 [(set_attr "prefix_rep" "1")
12156 (set_attr "type" "bitmanip")
12157 (set_attr "mode" "<MODE>")])
12158
12159 (define_insn "*popcountsi2_cmp_zext"
12160 [(set (reg FLAGS_REG)
12161 (compare
12162 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12163 (const_int 0)))
12164 (set (match_operand:DI 0 "register_operand" "=r")
12165 (zero_extend:DI(popcount:SI (match_dup 1))))]
12166 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12167 {
12168 #if TARGET_MACHO
12169 return "popcnt\t{%1, %0|%0, %1}";
12170 #else
12171 return "popcnt{l}\t{%1, %0|%0, %1}";
12172 #endif
12173 }
12174 [(set_attr "prefix_rep" "1")
12175 (set_attr "type" "bitmanip")
12176 (set_attr "mode" "SI")])
12177
12178 (define_expand "bswap<mode>2"
12179 [(set (match_operand:SWI48 0 "register_operand" "")
12180 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12181 ""
12182 {
12183 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12184 {
12185 rtx x = operands[0];
12186
12187 emit_move_insn (x, operands[1]);
12188 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12189 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12190 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12191 DONE;
12192 }
12193 })
12194
12195 (define_insn "*bswap<mode>2_movbe"
12196 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12197 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12198 "TARGET_MOVBE
12199 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12200 "@
12201 bswap\t%0
12202 movbe\t{%1, %0|%0, %1}
12203 movbe\t{%1, %0|%0, %1}"
12204 [(set_attr "type" "bitmanip,imov,imov")
12205 (set_attr "modrm" "0,1,1")
12206 (set_attr "prefix_0f" "*,1,1")
12207 (set_attr "prefix_extra" "*,1,1")
12208 (set_attr "mode" "<MODE>")])
12209
12210 (define_insn "*bswap<mode>2_1"
12211 [(set (match_operand:SWI48 0 "register_operand" "=r")
12212 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12213 "TARGET_BSWAP"
12214 "bswap\t%0"
12215 [(set_attr "type" "bitmanip")
12216 (set_attr "modrm" "0")
12217 (set_attr "mode" "<MODE>")])
12218
12219 (define_insn "*bswaphi_lowpart_1"
12220 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12221 (bswap:HI (match_dup 0)))
12222 (clobber (reg:CC FLAGS_REG))]
12223 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12224 "@
12225 xchg{b}\t{%h0, %b0|%b0, %h0}
12226 rol{w}\t{$8, %0|%0, 8}"
12227 [(set_attr "length" "2,4")
12228 (set_attr "mode" "QI,HI")])
12229
12230 (define_insn "bswaphi_lowpart"
12231 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12232 (bswap:HI (match_dup 0)))
12233 (clobber (reg:CC FLAGS_REG))]
12234 ""
12235 "rol{w}\t{$8, %0|%0, 8}"
12236 [(set_attr "length" "4")
12237 (set_attr "mode" "HI")])
12238
12239 (define_expand "paritydi2"
12240 [(set (match_operand:DI 0 "register_operand" "")
12241 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12242 "! TARGET_POPCNT"
12243 {
12244 rtx scratch = gen_reg_rtx (QImode);
12245 rtx cond;
12246
12247 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12248 NULL_RTX, operands[1]));
12249
12250 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12251 gen_rtx_REG (CCmode, FLAGS_REG),
12252 const0_rtx);
12253 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12254
12255 if (TARGET_64BIT)
12256 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12257 else
12258 {
12259 rtx tmp = gen_reg_rtx (SImode);
12260
12261 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12262 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12263 }
12264 DONE;
12265 })
12266
12267 (define_expand "paritysi2"
12268 [(set (match_operand:SI 0 "register_operand" "")
12269 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12270 "! TARGET_POPCNT"
12271 {
12272 rtx scratch = gen_reg_rtx (QImode);
12273 rtx cond;
12274
12275 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12276
12277 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12278 gen_rtx_REG (CCmode, FLAGS_REG),
12279 const0_rtx);
12280 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12281
12282 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12283 DONE;
12284 })
12285
12286 (define_insn_and_split "paritydi2_cmp"
12287 [(set (reg:CC FLAGS_REG)
12288 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12289 UNSPEC_PARITY))
12290 (clobber (match_scratch:DI 0 "=r"))
12291 (clobber (match_scratch:SI 1 "=&r"))
12292 (clobber (match_scratch:HI 2 "=Q"))]
12293 "! TARGET_POPCNT"
12294 "#"
12295 "&& reload_completed"
12296 [(parallel
12297 [(set (match_dup 1)
12298 (xor:SI (match_dup 1) (match_dup 4)))
12299 (clobber (reg:CC FLAGS_REG))])
12300 (parallel
12301 [(set (reg:CC FLAGS_REG)
12302 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12303 (clobber (match_dup 1))
12304 (clobber (match_dup 2))])]
12305 {
12306 operands[4] = gen_lowpart (SImode, operands[3]);
12307
12308 if (TARGET_64BIT)
12309 {
12310 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12311 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12312 }
12313 else
12314 operands[1] = gen_highpart (SImode, operands[3]);
12315 })
12316
12317 (define_insn_and_split "paritysi2_cmp"
12318 [(set (reg:CC FLAGS_REG)
12319 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12320 UNSPEC_PARITY))
12321 (clobber (match_scratch:SI 0 "=r"))
12322 (clobber (match_scratch:HI 1 "=&Q"))]
12323 "! TARGET_POPCNT"
12324 "#"
12325 "&& reload_completed"
12326 [(parallel
12327 [(set (match_dup 1)
12328 (xor:HI (match_dup 1) (match_dup 3)))
12329 (clobber (reg:CC FLAGS_REG))])
12330 (parallel
12331 [(set (reg:CC FLAGS_REG)
12332 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12333 (clobber (match_dup 1))])]
12334 {
12335 operands[3] = gen_lowpart (HImode, operands[2]);
12336
12337 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12338 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12339 })
12340
12341 (define_insn "*parityhi2_cmp"
12342 [(set (reg:CC FLAGS_REG)
12343 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12344 UNSPEC_PARITY))
12345 (clobber (match_scratch:HI 0 "=Q"))]
12346 "! TARGET_POPCNT"
12347 "xor{b}\t{%h0, %b0|%b0, %h0}"
12348 [(set_attr "length" "2")
12349 (set_attr "mode" "HI")])
12350 \f
12351 ;; Thread-local storage patterns for ELF.
12352 ;;
12353 ;; Note that these code sequences must appear exactly as shown
12354 ;; in order to allow linker relaxation.
12355
12356 (define_insn "*tls_global_dynamic_32_gnu"
12357 [(set (match_operand:SI 0 "register_operand" "=a")
12358 (unspec:SI
12359 [(match_operand:SI 1 "register_operand" "b")
12360 (match_operand:SI 2 "tls_symbolic_operand" "")
12361 (match_operand:SI 3 "constant_call_address_operand" "z")]
12362 UNSPEC_TLS_GD))
12363 (clobber (match_scratch:SI 4 "=d"))
12364 (clobber (match_scratch:SI 5 "=c"))
12365 (clobber (reg:CC FLAGS_REG))]
12366 "!TARGET_64BIT && TARGET_GNU_TLS"
12367 {
12368 output_asm_insn
12369 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12370 return "call\t%P3";
12371 }
12372 [(set_attr "type" "multi")
12373 (set_attr "length" "12")])
12374
12375 (define_expand "tls_global_dynamic_32"
12376 [(parallel
12377 [(set (match_operand:SI 0 "register_operand" "")
12378 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12379 (match_operand:SI 1 "tls_symbolic_operand" "")
12380 (match_operand:SI 3 "constant_call_address_operand" "")]
12381 UNSPEC_TLS_GD))
12382 (clobber (match_scratch:SI 4 ""))
12383 (clobber (match_scratch:SI 5 ""))
12384 (clobber (reg:CC FLAGS_REG))])])
12385
12386 (define_insn "*tls_global_dynamic_64"
12387 [(set (match_operand:DI 0 "register_operand" "=a")
12388 (call:DI
12389 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12390 (match_operand:DI 3 "" "")))
12391 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12392 UNSPEC_TLS_GD)]
12393 "TARGET_64BIT"
12394 {
12395 fputs (ASM_BYTE "0x66\n", asm_out_file);
12396 output_asm_insn
12397 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12398 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12399 fputs ("\trex64\n", asm_out_file);
12400 return "call\t%P2";
12401 }
12402 [(set_attr "type" "multi")
12403 (set_attr "length" "16")])
12404
12405 (define_expand "tls_global_dynamic_64"
12406 [(parallel
12407 [(set (match_operand:DI 0 "register_operand" "")
12408 (call:DI
12409 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12410 (const_int 0)))
12411 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12412 UNSPEC_TLS_GD)])])
12413
12414 (define_insn "*tls_local_dynamic_base_32_gnu"
12415 [(set (match_operand:SI 0 "register_operand" "=a")
12416 (unspec:SI
12417 [(match_operand:SI 1 "register_operand" "b")
12418 (match_operand:SI 2 "constant_call_address_operand" "z")]
12419 UNSPEC_TLS_LD_BASE))
12420 (clobber (match_scratch:SI 3 "=d"))
12421 (clobber (match_scratch:SI 4 "=c"))
12422 (clobber (reg:CC FLAGS_REG))]
12423 "!TARGET_64BIT && TARGET_GNU_TLS"
12424 {
12425 output_asm_insn
12426 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12427 return "call\t%P2";
12428 }
12429 [(set_attr "type" "multi")
12430 (set_attr "length" "11")])
12431
12432 (define_expand "tls_local_dynamic_base_32"
12433 [(parallel
12434 [(set (match_operand:SI 0 "register_operand" "")
12435 (unspec:SI
12436 [(match_operand:SI 1 "register_operand" "")
12437 (match_operand:SI 2 "constant_call_address_operand" "")]
12438 UNSPEC_TLS_LD_BASE))
12439 (clobber (match_scratch:SI 3 ""))
12440 (clobber (match_scratch:SI 4 ""))
12441 (clobber (reg:CC FLAGS_REG))])])
12442
12443 (define_insn "*tls_local_dynamic_base_64"
12444 [(set (match_operand:DI 0 "register_operand" "=a")
12445 (call:DI
12446 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12447 (match_operand:DI 2 "" "")))
12448 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12449 "TARGET_64BIT"
12450 {
12451 output_asm_insn
12452 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12453 return "call\t%P1";
12454 }
12455 [(set_attr "type" "multi")
12456 (set_attr "length" "12")])
12457
12458 (define_expand "tls_local_dynamic_base_64"
12459 [(parallel
12460 [(set (match_operand:DI 0 "register_operand" "")
12461 (call:DI
12462 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12463 (const_int 0)))
12464 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12465
12466 ;; Local dynamic of a single variable is a lose. Show combine how
12467 ;; to convert that back to global dynamic.
12468
12469 (define_insn_and_split "*tls_local_dynamic_32_once"
12470 [(set (match_operand:SI 0 "register_operand" "=a")
12471 (plus:SI
12472 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12473 (match_operand:SI 2 "constant_call_address_operand" "z")]
12474 UNSPEC_TLS_LD_BASE)
12475 (const:SI (unspec:SI
12476 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12477 UNSPEC_DTPOFF))))
12478 (clobber (match_scratch:SI 4 "=d"))
12479 (clobber (match_scratch:SI 5 "=c"))
12480 (clobber (reg:CC FLAGS_REG))]
12481 ""
12482 "#"
12483 ""
12484 [(parallel
12485 [(set (match_dup 0)
12486 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12487 UNSPEC_TLS_GD))
12488 (clobber (match_dup 4))
12489 (clobber (match_dup 5))
12490 (clobber (reg:CC FLAGS_REG))])])
12491
12492 ;; Segment register for the thread base ptr load
12493 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12494
12495 ;; Load and add the thread base pointer from %<tp_seg>:0.
12496 (define_insn "*load_tp_<mode>"
12497 [(set (match_operand:P 0 "register_operand" "=r")
12498 (unspec:P [(const_int 0)] UNSPEC_TP))]
12499 ""
12500 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12501 [(set_attr "type" "imov")
12502 (set_attr "modrm" "0")
12503 (set_attr "length" "7")
12504 (set_attr "memory" "load")
12505 (set_attr "imm_disp" "false")])
12506
12507 (define_insn "*add_tp_<mode>"
12508 [(set (match_operand:P 0 "register_operand" "=r")
12509 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12510 (match_operand:P 1 "register_operand" "0")))
12511 (clobber (reg:CC FLAGS_REG))]
12512 ""
12513 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12514 [(set_attr "type" "alu")
12515 (set_attr "modrm" "0")
12516 (set_attr "length" "7")
12517 (set_attr "memory" "load")
12518 (set_attr "imm_disp" "false")])
12519
12520 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12521 ;; %rax as destination of the initial executable code sequence.
12522 (define_insn "tls_initial_exec_64_sun"
12523 [(set (match_operand:DI 0 "register_operand" "=a")
12524 (unspec:DI
12525 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12526 UNSPEC_TLS_IE_SUN))
12527 (clobber (reg:CC FLAGS_REG))]
12528 "TARGET_64BIT && TARGET_SUN_TLS"
12529 {
12530 output_asm_insn
12531 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands)
12532 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12533 }
12534 [(set_attr "type" "multi")])
12535
12536 ;; GNU2 TLS patterns can be split.
12537
12538 (define_expand "tls_dynamic_gnu2_32"
12539 [(set (match_dup 3)
12540 (plus:SI (match_operand:SI 2 "register_operand" "")
12541 (const:SI
12542 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12543 UNSPEC_TLSDESC))))
12544 (parallel
12545 [(set (match_operand:SI 0 "register_operand" "")
12546 (unspec:SI [(match_dup 1) (match_dup 3)
12547 (match_dup 2) (reg:SI SP_REG)]
12548 UNSPEC_TLSDESC))
12549 (clobber (reg:CC FLAGS_REG))])]
12550 "!TARGET_64BIT && TARGET_GNU2_TLS"
12551 {
12552 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12553 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12554 })
12555
12556 (define_insn "*tls_dynamic_lea_32"
12557 [(set (match_operand:SI 0 "register_operand" "=r")
12558 (plus:SI (match_operand:SI 1 "register_operand" "b")
12559 (const:SI
12560 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12561 UNSPEC_TLSDESC))))]
12562 "!TARGET_64BIT && TARGET_GNU2_TLS"
12563 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12564 [(set_attr "type" "lea")
12565 (set_attr "mode" "SI")
12566 (set_attr "length" "6")
12567 (set_attr "length_address" "4")])
12568
12569 (define_insn "*tls_dynamic_call_32"
12570 [(set (match_operand:SI 0 "register_operand" "=a")
12571 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12572 (match_operand:SI 2 "register_operand" "0")
12573 ;; we have to make sure %ebx still points to the GOT
12574 (match_operand:SI 3 "register_operand" "b")
12575 (reg:SI SP_REG)]
12576 UNSPEC_TLSDESC))
12577 (clobber (reg:CC FLAGS_REG))]
12578 "!TARGET_64BIT && TARGET_GNU2_TLS"
12579 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12580 [(set_attr "type" "call")
12581 (set_attr "length" "2")
12582 (set_attr "length_address" "0")])
12583
12584 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12585 [(set (match_operand:SI 0 "register_operand" "=&a")
12586 (plus:SI
12587 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12588 (match_operand:SI 4 "" "")
12589 (match_operand:SI 2 "register_operand" "b")
12590 (reg:SI SP_REG)]
12591 UNSPEC_TLSDESC)
12592 (const:SI (unspec:SI
12593 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12594 UNSPEC_DTPOFF))))
12595 (clobber (reg:CC FLAGS_REG))]
12596 "!TARGET_64BIT && TARGET_GNU2_TLS"
12597 "#"
12598 ""
12599 [(set (match_dup 0) (match_dup 5))]
12600 {
12601 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12602 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12603 })
12604
12605 (define_expand "tls_dynamic_gnu2_64"
12606 [(set (match_dup 2)
12607 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12608 UNSPEC_TLSDESC))
12609 (parallel
12610 [(set (match_operand:DI 0 "register_operand" "")
12611 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12612 UNSPEC_TLSDESC))
12613 (clobber (reg:CC FLAGS_REG))])]
12614 "TARGET_64BIT && TARGET_GNU2_TLS"
12615 {
12616 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12617 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12618 })
12619
12620 (define_insn "*tls_dynamic_lea_64"
12621 [(set (match_operand:DI 0 "register_operand" "=r")
12622 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12623 UNSPEC_TLSDESC))]
12624 "TARGET_64BIT && TARGET_GNU2_TLS"
12625 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12626 [(set_attr "type" "lea")
12627 (set_attr "mode" "DI")
12628 (set_attr "length" "7")
12629 (set_attr "length_address" "4")])
12630
12631 (define_insn "*tls_dynamic_call_64"
12632 [(set (match_operand:DI 0 "register_operand" "=a")
12633 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12634 (match_operand:DI 2 "register_operand" "0")
12635 (reg:DI SP_REG)]
12636 UNSPEC_TLSDESC))
12637 (clobber (reg:CC FLAGS_REG))]
12638 "TARGET_64BIT && TARGET_GNU2_TLS"
12639 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12640 [(set_attr "type" "call")
12641 (set_attr "length" "2")
12642 (set_attr "length_address" "0")])
12643
12644 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12645 [(set (match_operand:DI 0 "register_operand" "=&a")
12646 (plus:DI
12647 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12648 (match_operand:DI 3 "" "")
12649 (reg:DI SP_REG)]
12650 UNSPEC_TLSDESC)
12651 (const:DI (unspec:DI
12652 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12653 UNSPEC_DTPOFF))))
12654 (clobber (reg:CC FLAGS_REG))]
12655 "TARGET_64BIT && TARGET_GNU2_TLS"
12656 "#"
12657 ""
12658 [(set (match_dup 0) (match_dup 4))]
12659 {
12660 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12661 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12662 })
12663 \f
12664 ;; These patterns match the binary 387 instructions for addM3, subM3,
12665 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12666 ;; SFmode. The first is the normal insn, the second the same insn but
12667 ;; with one operand a conversion, and the third the same insn but with
12668 ;; the other operand a conversion. The conversion may be SFmode or
12669 ;; SImode if the target mode DFmode, but only SImode if the target mode
12670 ;; is SFmode.
12671
12672 ;; Gcc is slightly more smart about handling normal two address instructions
12673 ;; so use special patterns for add and mull.
12674
12675 (define_insn "*fop_<mode>_comm_mixed"
12676 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12677 (match_operator:MODEF 3 "binary_fp_operator"
12678 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12679 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12680 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12681 && COMMUTATIVE_ARITH_P (operands[3])
12682 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12683 "* return output_387_binary_op (insn, operands);"
12684 [(set (attr "type")
12685 (if_then_else (eq_attr "alternative" "1,2")
12686 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12687 (const_string "ssemul")
12688 (const_string "sseadd"))
12689 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12690 (const_string "fmul")
12691 (const_string "fop"))))
12692 (set_attr "isa" "base,noavx,avx")
12693 (set_attr "prefix" "orig,orig,vex")
12694 (set_attr "mode" "<MODE>")])
12695
12696 (define_insn "*fop_<mode>_comm_sse"
12697 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12698 (match_operator:MODEF 3 "binary_fp_operator"
12699 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12700 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12701 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12702 && COMMUTATIVE_ARITH_P (operands[3])
12703 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12704 "* return output_387_binary_op (insn, operands);"
12705 [(set (attr "type")
12706 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12707 (const_string "ssemul")
12708 (const_string "sseadd")))
12709 (set_attr "isa" "noavx,avx")
12710 (set_attr "prefix" "orig,vex")
12711 (set_attr "mode" "<MODE>")])
12712
12713 (define_insn "*fop_<mode>_comm_i387"
12714 [(set (match_operand:MODEF 0 "register_operand" "=f")
12715 (match_operator:MODEF 3 "binary_fp_operator"
12716 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12717 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12718 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12719 && COMMUTATIVE_ARITH_P (operands[3])
12720 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12721 "* return output_387_binary_op (insn, operands);"
12722 [(set (attr "type")
12723 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12724 (const_string "fmul")
12725 (const_string "fop")))
12726 (set_attr "mode" "<MODE>")])
12727
12728 (define_insn "*fop_<mode>_1_mixed"
12729 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12730 (match_operator:MODEF 3 "binary_fp_operator"
12731 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12732 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12733 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12734 && !COMMUTATIVE_ARITH_P (operands[3])
12735 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12736 "* return output_387_binary_op (insn, operands);"
12737 [(set (attr "type")
12738 (cond [(and (eq_attr "alternative" "2,3")
12739 (match_operand:MODEF 3 "mult_operator" ""))
12740 (const_string "ssemul")
12741 (and (eq_attr "alternative" "2,3")
12742 (match_operand:MODEF 3 "div_operator" ""))
12743 (const_string "ssediv")
12744 (eq_attr "alternative" "2,3")
12745 (const_string "sseadd")
12746 (match_operand:MODEF 3 "mult_operator" "")
12747 (const_string "fmul")
12748 (match_operand:MODEF 3 "div_operator" "")
12749 (const_string "fdiv")
12750 ]
12751 (const_string "fop")))
12752 (set_attr "isa" "base,base,noavx,avx")
12753 (set_attr "prefix" "orig,orig,orig,vex")
12754 (set_attr "mode" "<MODE>")])
12755
12756 (define_insn "*rcpsf2_sse"
12757 [(set (match_operand:SF 0 "register_operand" "=x")
12758 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12759 UNSPEC_RCP))]
12760 "TARGET_SSE_MATH"
12761 "%vrcpss\t{%1, %d0|%d0, %1}"
12762 [(set_attr "type" "sse")
12763 (set_attr "atom_sse_attr" "rcp")
12764 (set_attr "prefix" "maybe_vex")
12765 (set_attr "mode" "SF")])
12766
12767 (define_insn "*fop_<mode>_1_sse"
12768 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12769 (match_operator:MODEF 3 "binary_fp_operator"
12770 [(match_operand:MODEF 1 "register_operand" "0,x")
12771 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12772 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12773 && !COMMUTATIVE_ARITH_P (operands[3])"
12774 "* return output_387_binary_op (insn, operands);"
12775 [(set (attr "type")
12776 (cond [(match_operand:MODEF 3 "mult_operator" "")
12777 (const_string "ssemul")
12778 (match_operand:MODEF 3 "div_operator" "")
12779 (const_string "ssediv")
12780 ]
12781 (const_string "sseadd")))
12782 (set_attr "isa" "noavx,avx")
12783 (set_attr "prefix" "orig,vex")
12784 (set_attr "mode" "<MODE>")])
12785
12786 ;; This pattern is not fully shadowed by the pattern above.
12787 (define_insn "*fop_<mode>_1_i387"
12788 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12789 (match_operator:MODEF 3 "binary_fp_operator"
12790 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12791 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12792 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12793 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12794 && !COMMUTATIVE_ARITH_P (operands[3])
12795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12796 "* return output_387_binary_op (insn, operands);"
12797 [(set (attr "type")
12798 (cond [(match_operand:MODEF 3 "mult_operator" "")
12799 (const_string "fmul")
12800 (match_operand:MODEF 3 "div_operator" "")
12801 (const_string "fdiv")
12802 ]
12803 (const_string "fop")))
12804 (set_attr "mode" "<MODE>")])
12805
12806 ;; ??? Add SSE splitters for these!
12807 (define_insn "*fop_<MODEF:mode>_2_i387"
12808 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12809 (match_operator:MODEF 3 "binary_fp_operator"
12810 [(float:MODEF
12811 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12812 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12813 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12814 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12815 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12816 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12817 [(set (attr "type")
12818 (cond [(match_operand:MODEF 3 "mult_operator" "")
12819 (const_string "fmul")
12820 (match_operand:MODEF 3 "div_operator" "")
12821 (const_string "fdiv")
12822 ]
12823 (const_string "fop")))
12824 (set_attr "fp_int_src" "true")
12825 (set_attr "mode" "<X87MODEI12:MODE>")])
12826
12827 (define_insn "*fop_<MODEF:mode>_3_i387"
12828 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12829 (match_operator:MODEF 3 "binary_fp_operator"
12830 [(match_operand:MODEF 1 "register_operand" "0,0")
12831 (float:MODEF
12832 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12833 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12834 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12835 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12836 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12837 [(set (attr "type")
12838 (cond [(match_operand:MODEF 3 "mult_operator" "")
12839 (const_string "fmul")
12840 (match_operand:MODEF 3 "div_operator" "")
12841 (const_string "fdiv")
12842 ]
12843 (const_string "fop")))
12844 (set_attr "fp_int_src" "true")
12845 (set_attr "mode" "<MODE>")])
12846
12847 (define_insn "*fop_df_4_i387"
12848 [(set (match_operand:DF 0 "register_operand" "=f,f")
12849 (match_operator:DF 3 "binary_fp_operator"
12850 [(float_extend:DF
12851 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12852 (match_operand:DF 2 "register_operand" "0,f")]))]
12853 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12854 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12855 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12856 "* return output_387_binary_op (insn, operands);"
12857 [(set (attr "type")
12858 (cond [(match_operand:DF 3 "mult_operator" "")
12859 (const_string "fmul")
12860 (match_operand:DF 3 "div_operator" "")
12861 (const_string "fdiv")
12862 ]
12863 (const_string "fop")))
12864 (set_attr "mode" "SF")])
12865
12866 (define_insn "*fop_df_5_i387"
12867 [(set (match_operand:DF 0 "register_operand" "=f,f")
12868 (match_operator:DF 3 "binary_fp_operator"
12869 [(match_operand:DF 1 "register_operand" "0,f")
12870 (float_extend:DF
12871 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12872 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12873 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12874 "* return output_387_binary_op (insn, operands);"
12875 [(set (attr "type")
12876 (cond [(match_operand:DF 3 "mult_operator" "")
12877 (const_string "fmul")
12878 (match_operand:DF 3 "div_operator" "")
12879 (const_string "fdiv")
12880 ]
12881 (const_string "fop")))
12882 (set_attr "mode" "SF")])
12883
12884 (define_insn "*fop_df_6_i387"
12885 [(set (match_operand:DF 0 "register_operand" "=f,f")
12886 (match_operator:DF 3 "binary_fp_operator"
12887 [(float_extend:DF
12888 (match_operand:SF 1 "register_operand" "0,f"))
12889 (float_extend:DF
12890 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12891 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12892 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12893 "* return output_387_binary_op (insn, operands);"
12894 [(set (attr "type")
12895 (cond [(match_operand:DF 3 "mult_operator" "")
12896 (const_string "fmul")
12897 (match_operand:DF 3 "div_operator" "")
12898 (const_string "fdiv")
12899 ]
12900 (const_string "fop")))
12901 (set_attr "mode" "SF")])
12902
12903 (define_insn "*fop_xf_comm_i387"
12904 [(set (match_operand:XF 0 "register_operand" "=f")
12905 (match_operator:XF 3 "binary_fp_operator"
12906 [(match_operand:XF 1 "register_operand" "%0")
12907 (match_operand:XF 2 "register_operand" "f")]))]
12908 "TARGET_80387
12909 && COMMUTATIVE_ARITH_P (operands[3])"
12910 "* return output_387_binary_op (insn, operands);"
12911 [(set (attr "type")
12912 (if_then_else (match_operand:XF 3 "mult_operator" "")
12913 (const_string "fmul")
12914 (const_string "fop")))
12915 (set_attr "mode" "XF")])
12916
12917 (define_insn "*fop_xf_1_i387"
12918 [(set (match_operand:XF 0 "register_operand" "=f,f")
12919 (match_operator:XF 3 "binary_fp_operator"
12920 [(match_operand:XF 1 "register_operand" "0,f")
12921 (match_operand:XF 2 "register_operand" "f,0")]))]
12922 "TARGET_80387
12923 && !COMMUTATIVE_ARITH_P (operands[3])"
12924 "* return output_387_binary_op (insn, operands);"
12925 [(set (attr "type")
12926 (cond [(match_operand:XF 3 "mult_operator" "")
12927 (const_string "fmul")
12928 (match_operand:XF 3 "div_operator" "")
12929 (const_string "fdiv")
12930 ]
12931 (const_string "fop")))
12932 (set_attr "mode" "XF")])
12933
12934 (define_insn "*fop_xf_2_i387"
12935 [(set (match_operand:XF 0 "register_operand" "=f,f")
12936 (match_operator:XF 3 "binary_fp_operator"
12937 [(float:XF
12938 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12939 (match_operand:XF 2 "register_operand" "0,0")]))]
12940 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12941 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12942 [(set (attr "type")
12943 (cond [(match_operand:XF 3 "mult_operator" "")
12944 (const_string "fmul")
12945 (match_operand:XF 3 "div_operator" "")
12946 (const_string "fdiv")
12947 ]
12948 (const_string "fop")))
12949 (set_attr "fp_int_src" "true")
12950 (set_attr "mode" "<MODE>")])
12951
12952 (define_insn "*fop_xf_3_i387"
12953 [(set (match_operand:XF 0 "register_operand" "=f,f")
12954 (match_operator:XF 3 "binary_fp_operator"
12955 [(match_operand:XF 1 "register_operand" "0,0")
12956 (float:XF
12957 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12958 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12959 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12960 [(set (attr "type")
12961 (cond [(match_operand:XF 3 "mult_operator" "")
12962 (const_string "fmul")
12963 (match_operand:XF 3 "div_operator" "")
12964 (const_string "fdiv")
12965 ]
12966 (const_string "fop")))
12967 (set_attr "fp_int_src" "true")
12968 (set_attr "mode" "<MODE>")])
12969
12970 (define_insn "*fop_xf_4_i387"
12971 [(set (match_operand:XF 0 "register_operand" "=f,f")
12972 (match_operator:XF 3 "binary_fp_operator"
12973 [(float_extend:XF
12974 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12975 (match_operand:XF 2 "register_operand" "0,f")]))]
12976 "TARGET_80387"
12977 "* return output_387_binary_op (insn, operands);"
12978 [(set (attr "type")
12979 (cond [(match_operand:XF 3 "mult_operator" "")
12980 (const_string "fmul")
12981 (match_operand:XF 3 "div_operator" "")
12982 (const_string "fdiv")
12983 ]
12984 (const_string "fop")))
12985 (set_attr "mode" "<MODE>")])
12986
12987 (define_insn "*fop_xf_5_i387"
12988 [(set (match_operand:XF 0 "register_operand" "=f,f")
12989 (match_operator:XF 3 "binary_fp_operator"
12990 [(match_operand:XF 1 "register_operand" "0,f")
12991 (float_extend:XF
12992 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12993 "TARGET_80387"
12994 "* return output_387_binary_op (insn, operands);"
12995 [(set (attr "type")
12996 (cond [(match_operand:XF 3 "mult_operator" "")
12997 (const_string "fmul")
12998 (match_operand:XF 3 "div_operator" "")
12999 (const_string "fdiv")
13000 ]
13001 (const_string "fop")))
13002 (set_attr "mode" "<MODE>")])
13003
13004 (define_insn "*fop_xf_6_i387"
13005 [(set (match_operand:XF 0 "register_operand" "=f,f")
13006 (match_operator:XF 3 "binary_fp_operator"
13007 [(float_extend:XF
13008 (match_operand:MODEF 1 "register_operand" "0,f"))
13009 (float_extend:XF
13010 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13011 "TARGET_80387"
13012 "* return output_387_binary_op (insn, operands);"
13013 [(set (attr "type")
13014 (cond [(match_operand:XF 3 "mult_operator" "")
13015 (const_string "fmul")
13016 (match_operand:XF 3 "div_operator" "")
13017 (const_string "fdiv")
13018 ]
13019 (const_string "fop")))
13020 (set_attr "mode" "<MODE>")])
13021
13022 (define_split
13023 [(set (match_operand 0 "register_operand" "")
13024 (match_operator 3 "binary_fp_operator"
13025 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13026 (match_operand 2 "register_operand" "")]))]
13027 "reload_completed
13028 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13029 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13030 [(const_int 0)]
13031 {
13032 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13033 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13034 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13035 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13036 GET_MODE (operands[3]),
13037 operands[4],
13038 operands[2])));
13039 ix86_free_from_memory (GET_MODE (operands[1]));
13040 DONE;
13041 })
13042
13043 (define_split
13044 [(set (match_operand 0 "register_operand" "")
13045 (match_operator 3 "binary_fp_operator"
13046 [(match_operand 1 "register_operand" "")
13047 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13048 "reload_completed
13049 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13050 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13051 [(const_int 0)]
13052 {
13053 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13054 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13055 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13056 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13057 GET_MODE (operands[3]),
13058 operands[1],
13059 operands[4])));
13060 ix86_free_from_memory (GET_MODE (operands[2]));
13061 DONE;
13062 })
13063 \f
13064 ;; FPU special functions.
13065
13066 ;; This pattern implements a no-op XFmode truncation for
13067 ;; all fancy i386 XFmode math functions.
13068
13069 (define_insn "truncxf<mode>2_i387_noop_unspec"
13070 [(set (match_operand:MODEF 0 "register_operand" "=f")
13071 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13072 UNSPEC_TRUNC_NOOP))]
13073 "TARGET_USE_FANCY_MATH_387"
13074 "* return output_387_reg_move (insn, operands);"
13075 [(set_attr "type" "fmov")
13076 (set_attr "mode" "<MODE>")])
13077
13078 (define_insn "sqrtxf2"
13079 [(set (match_operand:XF 0 "register_operand" "=f")
13080 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13081 "TARGET_USE_FANCY_MATH_387"
13082 "fsqrt"
13083 [(set_attr "type" "fpspc")
13084 (set_attr "mode" "XF")
13085 (set_attr "athlon_decode" "direct")
13086 (set_attr "amdfam10_decode" "direct")
13087 (set_attr "bdver1_decode" "direct")])
13088
13089 (define_insn "sqrt_extend<mode>xf2_i387"
13090 [(set (match_operand:XF 0 "register_operand" "=f")
13091 (sqrt:XF
13092 (float_extend:XF
13093 (match_operand:MODEF 1 "register_operand" "0"))))]
13094 "TARGET_USE_FANCY_MATH_387"
13095 "fsqrt"
13096 [(set_attr "type" "fpspc")
13097 (set_attr "mode" "XF")
13098 (set_attr "athlon_decode" "direct")
13099 (set_attr "amdfam10_decode" "direct")
13100 (set_attr "bdver1_decode" "direct")])
13101
13102 (define_insn "*rsqrtsf2_sse"
13103 [(set (match_operand:SF 0 "register_operand" "=x")
13104 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13105 UNSPEC_RSQRT))]
13106 "TARGET_SSE_MATH"
13107 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13108 [(set_attr "type" "sse")
13109 (set_attr "atom_sse_attr" "rcp")
13110 (set_attr "prefix" "maybe_vex")
13111 (set_attr "mode" "SF")])
13112
13113 (define_expand "rsqrtsf2"
13114 [(set (match_operand:SF 0 "register_operand" "")
13115 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13116 UNSPEC_RSQRT))]
13117 "TARGET_SSE_MATH"
13118 {
13119 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13120 DONE;
13121 })
13122
13123 (define_insn "*sqrt<mode>2_sse"
13124 [(set (match_operand:MODEF 0 "register_operand" "=x")
13125 (sqrt:MODEF
13126 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13127 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13128 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13129 [(set_attr "type" "sse")
13130 (set_attr "atom_sse_attr" "sqrt")
13131 (set_attr "prefix" "maybe_vex")
13132 (set_attr "mode" "<MODE>")
13133 (set_attr "athlon_decode" "*")
13134 (set_attr "amdfam10_decode" "*")
13135 (set_attr "bdver1_decode" "*")])
13136
13137 (define_expand "sqrt<mode>2"
13138 [(set (match_operand:MODEF 0 "register_operand" "")
13139 (sqrt:MODEF
13140 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13141 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13142 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13143 {
13144 if (<MODE>mode == SFmode
13145 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13146 && flag_finite_math_only && !flag_trapping_math
13147 && flag_unsafe_math_optimizations)
13148 {
13149 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13150 DONE;
13151 }
13152
13153 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13154 {
13155 rtx op0 = gen_reg_rtx (XFmode);
13156 rtx op1 = force_reg (<MODE>mode, operands[1]);
13157
13158 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13159 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13160 DONE;
13161 }
13162 })
13163
13164 (define_insn "fpremxf4_i387"
13165 [(set (match_operand:XF 0 "register_operand" "=f")
13166 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13167 (match_operand:XF 3 "register_operand" "1")]
13168 UNSPEC_FPREM_F))
13169 (set (match_operand:XF 1 "register_operand" "=u")
13170 (unspec:XF [(match_dup 2) (match_dup 3)]
13171 UNSPEC_FPREM_U))
13172 (set (reg:CCFP FPSR_REG)
13173 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13174 UNSPEC_C2_FLAG))]
13175 "TARGET_USE_FANCY_MATH_387"
13176 "fprem"
13177 [(set_attr "type" "fpspc")
13178 (set_attr "mode" "XF")])
13179
13180 (define_expand "fmodxf3"
13181 [(use (match_operand:XF 0 "register_operand" ""))
13182 (use (match_operand:XF 1 "general_operand" ""))
13183 (use (match_operand:XF 2 "general_operand" ""))]
13184 "TARGET_USE_FANCY_MATH_387"
13185 {
13186 rtx label = gen_label_rtx ();
13187
13188 rtx op1 = gen_reg_rtx (XFmode);
13189 rtx op2 = gen_reg_rtx (XFmode);
13190
13191 emit_move_insn (op2, operands[2]);
13192 emit_move_insn (op1, operands[1]);
13193
13194 emit_label (label);
13195 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13196 ix86_emit_fp_unordered_jump (label);
13197 LABEL_NUSES (label) = 1;
13198
13199 emit_move_insn (operands[0], op1);
13200 DONE;
13201 })
13202
13203 (define_expand "fmod<mode>3"
13204 [(use (match_operand:MODEF 0 "register_operand" ""))
13205 (use (match_operand:MODEF 1 "general_operand" ""))
13206 (use (match_operand:MODEF 2 "general_operand" ""))]
13207 "TARGET_USE_FANCY_MATH_387"
13208 {
13209 rtx (*gen_truncxf) (rtx, rtx);
13210
13211 rtx label = gen_label_rtx ();
13212
13213 rtx op1 = gen_reg_rtx (XFmode);
13214 rtx op2 = gen_reg_rtx (XFmode);
13215
13216 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13217 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13218
13219 emit_label (label);
13220 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13221 ix86_emit_fp_unordered_jump (label);
13222 LABEL_NUSES (label) = 1;
13223
13224 /* Truncate the result properly for strict SSE math. */
13225 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13226 && !TARGET_MIX_SSE_I387)
13227 gen_truncxf = gen_truncxf<mode>2;
13228 else
13229 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13230
13231 emit_insn (gen_truncxf (operands[0], op1));
13232 DONE;
13233 })
13234
13235 (define_insn "fprem1xf4_i387"
13236 [(set (match_operand:XF 0 "register_operand" "=f")
13237 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13238 (match_operand:XF 3 "register_operand" "1")]
13239 UNSPEC_FPREM1_F))
13240 (set (match_operand:XF 1 "register_operand" "=u")
13241 (unspec:XF [(match_dup 2) (match_dup 3)]
13242 UNSPEC_FPREM1_U))
13243 (set (reg:CCFP FPSR_REG)
13244 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13245 UNSPEC_C2_FLAG))]
13246 "TARGET_USE_FANCY_MATH_387"
13247 "fprem1"
13248 [(set_attr "type" "fpspc")
13249 (set_attr "mode" "XF")])
13250
13251 (define_expand "remainderxf3"
13252 [(use (match_operand:XF 0 "register_operand" ""))
13253 (use (match_operand:XF 1 "general_operand" ""))
13254 (use (match_operand:XF 2 "general_operand" ""))]
13255 "TARGET_USE_FANCY_MATH_387"
13256 {
13257 rtx label = gen_label_rtx ();
13258
13259 rtx op1 = gen_reg_rtx (XFmode);
13260 rtx op2 = gen_reg_rtx (XFmode);
13261
13262 emit_move_insn (op2, operands[2]);
13263 emit_move_insn (op1, operands[1]);
13264
13265 emit_label (label);
13266 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13267 ix86_emit_fp_unordered_jump (label);
13268 LABEL_NUSES (label) = 1;
13269
13270 emit_move_insn (operands[0], op1);
13271 DONE;
13272 })
13273
13274 (define_expand "remainder<mode>3"
13275 [(use (match_operand:MODEF 0 "register_operand" ""))
13276 (use (match_operand:MODEF 1 "general_operand" ""))
13277 (use (match_operand:MODEF 2 "general_operand" ""))]
13278 "TARGET_USE_FANCY_MATH_387"
13279 {
13280 rtx (*gen_truncxf) (rtx, rtx);
13281
13282 rtx label = gen_label_rtx ();
13283
13284 rtx op1 = gen_reg_rtx (XFmode);
13285 rtx op2 = gen_reg_rtx (XFmode);
13286
13287 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13288 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13289
13290 emit_label (label);
13291
13292 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13293 ix86_emit_fp_unordered_jump (label);
13294 LABEL_NUSES (label) = 1;
13295
13296 /* Truncate the result properly for strict SSE math. */
13297 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13298 && !TARGET_MIX_SSE_I387)
13299 gen_truncxf = gen_truncxf<mode>2;
13300 else
13301 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13302
13303 emit_insn (gen_truncxf (operands[0], op1));
13304 DONE;
13305 })
13306
13307 (define_insn "*sinxf2_i387"
13308 [(set (match_operand:XF 0 "register_operand" "=f")
13309 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13310 "TARGET_USE_FANCY_MATH_387
13311 && flag_unsafe_math_optimizations"
13312 "fsin"
13313 [(set_attr "type" "fpspc")
13314 (set_attr "mode" "XF")])
13315
13316 (define_insn "*sin_extend<mode>xf2_i387"
13317 [(set (match_operand:XF 0 "register_operand" "=f")
13318 (unspec:XF [(float_extend:XF
13319 (match_operand:MODEF 1 "register_operand" "0"))]
13320 UNSPEC_SIN))]
13321 "TARGET_USE_FANCY_MATH_387
13322 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13323 || TARGET_MIX_SSE_I387)
13324 && flag_unsafe_math_optimizations"
13325 "fsin"
13326 [(set_attr "type" "fpspc")
13327 (set_attr "mode" "XF")])
13328
13329 (define_insn "*cosxf2_i387"
13330 [(set (match_operand:XF 0 "register_operand" "=f")
13331 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13332 "TARGET_USE_FANCY_MATH_387
13333 && flag_unsafe_math_optimizations"
13334 "fcos"
13335 [(set_attr "type" "fpspc")
13336 (set_attr "mode" "XF")])
13337
13338 (define_insn "*cos_extend<mode>xf2_i387"
13339 [(set (match_operand:XF 0 "register_operand" "=f")
13340 (unspec:XF [(float_extend:XF
13341 (match_operand:MODEF 1 "register_operand" "0"))]
13342 UNSPEC_COS))]
13343 "TARGET_USE_FANCY_MATH_387
13344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13345 || TARGET_MIX_SSE_I387)
13346 && flag_unsafe_math_optimizations"
13347 "fcos"
13348 [(set_attr "type" "fpspc")
13349 (set_attr "mode" "XF")])
13350
13351 ;; When sincos pattern is defined, sin and cos builtin functions will be
13352 ;; expanded to sincos pattern with one of its outputs left unused.
13353 ;; CSE pass will figure out if two sincos patterns can be combined,
13354 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13355 ;; depending on the unused output.
13356
13357 (define_insn "sincosxf3"
13358 [(set (match_operand:XF 0 "register_operand" "=f")
13359 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13360 UNSPEC_SINCOS_COS))
13361 (set (match_operand:XF 1 "register_operand" "=u")
13362 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13363 "TARGET_USE_FANCY_MATH_387
13364 && flag_unsafe_math_optimizations"
13365 "fsincos"
13366 [(set_attr "type" "fpspc")
13367 (set_attr "mode" "XF")])
13368
13369 (define_split
13370 [(set (match_operand:XF 0 "register_operand" "")
13371 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13372 UNSPEC_SINCOS_COS))
13373 (set (match_operand:XF 1 "register_operand" "")
13374 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13375 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13376 && can_create_pseudo_p ()"
13377 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13378
13379 (define_split
13380 [(set (match_operand:XF 0 "register_operand" "")
13381 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13382 UNSPEC_SINCOS_COS))
13383 (set (match_operand:XF 1 "register_operand" "")
13384 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13385 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13386 && can_create_pseudo_p ()"
13387 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13388
13389 (define_insn "sincos_extend<mode>xf3_i387"
13390 [(set (match_operand:XF 0 "register_operand" "=f")
13391 (unspec:XF [(float_extend:XF
13392 (match_operand:MODEF 2 "register_operand" "0"))]
13393 UNSPEC_SINCOS_COS))
13394 (set (match_operand:XF 1 "register_operand" "=u")
13395 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13396 "TARGET_USE_FANCY_MATH_387
13397 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13398 || TARGET_MIX_SSE_I387)
13399 && flag_unsafe_math_optimizations"
13400 "fsincos"
13401 [(set_attr "type" "fpspc")
13402 (set_attr "mode" "XF")])
13403
13404 (define_split
13405 [(set (match_operand:XF 0 "register_operand" "")
13406 (unspec:XF [(float_extend:XF
13407 (match_operand:MODEF 2 "register_operand" ""))]
13408 UNSPEC_SINCOS_COS))
13409 (set (match_operand:XF 1 "register_operand" "")
13410 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13411 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13412 && can_create_pseudo_p ()"
13413 [(set (match_dup 1)
13414 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13415
13416 (define_split
13417 [(set (match_operand:XF 0 "register_operand" "")
13418 (unspec:XF [(float_extend:XF
13419 (match_operand:MODEF 2 "register_operand" ""))]
13420 UNSPEC_SINCOS_COS))
13421 (set (match_operand:XF 1 "register_operand" "")
13422 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13423 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13424 && can_create_pseudo_p ()"
13425 [(set (match_dup 0)
13426 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13427
13428 (define_expand "sincos<mode>3"
13429 [(use (match_operand:MODEF 0 "register_operand" ""))
13430 (use (match_operand:MODEF 1 "register_operand" ""))
13431 (use (match_operand:MODEF 2 "register_operand" ""))]
13432 "TARGET_USE_FANCY_MATH_387
13433 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13434 || TARGET_MIX_SSE_I387)
13435 && flag_unsafe_math_optimizations"
13436 {
13437 rtx op0 = gen_reg_rtx (XFmode);
13438 rtx op1 = gen_reg_rtx (XFmode);
13439
13440 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13441 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13442 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13443 DONE;
13444 })
13445
13446 (define_insn "fptanxf4_i387"
13447 [(set (match_operand:XF 0 "register_operand" "=f")
13448 (match_operand:XF 3 "const_double_operand" "F"))
13449 (set (match_operand:XF 1 "register_operand" "=u")
13450 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13451 UNSPEC_TAN))]
13452 "TARGET_USE_FANCY_MATH_387
13453 && flag_unsafe_math_optimizations
13454 && standard_80387_constant_p (operands[3]) == 2"
13455 "fptan"
13456 [(set_attr "type" "fpspc")
13457 (set_attr "mode" "XF")])
13458
13459 (define_insn "fptan_extend<mode>xf4_i387"
13460 [(set (match_operand:MODEF 0 "register_operand" "=f")
13461 (match_operand:MODEF 3 "const_double_operand" "F"))
13462 (set (match_operand:XF 1 "register_operand" "=u")
13463 (unspec:XF [(float_extend:XF
13464 (match_operand:MODEF 2 "register_operand" "0"))]
13465 UNSPEC_TAN))]
13466 "TARGET_USE_FANCY_MATH_387
13467 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13468 || TARGET_MIX_SSE_I387)
13469 && flag_unsafe_math_optimizations
13470 && standard_80387_constant_p (operands[3]) == 2"
13471 "fptan"
13472 [(set_attr "type" "fpspc")
13473 (set_attr "mode" "XF")])
13474
13475 (define_expand "tanxf2"
13476 [(use (match_operand:XF 0 "register_operand" ""))
13477 (use (match_operand:XF 1 "register_operand" ""))]
13478 "TARGET_USE_FANCY_MATH_387
13479 && flag_unsafe_math_optimizations"
13480 {
13481 rtx one = gen_reg_rtx (XFmode);
13482 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13483
13484 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13485 DONE;
13486 })
13487
13488 (define_expand "tan<mode>2"
13489 [(use (match_operand:MODEF 0 "register_operand" ""))
13490 (use (match_operand:MODEF 1 "register_operand" ""))]
13491 "TARGET_USE_FANCY_MATH_387
13492 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13493 || TARGET_MIX_SSE_I387)
13494 && flag_unsafe_math_optimizations"
13495 {
13496 rtx op0 = gen_reg_rtx (XFmode);
13497
13498 rtx one = gen_reg_rtx (<MODE>mode);
13499 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13500
13501 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13502 operands[1], op2));
13503 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13504 DONE;
13505 })
13506
13507 (define_insn "*fpatanxf3_i387"
13508 [(set (match_operand:XF 0 "register_operand" "=f")
13509 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13510 (match_operand:XF 2 "register_operand" "u")]
13511 UNSPEC_FPATAN))
13512 (clobber (match_scratch:XF 3 "=2"))]
13513 "TARGET_USE_FANCY_MATH_387
13514 && flag_unsafe_math_optimizations"
13515 "fpatan"
13516 [(set_attr "type" "fpspc")
13517 (set_attr "mode" "XF")])
13518
13519 (define_insn "fpatan_extend<mode>xf3_i387"
13520 [(set (match_operand:XF 0 "register_operand" "=f")
13521 (unspec:XF [(float_extend:XF
13522 (match_operand:MODEF 1 "register_operand" "0"))
13523 (float_extend:XF
13524 (match_operand:MODEF 2 "register_operand" "u"))]
13525 UNSPEC_FPATAN))
13526 (clobber (match_scratch:XF 3 "=2"))]
13527 "TARGET_USE_FANCY_MATH_387
13528 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13529 || TARGET_MIX_SSE_I387)
13530 && flag_unsafe_math_optimizations"
13531 "fpatan"
13532 [(set_attr "type" "fpspc")
13533 (set_attr "mode" "XF")])
13534
13535 (define_expand "atan2xf3"
13536 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13537 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13538 (match_operand:XF 1 "register_operand" "")]
13539 UNSPEC_FPATAN))
13540 (clobber (match_scratch:XF 3 ""))])]
13541 "TARGET_USE_FANCY_MATH_387
13542 && flag_unsafe_math_optimizations")
13543
13544 (define_expand "atan2<mode>3"
13545 [(use (match_operand:MODEF 0 "register_operand" ""))
13546 (use (match_operand:MODEF 1 "register_operand" ""))
13547 (use (match_operand:MODEF 2 "register_operand" ""))]
13548 "TARGET_USE_FANCY_MATH_387
13549 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13550 || TARGET_MIX_SSE_I387)
13551 && flag_unsafe_math_optimizations"
13552 {
13553 rtx op0 = gen_reg_rtx (XFmode);
13554
13555 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13556 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13557 DONE;
13558 })
13559
13560 (define_expand "atanxf2"
13561 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13562 (unspec:XF [(match_dup 2)
13563 (match_operand:XF 1 "register_operand" "")]
13564 UNSPEC_FPATAN))
13565 (clobber (match_scratch:XF 3 ""))])]
13566 "TARGET_USE_FANCY_MATH_387
13567 && flag_unsafe_math_optimizations"
13568 {
13569 operands[2] = gen_reg_rtx (XFmode);
13570 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13571 })
13572
13573 (define_expand "atan<mode>2"
13574 [(use (match_operand:MODEF 0 "register_operand" ""))
13575 (use (match_operand:MODEF 1 "register_operand" ""))]
13576 "TARGET_USE_FANCY_MATH_387
13577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13578 || TARGET_MIX_SSE_I387)
13579 && flag_unsafe_math_optimizations"
13580 {
13581 rtx op0 = gen_reg_rtx (XFmode);
13582
13583 rtx op2 = gen_reg_rtx (<MODE>mode);
13584 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13585
13586 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13587 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13588 DONE;
13589 })
13590
13591 (define_expand "asinxf2"
13592 [(set (match_dup 2)
13593 (mult:XF (match_operand:XF 1 "register_operand" "")
13594 (match_dup 1)))
13595 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13596 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13597 (parallel [(set (match_operand:XF 0 "register_operand" "")
13598 (unspec:XF [(match_dup 5) (match_dup 1)]
13599 UNSPEC_FPATAN))
13600 (clobber (match_scratch:XF 6 ""))])]
13601 "TARGET_USE_FANCY_MATH_387
13602 && flag_unsafe_math_optimizations"
13603 {
13604 int i;
13605
13606 if (optimize_insn_for_size_p ())
13607 FAIL;
13608
13609 for (i = 2; i < 6; i++)
13610 operands[i] = gen_reg_rtx (XFmode);
13611
13612 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13613 })
13614
13615 (define_expand "asin<mode>2"
13616 [(use (match_operand:MODEF 0 "register_operand" ""))
13617 (use (match_operand:MODEF 1 "general_operand" ""))]
13618 "TARGET_USE_FANCY_MATH_387
13619 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13620 || TARGET_MIX_SSE_I387)
13621 && flag_unsafe_math_optimizations"
13622 {
13623 rtx op0 = gen_reg_rtx (XFmode);
13624 rtx op1 = gen_reg_rtx (XFmode);
13625
13626 if (optimize_insn_for_size_p ())
13627 FAIL;
13628
13629 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13630 emit_insn (gen_asinxf2 (op0, op1));
13631 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13632 DONE;
13633 })
13634
13635 (define_expand "acosxf2"
13636 [(set (match_dup 2)
13637 (mult:XF (match_operand:XF 1 "register_operand" "")
13638 (match_dup 1)))
13639 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13640 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13641 (parallel [(set (match_operand:XF 0 "register_operand" "")
13642 (unspec:XF [(match_dup 1) (match_dup 5)]
13643 UNSPEC_FPATAN))
13644 (clobber (match_scratch:XF 6 ""))])]
13645 "TARGET_USE_FANCY_MATH_387
13646 && flag_unsafe_math_optimizations"
13647 {
13648 int i;
13649
13650 if (optimize_insn_for_size_p ())
13651 FAIL;
13652
13653 for (i = 2; i < 6; i++)
13654 operands[i] = gen_reg_rtx (XFmode);
13655
13656 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13657 })
13658
13659 (define_expand "acos<mode>2"
13660 [(use (match_operand:MODEF 0 "register_operand" ""))
13661 (use (match_operand:MODEF 1 "general_operand" ""))]
13662 "TARGET_USE_FANCY_MATH_387
13663 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13664 || TARGET_MIX_SSE_I387)
13665 && flag_unsafe_math_optimizations"
13666 {
13667 rtx op0 = gen_reg_rtx (XFmode);
13668 rtx op1 = gen_reg_rtx (XFmode);
13669
13670 if (optimize_insn_for_size_p ())
13671 FAIL;
13672
13673 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13674 emit_insn (gen_acosxf2 (op0, op1));
13675 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13676 DONE;
13677 })
13678
13679 (define_insn "fyl2xxf3_i387"
13680 [(set (match_operand:XF 0 "register_operand" "=f")
13681 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13682 (match_operand:XF 2 "register_operand" "u")]
13683 UNSPEC_FYL2X))
13684 (clobber (match_scratch:XF 3 "=2"))]
13685 "TARGET_USE_FANCY_MATH_387
13686 && flag_unsafe_math_optimizations"
13687 "fyl2x"
13688 [(set_attr "type" "fpspc")
13689 (set_attr "mode" "XF")])
13690
13691 (define_insn "fyl2x_extend<mode>xf3_i387"
13692 [(set (match_operand:XF 0 "register_operand" "=f")
13693 (unspec:XF [(float_extend:XF
13694 (match_operand:MODEF 1 "register_operand" "0"))
13695 (match_operand:XF 2 "register_operand" "u")]
13696 UNSPEC_FYL2X))
13697 (clobber (match_scratch:XF 3 "=2"))]
13698 "TARGET_USE_FANCY_MATH_387
13699 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13700 || TARGET_MIX_SSE_I387)
13701 && flag_unsafe_math_optimizations"
13702 "fyl2x"
13703 [(set_attr "type" "fpspc")
13704 (set_attr "mode" "XF")])
13705
13706 (define_expand "logxf2"
13707 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13708 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13709 (match_dup 2)] UNSPEC_FYL2X))
13710 (clobber (match_scratch:XF 3 ""))])]
13711 "TARGET_USE_FANCY_MATH_387
13712 && flag_unsafe_math_optimizations"
13713 {
13714 operands[2] = gen_reg_rtx (XFmode);
13715 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13716 })
13717
13718 (define_expand "log<mode>2"
13719 [(use (match_operand:MODEF 0 "register_operand" ""))
13720 (use (match_operand:MODEF 1 "register_operand" ""))]
13721 "TARGET_USE_FANCY_MATH_387
13722 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13723 || TARGET_MIX_SSE_I387)
13724 && flag_unsafe_math_optimizations"
13725 {
13726 rtx op0 = gen_reg_rtx (XFmode);
13727
13728 rtx op2 = gen_reg_rtx (XFmode);
13729 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13730
13731 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13732 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13733 DONE;
13734 })
13735
13736 (define_expand "log10xf2"
13737 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13738 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13739 (match_dup 2)] UNSPEC_FYL2X))
13740 (clobber (match_scratch:XF 3 ""))])]
13741 "TARGET_USE_FANCY_MATH_387
13742 && flag_unsafe_math_optimizations"
13743 {
13744 operands[2] = gen_reg_rtx (XFmode);
13745 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13746 })
13747
13748 (define_expand "log10<mode>2"
13749 [(use (match_operand:MODEF 0 "register_operand" ""))
13750 (use (match_operand:MODEF 1 "register_operand" ""))]
13751 "TARGET_USE_FANCY_MATH_387
13752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13753 || TARGET_MIX_SSE_I387)
13754 && flag_unsafe_math_optimizations"
13755 {
13756 rtx op0 = gen_reg_rtx (XFmode);
13757
13758 rtx op2 = gen_reg_rtx (XFmode);
13759 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13760
13761 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13762 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13763 DONE;
13764 })
13765
13766 (define_expand "log2xf2"
13767 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13768 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13769 (match_dup 2)] UNSPEC_FYL2X))
13770 (clobber (match_scratch:XF 3 ""))])]
13771 "TARGET_USE_FANCY_MATH_387
13772 && flag_unsafe_math_optimizations"
13773 {
13774 operands[2] = gen_reg_rtx (XFmode);
13775 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13776 })
13777
13778 (define_expand "log2<mode>2"
13779 [(use (match_operand:MODEF 0 "register_operand" ""))
13780 (use (match_operand:MODEF 1 "register_operand" ""))]
13781 "TARGET_USE_FANCY_MATH_387
13782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13783 || TARGET_MIX_SSE_I387)
13784 && flag_unsafe_math_optimizations"
13785 {
13786 rtx op0 = gen_reg_rtx (XFmode);
13787
13788 rtx op2 = gen_reg_rtx (XFmode);
13789 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13790
13791 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13792 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13793 DONE;
13794 })
13795
13796 (define_insn "fyl2xp1xf3_i387"
13797 [(set (match_operand:XF 0 "register_operand" "=f")
13798 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13799 (match_operand:XF 2 "register_operand" "u")]
13800 UNSPEC_FYL2XP1))
13801 (clobber (match_scratch:XF 3 "=2"))]
13802 "TARGET_USE_FANCY_MATH_387
13803 && flag_unsafe_math_optimizations"
13804 "fyl2xp1"
13805 [(set_attr "type" "fpspc")
13806 (set_attr "mode" "XF")])
13807
13808 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13809 [(set (match_operand:XF 0 "register_operand" "=f")
13810 (unspec:XF [(float_extend:XF
13811 (match_operand:MODEF 1 "register_operand" "0"))
13812 (match_operand:XF 2 "register_operand" "u")]
13813 UNSPEC_FYL2XP1))
13814 (clobber (match_scratch:XF 3 "=2"))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13817 || TARGET_MIX_SSE_I387)
13818 && flag_unsafe_math_optimizations"
13819 "fyl2xp1"
13820 [(set_attr "type" "fpspc")
13821 (set_attr "mode" "XF")])
13822
13823 (define_expand "log1pxf2"
13824 [(use (match_operand:XF 0 "register_operand" ""))
13825 (use (match_operand:XF 1 "register_operand" ""))]
13826 "TARGET_USE_FANCY_MATH_387
13827 && flag_unsafe_math_optimizations"
13828 {
13829 if (optimize_insn_for_size_p ())
13830 FAIL;
13831
13832 ix86_emit_i387_log1p (operands[0], operands[1]);
13833 DONE;
13834 })
13835
13836 (define_expand "log1p<mode>2"
13837 [(use (match_operand:MODEF 0 "register_operand" ""))
13838 (use (match_operand:MODEF 1 "register_operand" ""))]
13839 "TARGET_USE_FANCY_MATH_387
13840 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13841 || TARGET_MIX_SSE_I387)
13842 && flag_unsafe_math_optimizations"
13843 {
13844 rtx op0;
13845
13846 if (optimize_insn_for_size_p ())
13847 FAIL;
13848
13849 op0 = gen_reg_rtx (XFmode);
13850
13851 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13852
13853 ix86_emit_i387_log1p (op0, operands[1]);
13854 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13855 DONE;
13856 })
13857
13858 (define_insn "fxtractxf3_i387"
13859 [(set (match_operand:XF 0 "register_operand" "=f")
13860 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13861 UNSPEC_XTRACT_FRACT))
13862 (set (match_operand:XF 1 "register_operand" "=u")
13863 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13864 "TARGET_USE_FANCY_MATH_387
13865 && flag_unsafe_math_optimizations"
13866 "fxtract"
13867 [(set_attr "type" "fpspc")
13868 (set_attr "mode" "XF")])
13869
13870 (define_insn "fxtract_extend<mode>xf3_i387"
13871 [(set (match_operand:XF 0 "register_operand" "=f")
13872 (unspec:XF [(float_extend:XF
13873 (match_operand:MODEF 2 "register_operand" "0"))]
13874 UNSPEC_XTRACT_FRACT))
13875 (set (match_operand:XF 1 "register_operand" "=u")
13876 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13877 "TARGET_USE_FANCY_MATH_387
13878 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13879 || TARGET_MIX_SSE_I387)
13880 && flag_unsafe_math_optimizations"
13881 "fxtract"
13882 [(set_attr "type" "fpspc")
13883 (set_attr "mode" "XF")])
13884
13885 (define_expand "logbxf2"
13886 [(parallel [(set (match_dup 2)
13887 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13888 UNSPEC_XTRACT_FRACT))
13889 (set (match_operand:XF 0 "register_operand" "")
13890 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13891 "TARGET_USE_FANCY_MATH_387
13892 && flag_unsafe_math_optimizations"
13893 "operands[2] = gen_reg_rtx (XFmode);")
13894
13895 (define_expand "logb<mode>2"
13896 [(use (match_operand:MODEF 0 "register_operand" ""))
13897 (use (match_operand:MODEF 1 "register_operand" ""))]
13898 "TARGET_USE_FANCY_MATH_387
13899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13900 || TARGET_MIX_SSE_I387)
13901 && flag_unsafe_math_optimizations"
13902 {
13903 rtx op0 = gen_reg_rtx (XFmode);
13904 rtx op1 = gen_reg_rtx (XFmode);
13905
13906 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13907 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13908 DONE;
13909 })
13910
13911 (define_expand "ilogbxf2"
13912 [(use (match_operand:SI 0 "register_operand" ""))
13913 (use (match_operand:XF 1 "register_operand" ""))]
13914 "TARGET_USE_FANCY_MATH_387
13915 && flag_unsafe_math_optimizations"
13916 {
13917 rtx op0, op1;
13918
13919 if (optimize_insn_for_size_p ())
13920 FAIL;
13921
13922 op0 = gen_reg_rtx (XFmode);
13923 op1 = gen_reg_rtx (XFmode);
13924
13925 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13926 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13927 DONE;
13928 })
13929
13930 (define_expand "ilogb<mode>2"
13931 [(use (match_operand:SI 0 "register_operand" ""))
13932 (use (match_operand:MODEF 1 "register_operand" ""))]
13933 "TARGET_USE_FANCY_MATH_387
13934 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13935 || TARGET_MIX_SSE_I387)
13936 && flag_unsafe_math_optimizations"
13937 {
13938 rtx op0, op1;
13939
13940 if (optimize_insn_for_size_p ())
13941 FAIL;
13942
13943 op0 = gen_reg_rtx (XFmode);
13944 op1 = gen_reg_rtx (XFmode);
13945
13946 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13947 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13948 DONE;
13949 })
13950
13951 (define_insn "*f2xm1xf2_i387"
13952 [(set (match_operand:XF 0 "register_operand" "=f")
13953 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13954 UNSPEC_F2XM1))]
13955 "TARGET_USE_FANCY_MATH_387
13956 && flag_unsafe_math_optimizations"
13957 "f2xm1"
13958 [(set_attr "type" "fpspc")
13959 (set_attr "mode" "XF")])
13960
13961 (define_insn "*fscalexf4_i387"
13962 [(set (match_operand:XF 0 "register_operand" "=f")
13963 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13964 (match_operand:XF 3 "register_operand" "1")]
13965 UNSPEC_FSCALE_FRACT))
13966 (set (match_operand:XF 1 "register_operand" "=u")
13967 (unspec:XF [(match_dup 2) (match_dup 3)]
13968 UNSPEC_FSCALE_EXP))]
13969 "TARGET_USE_FANCY_MATH_387
13970 && flag_unsafe_math_optimizations"
13971 "fscale"
13972 [(set_attr "type" "fpspc")
13973 (set_attr "mode" "XF")])
13974
13975 (define_expand "expNcorexf3"
13976 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13977 (match_operand:XF 2 "register_operand" "")))
13978 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13979 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13980 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13981 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13982 (parallel [(set (match_operand:XF 0 "register_operand" "")
13983 (unspec:XF [(match_dup 8) (match_dup 4)]
13984 UNSPEC_FSCALE_FRACT))
13985 (set (match_dup 9)
13986 (unspec:XF [(match_dup 8) (match_dup 4)]
13987 UNSPEC_FSCALE_EXP))])]
13988 "TARGET_USE_FANCY_MATH_387
13989 && flag_unsafe_math_optimizations"
13990 {
13991 int i;
13992
13993 if (optimize_insn_for_size_p ())
13994 FAIL;
13995
13996 for (i = 3; i < 10; i++)
13997 operands[i] = gen_reg_rtx (XFmode);
13998
13999 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14000 })
14001
14002 (define_expand "expxf2"
14003 [(use (match_operand:XF 0 "register_operand" ""))
14004 (use (match_operand:XF 1 "register_operand" ""))]
14005 "TARGET_USE_FANCY_MATH_387
14006 && flag_unsafe_math_optimizations"
14007 {
14008 rtx op2;
14009
14010 if (optimize_insn_for_size_p ())
14011 FAIL;
14012
14013 op2 = gen_reg_rtx (XFmode);
14014 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14015
14016 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14017 DONE;
14018 })
14019
14020 (define_expand "exp<mode>2"
14021 [(use (match_operand:MODEF 0 "register_operand" ""))
14022 (use (match_operand:MODEF 1 "general_operand" ""))]
14023 "TARGET_USE_FANCY_MATH_387
14024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14025 || TARGET_MIX_SSE_I387)
14026 && flag_unsafe_math_optimizations"
14027 {
14028 rtx op0, op1;
14029
14030 if (optimize_insn_for_size_p ())
14031 FAIL;
14032
14033 op0 = gen_reg_rtx (XFmode);
14034 op1 = gen_reg_rtx (XFmode);
14035
14036 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14037 emit_insn (gen_expxf2 (op0, op1));
14038 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14039 DONE;
14040 })
14041
14042 (define_expand "exp10xf2"
14043 [(use (match_operand:XF 0 "register_operand" ""))
14044 (use (match_operand:XF 1 "register_operand" ""))]
14045 "TARGET_USE_FANCY_MATH_387
14046 && flag_unsafe_math_optimizations"
14047 {
14048 rtx op2;
14049
14050 if (optimize_insn_for_size_p ())
14051 FAIL;
14052
14053 op2 = gen_reg_rtx (XFmode);
14054 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14055
14056 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14057 DONE;
14058 })
14059
14060 (define_expand "exp10<mode>2"
14061 [(use (match_operand:MODEF 0 "register_operand" ""))
14062 (use (match_operand:MODEF 1 "general_operand" ""))]
14063 "TARGET_USE_FANCY_MATH_387
14064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14065 || TARGET_MIX_SSE_I387)
14066 && flag_unsafe_math_optimizations"
14067 {
14068 rtx op0, op1;
14069
14070 if (optimize_insn_for_size_p ())
14071 FAIL;
14072
14073 op0 = gen_reg_rtx (XFmode);
14074 op1 = gen_reg_rtx (XFmode);
14075
14076 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14077 emit_insn (gen_exp10xf2 (op0, op1));
14078 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14079 DONE;
14080 })
14081
14082 (define_expand "exp2xf2"
14083 [(use (match_operand:XF 0 "register_operand" ""))
14084 (use (match_operand:XF 1 "register_operand" ""))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && flag_unsafe_math_optimizations"
14087 {
14088 rtx op2;
14089
14090 if (optimize_insn_for_size_p ())
14091 FAIL;
14092
14093 op2 = gen_reg_rtx (XFmode);
14094 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14095
14096 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14097 DONE;
14098 })
14099
14100 (define_expand "exp2<mode>2"
14101 [(use (match_operand:MODEF 0 "register_operand" ""))
14102 (use (match_operand:MODEF 1 "general_operand" ""))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14105 || TARGET_MIX_SSE_I387)
14106 && flag_unsafe_math_optimizations"
14107 {
14108 rtx op0, op1;
14109
14110 if (optimize_insn_for_size_p ())
14111 FAIL;
14112
14113 op0 = gen_reg_rtx (XFmode);
14114 op1 = gen_reg_rtx (XFmode);
14115
14116 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14117 emit_insn (gen_exp2xf2 (op0, op1));
14118 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14119 DONE;
14120 })
14121
14122 (define_expand "expm1xf2"
14123 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14124 (match_dup 2)))
14125 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14126 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14127 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14128 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14129 (parallel [(set (match_dup 7)
14130 (unspec:XF [(match_dup 6) (match_dup 4)]
14131 UNSPEC_FSCALE_FRACT))
14132 (set (match_dup 8)
14133 (unspec:XF [(match_dup 6) (match_dup 4)]
14134 UNSPEC_FSCALE_EXP))])
14135 (parallel [(set (match_dup 10)
14136 (unspec:XF [(match_dup 9) (match_dup 8)]
14137 UNSPEC_FSCALE_FRACT))
14138 (set (match_dup 11)
14139 (unspec:XF [(match_dup 9) (match_dup 8)]
14140 UNSPEC_FSCALE_EXP))])
14141 (set (match_dup 12) (minus:XF (match_dup 10)
14142 (float_extend:XF (match_dup 13))))
14143 (set (match_operand:XF 0 "register_operand" "")
14144 (plus:XF (match_dup 12) (match_dup 7)))]
14145 "TARGET_USE_FANCY_MATH_387
14146 && flag_unsafe_math_optimizations"
14147 {
14148 int i;
14149
14150 if (optimize_insn_for_size_p ())
14151 FAIL;
14152
14153 for (i = 2; i < 13; i++)
14154 operands[i] = gen_reg_rtx (XFmode);
14155
14156 operands[13]
14157 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14158
14159 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14160 })
14161
14162 (define_expand "expm1<mode>2"
14163 [(use (match_operand:MODEF 0 "register_operand" ""))
14164 (use (match_operand:MODEF 1 "general_operand" ""))]
14165 "TARGET_USE_FANCY_MATH_387
14166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167 || TARGET_MIX_SSE_I387)
14168 && flag_unsafe_math_optimizations"
14169 {
14170 rtx op0, op1;
14171
14172 if (optimize_insn_for_size_p ())
14173 FAIL;
14174
14175 op0 = gen_reg_rtx (XFmode);
14176 op1 = gen_reg_rtx (XFmode);
14177
14178 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14179 emit_insn (gen_expm1xf2 (op0, op1));
14180 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14181 DONE;
14182 })
14183
14184 (define_expand "ldexpxf3"
14185 [(set (match_dup 3)
14186 (float:XF (match_operand:SI 2 "register_operand" "")))
14187 (parallel [(set (match_operand:XF 0 " register_operand" "")
14188 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14189 (match_dup 3)]
14190 UNSPEC_FSCALE_FRACT))
14191 (set (match_dup 4)
14192 (unspec:XF [(match_dup 1) (match_dup 3)]
14193 UNSPEC_FSCALE_EXP))])]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14196 {
14197 if (optimize_insn_for_size_p ())
14198 FAIL;
14199
14200 operands[3] = gen_reg_rtx (XFmode);
14201 operands[4] = gen_reg_rtx (XFmode);
14202 })
14203
14204 (define_expand "ldexp<mode>3"
14205 [(use (match_operand:MODEF 0 "register_operand" ""))
14206 (use (match_operand:MODEF 1 "general_operand" ""))
14207 (use (match_operand:SI 2 "register_operand" ""))]
14208 "TARGET_USE_FANCY_MATH_387
14209 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14210 || TARGET_MIX_SSE_I387)
14211 && flag_unsafe_math_optimizations"
14212 {
14213 rtx op0, op1;
14214
14215 if (optimize_insn_for_size_p ())
14216 FAIL;
14217
14218 op0 = gen_reg_rtx (XFmode);
14219 op1 = gen_reg_rtx (XFmode);
14220
14221 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14222 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14223 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14224 DONE;
14225 })
14226
14227 (define_expand "scalbxf3"
14228 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14229 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14230 (match_operand:XF 2 "register_operand" "")]
14231 UNSPEC_FSCALE_FRACT))
14232 (set (match_dup 3)
14233 (unspec:XF [(match_dup 1) (match_dup 2)]
14234 UNSPEC_FSCALE_EXP))])]
14235 "TARGET_USE_FANCY_MATH_387
14236 && flag_unsafe_math_optimizations"
14237 {
14238 if (optimize_insn_for_size_p ())
14239 FAIL;
14240
14241 operands[3] = gen_reg_rtx (XFmode);
14242 })
14243
14244 (define_expand "scalb<mode>3"
14245 [(use (match_operand:MODEF 0 "register_operand" ""))
14246 (use (match_operand:MODEF 1 "general_operand" ""))
14247 (use (match_operand:MODEF 2 "general_operand" ""))]
14248 "TARGET_USE_FANCY_MATH_387
14249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14250 || TARGET_MIX_SSE_I387)
14251 && flag_unsafe_math_optimizations"
14252 {
14253 rtx op0, op1, op2;
14254
14255 if (optimize_insn_for_size_p ())
14256 FAIL;
14257
14258 op0 = gen_reg_rtx (XFmode);
14259 op1 = gen_reg_rtx (XFmode);
14260 op2 = gen_reg_rtx (XFmode);
14261
14262 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14263 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14264 emit_insn (gen_scalbxf3 (op0, op1, op2));
14265 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14266 DONE;
14267 })
14268
14269 (define_expand "significandxf2"
14270 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14271 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14272 UNSPEC_XTRACT_FRACT))
14273 (set (match_dup 2)
14274 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14275 "TARGET_USE_FANCY_MATH_387
14276 && flag_unsafe_math_optimizations"
14277 "operands[2] = gen_reg_rtx (XFmode);")
14278
14279 (define_expand "significand<mode>2"
14280 [(use (match_operand:MODEF 0 "register_operand" ""))
14281 (use (match_operand:MODEF 1 "register_operand" ""))]
14282 "TARGET_USE_FANCY_MATH_387
14283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14284 || TARGET_MIX_SSE_I387)
14285 && flag_unsafe_math_optimizations"
14286 {
14287 rtx op0 = gen_reg_rtx (XFmode);
14288 rtx op1 = gen_reg_rtx (XFmode);
14289
14290 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14291 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14292 DONE;
14293 })
14294 \f
14295
14296 (define_insn "sse4_1_round<mode>2"
14297 [(set (match_operand:MODEF 0 "register_operand" "=x")
14298 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14299 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14300 UNSPEC_ROUND))]
14301 "TARGET_ROUND"
14302 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14303 [(set_attr "type" "ssecvt")
14304 (set_attr "prefix_extra" "1")
14305 (set_attr "prefix" "maybe_vex")
14306 (set_attr "mode" "<MODE>")])
14307
14308 (define_insn "rintxf2"
14309 [(set (match_operand:XF 0 "register_operand" "=f")
14310 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14311 UNSPEC_FRNDINT))]
14312 "TARGET_USE_FANCY_MATH_387
14313 && flag_unsafe_math_optimizations"
14314 "frndint"
14315 [(set_attr "type" "fpspc")
14316 (set_attr "mode" "XF")])
14317
14318 (define_expand "rint<mode>2"
14319 [(use (match_operand:MODEF 0 "register_operand" ""))
14320 (use (match_operand:MODEF 1 "register_operand" ""))]
14321 "(TARGET_USE_FANCY_MATH_387
14322 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14323 || TARGET_MIX_SSE_I387)
14324 && flag_unsafe_math_optimizations)
14325 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14326 && !flag_trapping_math)"
14327 {
14328 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14329 && !flag_trapping_math)
14330 {
14331 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14332 FAIL;
14333 if (TARGET_ROUND)
14334 emit_insn (gen_sse4_1_round<mode>2
14335 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14336 else
14337 ix86_expand_rint (operand0, operand1);
14338 }
14339 else
14340 {
14341 rtx op0 = gen_reg_rtx (XFmode);
14342 rtx op1 = gen_reg_rtx (XFmode);
14343
14344 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14345 emit_insn (gen_rintxf2 (op0, op1));
14346
14347 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14348 }
14349 DONE;
14350 })
14351
14352 (define_expand "round<mode>2"
14353 [(match_operand:MODEF 0 "register_operand" "")
14354 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14355 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14356 && !flag_trapping_math && !flag_rounding_math"
14357 {
14358 if (optimize_insn_for_size_p ())
14359 FAIL;
14360 if (TARGET_64BIT || (<MODE>mode != DFmode))
14361 ix86_expand_round (operand0, operand1);
14362 else
14363 ix86_expand_rounddf_32 (operand0, operand1);
14364 DONE;
14365 })
14366
14367 (define_insn_and_split "*fistdi2_1"
14368 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14369 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14370 UNSPEC_FIST))]
14371 "TARGET_USE_FANCY_MATH_387
14372 && can_create_pseudo_p ()"
14373 "#"
14374 "&& 1"
14375 [(const_int 0)]
14376 {
14377 if (memory_operand (operands[0], VOIDmode))
14378 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14379 else
14380 {
14381 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14382 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14383 operands[2]));
14384 }
14385 DONE;
14386 }
14387 [(set_attr "type" "fpspc")
14388 (set_attr "mode" "DI")])
14389
14390 (define_insn "fistdi2"
14391 [(set (match_operand:DI 0 "memory_operand" "=m")
14392 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14393 UNSPEC_FIST))
14394 (clobber (match_scratch:XF 2 "=&1f"))]
14395 "TARGET_USE_FANCY_MATH_387"
14396 "* return output_fix_trunc (insn, operands, false);"
14397 [(set_attr "type" "fpspc")
14398 (set_attr "mode" "DI")])
14399
14400 (define_insn "fistdi2_with_temp"
14401 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14402 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14403 UNSPEC_FIST))
14404 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14405 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14406 "TARGET_USE_FANCY_MATH_387"
14407 "#"
14408 [(set_attr "type" "fpspc")
14409 (set_attr "mode" "DI")])
14410
14411 (define_split
14412 [(set (match_operand:DI 0 "register_operand" "")
14413 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14414 UNSPEC_FIST))
14415 (clobber (match_operand:DI 2 "memory_operand" ""))
14416 (clobber (match_scratch 3 ""))]
14417 "reload_completed"
14418 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14419 (clobber (match_dup 3))])
14420 (set (match_dup 0) (match_dup 2))])
14421
14422 (define_split
14423 [(set (match_operand:DI 0 "memory_operand" "")
14424 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14425 UNSPEC_FIST))
14426 (clobber (match_operand:DI 2 "memory_operand" ""))
14427 (clobber (match_scratch 3 ""))]
14428 "reload_completed"
14429 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14430 (clobber (match_dup 3))])])
14431
14432 (define_insn_and_split "*fist<mode>2_1"
14433 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14434 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14435 UNSPEC_FIST))]
14436 "TARGET_USE_FANCY_MATH_387
14437 && can_create_pseudo_p ()"
14438 "#"
14439 "&& 1"
14440 [(const_int 0)]
14441 {
14442 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14443 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14444 operands[2]));
14445 DONE;
14446 }
14447 [(set_attr "type" "fpspc")
14448 (set_attr "mode" "<MODE>")])
14449
14450 (define_insn "fist<mode>2"
14451 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14452 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14453 UNSPEC_FIST))]
14454 "TARGET_USE_FANCY_MATH_387"
14455 "* return output_fix_trunc (insn, operands, false);"
14456 [(set_attr "type" "fpspc")
14457 (set_attr "mode" "<MODE>")])
14458
14459 (define_insn "fist<mode>2_with_temp"
14460 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14461 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14462 UNSPEC_FIST))
14463 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14464 "TARGET_USE_FANCY_MATH_387"
14465 "#"
14466 [(set_attr "type" "fpspc")
14467 (set_attr "mode" "<MODE>")])
14468
14469 (define_split
14470 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14471 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14472 UNSPEC_FIST))
14473 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14474 "reload_completed"
14475 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14476 (set (match_dup 0) (match_dup 2))])
14477
14478 (define_split
14479 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14480 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14481 UNSPEC_FIST))
14482 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14483 "reload_completed"
14484 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14485
14486 (define_expand "lrintxf<mode>2"
14487 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14488 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14489 UNSPEC_FIST))]
14490 "TARGET_USE_FANCY_MATH_387")
14491
14492 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14493 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14494 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14495 UNSPEC_FIX_NOTRUNC))]
14496 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14497 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14498
14499 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14500 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14501 (match_operand:MODEF 1 "register_operand" "")]
14502 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14503 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14504 && !flag_trapping_math && !flag_rounding_math"
14505 {
14506 if (optimize_insn_for_size_p ())
14507 FAIL;
14508 ix86_expand_lround (operand0, operand1);
14509 DONE;
14510 })
14511
14512 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14513 (define_insn_and_split "frndintxf2_floor"
14514 [(set (match_operand:XF 0 "register_operand" "")
14515 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14516 UNSPEC_FRNDINT_FLOOR))
14517 (clobber (reg:CC FLAGS_REG))]
14518 "TARGET_USE_FANCY_MATH_387
14519 && flag_unsafe_math_optimizations
14520 && can_create_pseudo_p ()"
14521 "#"
14522 "&& 1"
14523 [(const_int 0)]
14524 {
14525 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14526
14527 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14528 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14529
14530 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14531 operands[2], operands[3]));
14532 DONE;
14533 }
14534 [(set_attr "type" "frndint")
14535 (set_attr "i387_cw" "floor")
14536 (set_attr "mode" "XF")])
14537
14538 (define_insn "frndintxf2_floor_i387"
14539 [(set (match_operand:XF 0 "register_operand" "=f")
14540 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14541 UNSPEC_FRNDINT_FLOOR))
14542 (use (match_operand:HI 2 "memory_operand" "m"))
14543 (use (match_operand:HI 3 "memory_operand" "m"))]
14544 "TARGET_USE_FANCY_MATH_387
14545 && flag_unsafe_math_optimizations"
14546 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14547 [(set_attr "type" "frndint")
14548 (set_attr "i387_cw" "floor")
14549 (set_attr "mode" "XF")])
14550
14551 (define_expand "floorxf2"
14552 [(use (match_operand:XF 0 "register_operand" ""))
14553 (use (match_operand:XF 1 "register_operand" ""))]
14554 "TARGET_USE_FANCY_MATH_387
14555 && flag_unsafe_math_optimizations"
14556 {
14557 if (optimize_insn_for_size_p ())
14558 FAIL;
14559 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14560 DONE;
14561 })
14562
14563 (define_expand "floor<mode>2"
14564 [(use (match_operand:MODEF 0 "register_operand" ""))
14565 (use (match_operand:MODEF 1 "register_operand" ""))]
14566 "(TARGET_USE_FANCY_MATH_387
14567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568 || TARGET_MIX_SSE_I387)
14569 && flag_unsafe_math_optimizations)
14570 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14571 && !flag_trapping_math)"
14572 {
14573 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14574 && !flag_trapping_math
14575 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14576 {
14577 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14578 FAIL;
14579 if (TARGET_ROUND)
14580 emit_insn (gen_sse4_1_round<mode>2
14581 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14582 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14583 ix86_expand_floorceil (operand0, operand1, true);
14584 else
14585 ix86_expand_floorceildf_32 (operand0, operand1, true);
14586 }
14587 else
14588 {
14589 rtx op0, op1;
14590
14591 if (optimize_insn_for_size_p ())
14592 FAIL;
14593
14594 op0 = gen_reg_rtx (XFmode);
14595 op1 = gen_reg_rtx (XFmode);
14596 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14597 emit_insn (gen_frndintxf2_floor (op0, op1));
14598
14599 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14600 }
14601 DONE;
14602 })
14603
14604 (define_insn_and_split "*fist<mode>2_floor_1"
14605 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14606 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14607 UNSPEC_FIST_FLOOR))
14608 (clobber (reg:CC FLAGS_REG))]
14609 "TARGET_USE_FANCY_MATH_387
14610 && flag_unsafe_math_optimizations
14611 && can_create_pseudo_p ()"
14612 "#"
14613 "&& 1"
14614 [(const_int 0)]
14615 {
14616 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14617
14618 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14619 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14620 if (memory_operand (operands[0], VOIDmode))
14621 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14622 operands[2], operands[3]));
14623 else
14624 {
14625 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14626 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14627 operands[2], operands[3],
14628 operands[4]));
14629 }
14630 DONE;
14631 }
14632 [(set_attr "type" "fistp")
14633 (set_attr "i387_cw" "floor")
14634 (set_attr "mode" "<MODE>")])
14635
14636 (define_insn "fistdi2_floor"
14637 [(set (match_operand:DI 0 "memory_operand" "=m")
14638 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14639 UNSPEC_FIST_FLOOR))
14640 (use (match_operand:HI 2 "memory_operand" "m"))
14641 (use (match_operand:HI 3 "memory_operand" "m"))
14642 (clobber (match_scratch:XF 4 "=&1f"))]
14643 "TARGET_USE_FANCY_MATH_387
14644 && flag_unsafe_math_optimizations"
14645 "* return output_fix_trunc (insn, operands, false);"
14646 [(set_attr "type" "fistp")
14647 (set_attr "i387_cw" "floor")
14648 (set_attr "mode" "DI")])
14649
14650 (define_insn "fistdi2_floor_with_temp"
14651 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14652 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14653 UNSPEC_FIST_FLOOR))
14654 (use (match_operand:HI 2 "memory_operand" "m,m"))
14655 (use (match_operand:HI 3 "memory_operand" "m,m"))
14656 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14657 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14658 "TARGET_USE_FANCY_MATH_387
14659 && flag_unsafe_math_optimizations"
14660 "#"
14661 [(set_attr "type" "fistp")
14662 (set_attr "i387_cw" "floor")
14663 (set_attr "mode" "DI")])
14664
14665 (define_split
14666 [(set (match_operand:DI 0 "register_operand" "")
14667 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14668 UNSPEC_FIST_FLOOR))
14669 (use (match_operand:HI 2 "memory_operand" ""))
14670 (use (match_operand:HI 3 "memory_operand" ""))
14671 (clobber (match_operand:DI 4 "memory_operand" ""))
14672 (clobber (match_scratch 5 ""))]
14673 "reload_completed"
14674 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14675 (use (match_dup 2))
14676 (use (match_dup 3))
14677 (clobber (match_dup 5))])
14678 (set (match_dup 0) (match_dup 4))])
14679
14680 (define_split
14681 [(set (match_operand:DI 0 "memory_operand" "")
14682 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14683 UNSPEC_FIST_FLOOR))
14684 (use (match_operand:HI 2 "memory_operand" ""))
14685 (use (match_operand:HI 3 "memory_operand" ""))
14686 (clobber (match_operand:DI 4 "memory_operand" ""))
14687 (clobber (match_scratch 5 ""))]
14688 "reload_completed"
14689 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14690 (use (match_dup 2))
14691 (use (match_dup 3))
14692 (clobber (match_dup 5))])])
14693
14694 (define_insn "fist<mode>2_floor"
14695 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14696 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14697 UNSPEC_FIST_FLOOR))
14698 (use (match_operand:HI 2 "memory_operand" "m"))
14699 (use (match_operand:HI 3 "memory_operand" "m"))]
14700 "TARGET_USE_FANCY_MATH_387
14701 && flag_unsafe_math_optimizations"
14702 "* return output_fix_trunc (insn, operands, false);"
14703 [(set_attr "type" "fistp")
14704 (set_attr "i387_cw" "floor")
14705 (set_attr "mode" "<MODE>")])
14706
14707 (define_insn "fist<mode>2_floor_with_temp"
14708 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14709 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14710 UNSPEC_FIST_FLOOR))
14711 (use (match_operand:HI 2 "memory_operand" "m,m"))
14712 (use (match_operand:HI 3 "memory_operand" "m,m"))
14713 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14714 "TARGET_USE_FANCY_MATH_387
14715 && flag_unsafe_math_optimizations"
14716 "#"
14717 [(set_attr "type" "fistp")
14718 (set_attr "i387_cw" "floor")
14719 (set_attr "mode" "<MODE>")])
14720
14721 (define_split
14722 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14723 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14724 UNSPEC_FIST_FLOOR))
14725 (use (match_operand:HI 2 "memory_operand" ""))
14726 (use (match_operand:HI 3 "memory_operand" ""))
14727 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14728 "reload_completed"
14729 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14730 UNSPEC_FIST_FLOOR))
14731 (use (match_dup 2))
14732 (use (match_dup 3))])
14733 (set (match_dup 0) (match_dup 4))])
14734
14735 (define_split
14736 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14737 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14738 UNSPEC_FIST_FLOOR))
14739 (use (match_operand:HI 2 "memory_operand" ""))
14740 (use (match_operand:HI 3 "memory_operand" ""))
14741 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14742 "reload_completed"
14743 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14744 UNSPEC_FIST_FLOOR))
14745 (use (match_dup 2))
14746 (use (match_dup 3))])])
14747
14748 (define_expand "lfloorxf<mode>2"
14749 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14750 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14751 UNSPEC_FIST_FLOOR))
14752 (clobber (reg:CC FLAGS_REG))])]
14753 "TARGET_USE_FANCY_MATH_387
14754 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14755 && flag_unsafe_math_optimizations")
14756
14757 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14758 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14759 (match_operand:MODEF 1 "register_operand" "")]
14760 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14761 && !flag_trapping_math"
14762 {
14763 if (TARGET_64BIT && optimize_insn_for_size_p ())
14764 FAIL;
14765 ix86_expand_lfloorceil (operand0, operand1, true);
14766 DONE;
14767 })
14768
14769 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14770 (define_insn_and_split "frndintxf2_ceil"
14771 [(set (match_operand:XF 0 "register_operand" "")
14772 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14773 UNSPEC_FRNDINT_CEIL))
14774 (clobber (reg:CC FLAGS_REG))]
14775 "TARGET_USE_FANCY_MATH_387
14776 && flag_unsafe_math_optimizations
14777 && can_create_pseudo_p ()"
14778 "#"
14779 "&& 1"
14780 [(const_int 0)]
14781 {
14782 ix86_optimize_mode_switching[I387_CEIL] = 1;
14783
14784 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14785 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14786
14787 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14788 operands[2], operands[3]));
14789 DONE;
14790 }
14791 [(set_attr "type" "frndint")
14792 (set_attr "i387_cw" "ceil")
14793 (set_attr "mode" "XF")])
14794
14795 (define_insn "frndintxf2_ceil_i387"
14796 [(set (match_operand:XF 0 "register_operand" "=f")
14797 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14798 UNSPEC_FRNDINT_CEIL))
14799 (use (match_operand:HI 2 "memory_operand" "m"))
14800 (use (match_operand:HI 3 "memory_operand" "m"))]
14801 "TARGET_USE_FANCY_MATH_387
14802 && flag_unsafe_math_optimizations"
14803 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14804 [(set_attr "type" "frndint")
14805 (set_attr "i387_cw" "ceil")
14806 (set_attr "mode" "XF")])
14807
14808 (define_expand "ceilxf2"
14809 [(use (match_operand:XF 0 "register_operand" ""))
14810 (use (match_operand:XF 1 "register_operand" ""))]
14811 "TARGET_USE_FANCY_MATH_387
14812 && flag_unsafe_math_optimizations"
14813 {
14814 if (optimize_insn_for_size_p ())
14815 FAIL;
14816 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14817 DONE;
14818 })
14819
14820 (define_expand "ceil<mode>2"
14821 [(use (match_operand:MODEF 0 "register_operand" ""))
14822 (use (match_operand:MODEF 1 "register_operand" ""))]
14823 "(TARGET_USE_FANCY_MATH_387
14824 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14825 || TARGET_MIX_SSE_I387)
14826 && flag_unsafe_math_optimizations)
14827 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14828 && !flag_trapping_math)"
14829 {
14830 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14831 && !flag_trapping_math
14832 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14833 {
14834 if (TARGET_ROUND)
14835 emit_insn (gen_sse4_1_round<mode>2
14836 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14837 else if (optimize_insn_for_size_p ())
14838 FAIL;
14839 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14840 ix86_expand_floorceil (operand0, operand1, false);
14841 else
14842 ix86_expand_floorceildf_32 (operand0, operand1, false);
14843 }
14844 else
14845 {
14846 rtx op0, op1;
14847
14848 if (optimize_insn_for_size_p ())
14849 FAIL;
14850
14851 op0 = gen_reg_rtx (XFmode);
14852 op1 = gen_reg_rtx (XFmode);
14853 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14854 emit_insn (gen_frndintxf2_ceil (op0, op1));
14855
14856 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14857 }
14858 DONE;
14859 })
14860
14861 (define_insn_and_split "*fist<mode>2_ceil_1"
14862 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14863 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14864 UNSPEC_FIST_CEIL))
14865 (clobber (reg:CC FLAGS_REG))]
14866 "TARGET_USE_FANCY_MATH_387
14867 && flag_unsafe_math_optimizations
14868 && can_create_pseudo_p ()"
14869 "#"
14870 "&& 1"
14871 [(const_int 0)]
14872 {
14873 ix86_optimize_mode_switching[I387_CEIL] = 1;
14874
14875 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14876 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14877 if (memory_operand (operands[0], VOIDmode))
14878 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14879 operands[2], operands[3]));
14880 else
14881 {
14882 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14883 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14884 operands[2], operands[3],
14885 operands[4]));
14886 }
14887 DONE;
14888 }
14889 [(set_attr "type" "fistp")
14890 (set_attr "i387_cw" "ceil")
14891 (set_attr "mode" "<MODE>")])
14892
14893 (define_insn "fistdi2_ceil"
14894 [(set (match_operand:DI 0 "memory_operand" "=m")
14895 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14896 UNSPEC_FIST_CEIL))
14897 (use (match_operand:HI 2 "memory_operand" "m"))
14898 (use (match_operand:HI 3 "memory_operand" "m"))
14899 (clobber (match_scratch:XF 4 "=&1f"))]
14900 "TARGET_USE_FANCY_MATH_387
14901 && flag_unsafe_math_optimizations"
14902 "* return output_fix_trunc (insn, operands, false);"
14903 [(set_attr "type" "fistp")
14904 (set_attr "i387_cw" "ceil")
14905 (set_attr "mode" "DI")])
14906
14907 (define_insn "fistdi2_ceil_with_temp"
14908 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14909 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14910 UNSPEC_FIST_CEIL))
14911 (use (match_operand:HI 2 "memory_operand" "m,m"))
14912 (use (match_operand:HI 3 "memory_operand" "m,m"))
14913 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14914 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14915 "TARGET_USE_FANCY_MATH_387
14916 && flag_unsafe_math_optimizations"
14917 "#"
14918 [(set_attr "type" "fistp")
14919 (set_attr "i387_cw" "ceil")
14920 (set_attr "mode" "DI")])
14921
14922 (define_split
14923 [(set (match_operand:DI 0 "register_operand" "")
14924 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14925 UNSPEC_FIST_CEIL))
14926 (use (match_operand:HI 2 "memory_operand" ""))
14927 (use (match_operand:HI 3 "memory_operand" ""))
14928 (clobber (match_operand:DI 4 "memory_operand" ""))
14929 (clobber (match_scratch 5 ""))]
14930 "reload_completed"
14931 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14932 (use (match_dup 2))
14933 (use (match_dup 3))
14934 (clobber (match_dup 5))])
14935 (set (match_dup 0) (match_dup 4))])
14936
14937 (define_split
14938 [(set (match_operand:DI 0 "memory_operand" "")
14939 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14940 UNSPEC_FIST_CEIL))
14941 (use (match_operand:HI 2 "memory_operand" ""))
14942 (use (match_operand:HI 3 "memory_operand" ""))
14943 (clobber (match_operand:DI 4 "memory_operand" ""))
14944 (clobber (match_scratch 5 ""))]
14945 "reload_completed"
14946 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14947 (use (match_dup 2))
14948 (use (match_dup 3))
14949 (clobber (match_dup 5))])])
14950
14951 (define_insn "fist<mode>2_ceil"
14952 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14953 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14954 UNSPEC_FIST_CEIL))
14955 (use (match_operand:HI 2 "memory_operand" "m"))
14956 (use (match_operand:HI 3 "memory_operand" "m"))]
14957 "TARGET_USE_FANCY_MATH_387
14958 && flag_unsafe_math_optimizations"
14959 "* return output_fix_trunc (insn, operands, false);"
14960 [(set_attr "type" "fistp")
14961 (set_attr "i387_cw" "ceil")
14962 (set_attr "mode" "<MODE>")])
14963
14964 (define_insn "fist<mode>2_ceil_with_temp"
14965 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14966 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14967 UNSPEC_FIST_CEIL))
14968 (use (match_operand:HI 2 "memory_operand" "m,m"))
14969 (use (match_operand:HI 3 "memory_operand" "m,m"))
14970 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14971 "TARGET_USE_FANCY_MATH_387
14972 && flag_unsafe_math_optimizations"
14973 "#"
14974 [(set_attr "type" "fistp")
14975 (set_attr "i387_cw" "ceil")
14976 (set_attr "mode" "<MODE>")])
14977
14978 (define_split
14979 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14980 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14981 UNSPEC_FIST_CEIL))
14982 (use (match_operand:HI 2 "memory_operand" ""))
14983 (use (match_operand:HI 3 "memory_operand" ""))
14984 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14985 "reload_completed"
14986 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14987 UNSPEC_FIST_CEIL))
14988 (use (match_dup 2))
14989 (use (match_dup 3))])
14990 (set (match_dup 0) (match_dup 4))])
14991
14992 (define_split
14993 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14994 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14995 UNSPEC_FIST_CEIL))
14996 (use (match_operand:HI 2 "memory_operand" ""))
14997 (use (match_operand:HI 3 "memory_operand" ""))
14998 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14999 "reload_completed"
15000 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15001 UNSPEC_FIST_CEIL))
15002 (use (match_dup 2))
15003 (use (match_dup 3))])])
15004
15005 (define_expand "lceilxf<mode>2"
15006 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15007 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15008 UNSPEC_FIST_CEIL))
15009 (clobber (reg:CC FLAGS_REG))])]
15010 "TARGET_USE_FANCY_MATH_387
15011 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15012 && flag_unsafe_math_optimizations")
15013
15014 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15015 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15016 (match_operand:MODEF 1 "register_operand" "")]
15017 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15018 && !flag_trapping_math"
15019 {
15020 ix86_expand_lfloorceil (operand0, operand1, false);
15021 DONE;
15022 })
15023
15024 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15025 (define_insn_and_split "frndintxf2_trunc"
15026 [(set (match_operand:XF 0 "register_operand" "")
15027 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15028 UNSPEC_FRNDINT_TRUNC))
15029 (clobber (reg:CC FLAGS_REG))]
15030 "TARGET_USE_FANCY_MATH_387
15031 && flag_unsafe_math_optimizations
15032 && can_create_pseudo_p ()"
15033 "#"
15034 "&& 1"
15035 [(const_int 0)]
15036 {
15037 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15038
15039 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15040 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15041
15042 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15043 operands[2], operands[3]));
15044 DONE;
15045 }
15046 [(set_attr "type" "frndint")
15047 (set_attr "i387_cw" "trunc")
15048 (set_attr "mode" "XF")])
15049
15050 (define_insn "frndintxf2_trunc_i387"
15051 [(set (match_operand:XF 0 "register_operand" "=f")
15052 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15053 UNSPEC_FRNDINT_TRUNC))
15054 (use (match_operand:HI 2 "memory_operand" "m"))
15055 (use (match_operand:HI 3 "memory_operand" "m"))]
15056 "TARGET_USE_FANCY_MATH_387
15057 && flag_unsafe_math_optimizations"
15058 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15059 [(set_attr "type" "frndint")
15060 (set_attr "i387_cw" "trunc")
15061 (set_attr "mode" "XF")])
15062
15063 (define_expand "btruncxf2"
15064 [(use (match_operand:XF 0 "register_operand" ""))
15065 (use (match_operand:XF 1 "register_operand" ""))]
15066 "TARGET_USE_FANCY_MATH_387
15067 && flag_unsafe_math_optimizations"
15068 {
15069 if (optimize_insn_for_size_p ())
15070 FAIL;
15071 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15072 DONE;
15073 })
15074
15075 (define_expand "btrunc<mode>2"
15076 [(use (match_operand:MODEF 0 "register_operand" ""))
15077 (use (match_operand:MODEF 1 "register_operand" ""))]
15078 "(TARGET_USE_FANCY_MATH_387
15079 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15080 || TARGET_MIX_SSE_I387)
15081 && flag_unsafe_math_optimizations)
15082 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15083 && !flag_trapping_math)"
15084 {
15085 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15086 && !flag_trapping_math
15087 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15088 {
15089 if (TARGET_ROUND)
15090 emit_insn (gen_sse4_1_round<mode>2
15091 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15092 else if (optimize_insn_for_size_p ())
15093 FAIL;
15094 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15095 ix86_expand_trunc (operand0, operand1);
15096 else
15097 ix86_expand_truncdf_32 (operand0, operand1);
15098 }
15099 else
15100 {
15101 rtx op0, op1;
15102
15103 if (optimize_insn_for_size_p ())
15104 FAIL;
15105
15106 op0 = gen_reg_rtx (XFmode);
15107 op1 = gen_reg_rtx (XFmode);
15108 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15109 emit_insn (gen_frndintxf2_trunc (op0, op1));
15110
15111 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15112 }
15113 DONE;
15114 })
15115
15116 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15117 (define_insn_and_split "frndintxf2_mask_pm"
15118 [(set (match_operand:XF 0 "register_operand" "")
15119 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15120 UNSPEC_FRNDINT_MASK_PM))
15121 (clobber (reg:CC FLAGS_REG))]
15122 "TARGET_USE_FANCY_MATH_387
15123 && flag_unsafe_math_optimizations
15124 && can_create_pseudo_p ()"
15125 "#"
15126 "&& 1"
15127 [(const_int 0)]
15128 {
15129 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15130
15131 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15132 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15133
15134 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15135 operands[2], operands[3]));
15136 DONE;
15137 }
15138 [(set_attr "type" "frndint")
15139 (set_attr "i387_cw" "mask_pm")
15140 (set_attr "mode" "XF")])
15141
15142 (define_insn "frndintxf2_mask_pm_i387"
15143 [(set (match_operand:XF 0 "register_operand" "=f")
15144 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15145 UNSPEC_FRNDINT_MASK_PM))
15146 (use (match_operand:HI 2 "memory_operand" "m"))
15147 (use (match_operand:HI 3 "memory_operand" "m"))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations"
15150 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15151 [(set_attr "type" "frndint")
15152 (set_attr "i387_cw" "mask_pm")
15153 (set_attr "mode" "XF")])
15154
15155 (define_expand "nearbyintxf2"
15156 [(use (match_operand:XF 0 "register_operand" ""))
15157 (use (match_operand:XF 1 "register_operand" ""))]
15158 "TARGET_USE_FANCY_MATH_387
15159 && flag_unsafe_math_optimizations"
15160 {
15161 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15162 DONE;
15163 })
15164
15165 (define_expand "nearbyint<mode>2"
15166 [(use (match_operand:MODEF 0 "register_operand" ""))
15167 (use (match_operand:MODEF 1 "register_operand" ""))]
15168 "TARGET_USE_FANCY_MATH_387
15169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15170 || TARGET_MIX_SSE_I387)
15171 && flag_unsafe_math_optimizations"
15172 {
15173 rtx op0 = gen_reg_rtx (XFmode);
15174 rtx op1 = gen_reg_rtx (XFmode);
15175
15176 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15177 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15178
15179 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15180 DONE;
15181 })
15182
15183 (define_insn "fxam<mode>2_i387"
15184 [(set (match_operand:HI 0 "register_operand" "=a")
15185 (unspec:HI
15186 [(match_operand:X87MODEF 1 "register_operand" "f")]
15187 UNSPEC_FXAM))]
15188 "TARGET_USE_FANCY_MATH_387"
15189 "fxam\n\tfnstsw\t%0"
15190 [(set_attr "type" "multi")
15191 (set_attr "length" "4")
15192 (set_attr "unit" "i387")
15193 (set_attr "mode" "<MODE>")])
15194
15195 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15196 [(set (match_operand:HI 0 "register_operand" "")
15197 (unspec:HI
15198 [(match_operand:MODEF 1 "memory_operand" "")]
15199 UNSPEC_FXAM_MEM))]
15200 "TARGET_USE_FANCY_MATH_387
15201 && can_create_pseudo_p ()"
15202 "#"
15203 "&& 1"
15204 [(set (match_dup 2)(match_dup 1))
15205 (set (match_dup 0)
15206 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15207 {
15208 operands[2] = gen_reg_rtx (<MODE>mode);
15209
15210 MEM_VOLATILE_P (operands[1]) = 1;
15211 }
15212 [(set_attr "type" "multi")
15213 (set_attr "unit" "i387")
15214 (set_attr "mode" "<MODE>")])
15215
15216 (define_expand "isinfxf2"
15217 [(use (match_operand:SI 0 "register_operand" ""))
15218 (use (match_operand:XF 1 "register_operand" ""))]
15219 "TARGET_USE_FANCY_MATH_387
15220 && TARGET_C99_FUNCTIONS"
15221 {
15222 rtx mask = GEN_INT (0x45);
15223 rtx val = GEN_INT (0x05);
15224
15225 rtx cond;
15226
15227 rtx scratch = gen_reg_rtx (HImode);
15228 rtx res = gen_reg_rtx (QImode);
15229
15230 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15231
15232 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15233 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15234 cond = gen_rtx_fmt_ee (EQ, QImode,
15235 gen_rtx_REG (CCmode, FLAGS_REG),
15236 const0_rtx);
15237 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15238 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15239 DONE;
15240 })
15241
15242 (define_expand "isinf<mode>2"
15243 [(use (match_operand:SI 0 "register_operand" ""))
15244 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15245 "TARGET_USE_FANCY_MATH_387
15246 && TARGET_C99_FUNCTIONS
15247 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15248 {
15249 rtx mask = GEN_INT (0x45);
15250 rtx val = GEN_INT (0x05);
15251
15252 rtx cond;
15253
15254 rtx scratch = gen_reg_rtx (HImode);
15255 rtx res = gen_reg_rtx (QImode);
15256
15257 /* Remove excess precision by forcing value through memory. */
15258 if (memory_operand (operands[1], VOIDmode))
15259 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15260 else
15261 {
15262 enum ix86_stack_slot slot = (virtuals_instantiated
15263 ? SLOT_TEMP
15264 : SLOT_VIRTUAL);
15265 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15266
15267 emit_move_insn (temp, operands[1]);
15268 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15269 }
15270
15271 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15272 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15273 cond = gen_rtx_fmt_ee (EQ, QImode,
15274 gen_rtx_REG (CCmode, FLAGS_REG),
15275 const0_rtx);
15276 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15277 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15278 DONE;
15279 })
15280
15281 (define_expand "signbitxf2"
15282 [(use (match_operand:SI 0 "register_operand" ""))
15283 (use (match_operand:XF 1 "register_operand" ""))]
15284 "TARGET_USE_FANCY_MATH_387"
15285 {
15286 rtx scratch = gen_reg_rtx (HImode);
15287
15288 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15289 emit_insn (gen_andsi3 (operands[0],
15290 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15291 DONE;
15292 })
15293
15294 (define_insn "movmsk_df"
15295 [(set (match_operand:SI 0 "register_operand" "=r")
15296 (unspec:SI
15297 [(match_operand:DF 1 "register_operand" "x")]
15298 UNSPEC_MOVMSK))]
15299 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15300 "%vmovmskpd\t{%1, %0|%0, %1}"
15301 [(set_attr "type" "ssemov")
15302 (set_attr "prefix" "maybe_vex")
15303 (set_attr "mode" "DF")])
15304
15305 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15306 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15307 (define_expand "signbitdf2"
15308 [(use (match_operand:SI 0 "register_operand" ""))
15309 (use (match_operand:DF 1 "register_operand" ""))]
15310 "TARGET_USE_FANCY_MATH_387
15311 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15312 {
15313 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15314 {
15315 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15316 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15317 }
15318 else
15319 {
15320 rtx scratch = gen_reg_rtx (HImode);
15321
15322 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15323 emit_insn (gen_andsi3 (operands[0],
15324 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15325 }
15326 DONE;
15327 })
15328
15329 (define_expand "signbitsf2"
15330 [(use (match_operand:SI 0 "register_operand" ""))
15331 (use (match_operand:SF 1 "register_operand" ""))]
15332 "TARGET_USE_FANCY_MATH_387
15333 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15334 {
15335 rtx scratch = gen_reg_rtx (HImode);
15336
15337 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15338 emit_insn (gen_andsi3 (operands[0],
15339 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15340 DONE;
15341 })
15342 \f
15343 ;; Block operation instructions
15344
15345 (define_insn "cld"
15346 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15347 ""
15348 "cld"
15349 [(set_attr "length" "1")
15350 (set_attr "length_immediate" "0")
15351 (set_attr "modrm" "0")])
15352
15353 (define_expand "movmem<mode>"
15354 [(use (match_operand:BLK 0 "memory_operand" ""))
15355 (use (match_operand:BLK 1 "memory_operand" ""))
15356 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15357 (use (match_operand:SWI48 3 "const_int_operand" ""))
15358 (use (match_operand:SI 4 "const_int_operand" ""))
15359 (use (match_operand:SI 5 "const_int_operand" ""))]
15360 ""
15361 {
15362 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15363 operands[4], operands[5]))
15364 DONE;
15365 else
15366 FAIL;
15367 })
15368
15369 ;; Most CPUs don't like single string operations
15370 ;; Handle this case here to simplify previous expander.
15371
15372 (define_expand "strmov"
15373 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15374 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15375 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15376 (clobber (reg:CC FLAGS_REG))])
15377 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15378 (clobber (reg:CC FLAGS_REG))])]
15379 ""
15380 {
15381 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15382
15383 /* If .md ever supports :P for Pmode, these can be directly
15384 in the pattern above. */
15385 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15386 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15387
15388 /* Can't use this if the user has appropriated esi or edi. */
15389 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15390 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15391 {
15392 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15393 operands[2], operands[3],
15394 operands[5], operands[6]));
15395 DONE;
15396 }
15397
15398 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15399 })
15400
15401 (define_expand "strmov_singleop"
15402 [(parallel [(set (match_operand 1 "memory_operand" "")
15403 (match_operand 3 "memory_operand" ""))
15404 (set (match_operand 0 "register_operand" "")
15405 (match_operand 4 "" ""))
15406 (set (match_operand 2 "register_operand" "")
15407 (match_operand 5 "" ""))])]
15408 ""
15409 "ix86_current_function_needs_cld = 1;")
15410
15411 (define_insn "*strmovdi_rex_1"
15412 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15413 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15414 (set (match_operand:DI 0 "register_operand" "=D")
15415 (plus:DI (match_dup 2)
15416 (const_int 8)))
15417 (set (match_operand:DI 1 "register_operand" "=S")
15418 (plus:DI (match_dup 3)
15419 (const_int 8)))]
15420 "TARGET_64BIT"
15421 "movsq"
15422 [(set_attr "type" "str")
15423 (set_attr "memory" "both")
15424 (set_attr "mode" "DI")])
15425
15426 (define_insn "*strmovsi_1"
15427 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15428 (mem:SI (match_operand:P 3 "register_operand" "1")))
15429 (set (match_operand:P 0 "register_operand" "=D")
15430 (plus:P (match_dup 2)
15431 (const_int 4)))
15432 (set (match_operand:P 1 "register_operand" "=S")
15433 (plus:P (match_dup 3)
15434 (const_int 4)))]
15435 ""
15436 "movs{l|d}"
15437 [(set_attr "type" "str")
15438 (set_attr "memory" "both")
15439 (set_attr "mode" "SI")])
15440
15441 (define_insn "*strmovhi_1"
15442 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15443 (mem:HI (match_operand:P 3 "register_operand" "1")))
15444 (set (match_operand:P 0 "register_operand" "=D")
15445 (plus:P (match_dup 2)
15446 (const_int 2)))
15447 (set (match_operand:P 1 "register_operand" "=S")
15448 (plus:P (match_dup 3)
15449 (const_int 2)))]
15450 ""
15451 "movsw"
15452 [(set_attr "type" "str")
15453 (set_attr "memory" "both")
15454 (set_attr "mode" "HI")])
15455
15456 (define_insn "*strmovqi_1"
15457 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15458 (mem:QI (match_operand:P 3 "register_operand" "1")))
15459 (set (match_operand:P 0 "register_operand" "=D")
15460 (plus:P (match_dup 2)
15461 (const_int 1)))
15462 (set (match_operand:P 1 "register_operand" "=S")
15463 (plus:P (match_dup 3)
15464 (const_int 1)))]
15465 ""
15466 "movsb"
15467 [(set_attr "type" "str")
15468 (set_attr "memory" "both")
15469 (set (attr "prefix_rex")
15470 (if_then_else
15471 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15472 (const_string "0")
15473 (const_string "*")))
15474 (set_attr "mode" "QI")])
15475
15476 (define_expand "rep_mov"
15477 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15478 (set (match_operand 0 "register_operand" "")
15479 (match_operand 5 "" ""))
15480 (set (match_operand 2 "register_operand" "")
15481 (match_operand 6 "" ""))
15482 (set (match_operand 1 "memory_operand" "")
15483 (match_operand 3 "memory_operand" ""))
15484 (use (match_dup 4))])]
15485 ""
15486 "ix86_current_function_needs_cld = 1;")
15487
15488 (define_insn "*rep_movdi_rex64"
15489 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15490 (set (match_operand:DI 0 "register_operand" "=D")
15491 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15492 (const_int 3))
15493 (match_operand:DI 3 "register_operand" "0")))
15494 (set (match_operand:DI 1 "register_operand" "=S")
15495 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15496 (match_operand:DI 4 "register_operand" "1")))
15497 (set (mem:BLK (match_dup 3))
15498 (mem:BLK (match_dup 4)))
15499 (use (match_dup 5))]
15500 "TARGET_64BIT"
15501 "rep{%;} movsq"
15502 [(set_attr "type" "str")
15503 (set_attr "prefix_rep" "1")
15504 (set_attr "memory" "both")
15505 (set_attr "mode" "DI")])
15506
15507 (define_insn "*rep_movsi"
15508 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15509 (set (match_operand:P 0 "register_operand" "=D")
15510 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15511 (const_int 2))
15512 (match_operand:P 3 "register_operand" "0")))
15513 (set (match_operand:P 1 "register_operand" "=S")
15514 (plus:P (ashift:P (match_dup 5) (const_int 2))
15515 (match_operand:P 4 "register_operand" "1")))
15516 (set (mem:BLK (match_dup 3))
15517 (mem:BLK (match_dup 4)))
15518 (use (match_dup 5))]
15519 ""
15520 "rep{%;} movs{l|d}"
15521 [(set_attr "type" "str")
15522 (set_attr "prefix_rep" "1")
15523 (set_attr "memory" "both")
15524 (set_attr "mode" "SI")])
15525
15526 (define_insn "*rep_movqi"
15527 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15528 (set (match_operand:P 0 "register_operand" "=D")
15529 (plus:P (match_operand:P 3 "register_operand" "0")
15530 (match_operand:P 5 "register_operand" "2")))
15531 (set (match_operand:P 1 "register_operand" "=S")
15532 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15533 (set (mem:BLK (match_dup 3))
15534 (mem:BLK (match_dup 4)))
15535 (use (match_dup 5))]
15536 ""
15537 "rep{%;} movsb"
15538 [(set_attr "type" "str")
15539 (set_attr "prefix_rep" "1")
15540 (set_attr "memory" "both")
15541 (set_attr "mode" "QI")])
15542
15543 (define_expand "setmem<mode>"
15544 [(use (match_operand:BLK 0 "memory_operand" ""))
15545 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15546 (use (match_operand:QI 2 "nonmemory_operand" ""))
15547 (use (match_operand 3 "const_int_operand" ""))
15548 (use (match_operand:SI 4 "const_int_operand" ""))
15549 (use (match_operand:SI 5 "const_int_operand" ""))]
15550 ""
15551 {
15552 if (ix86_expand_setmem (operands[0], operands[1],
15553 operands[2], operands[3],
15554 operands[4], operands[5]))
15555 DONE;
15556 else
15557 FAIL;
15558 })
15559
15560 ;; Most CPUs don't like single string operations
15561 ;; Handle this case here to simplify previous expander.
15562
15563 (define_expand "strset"
15564 [(set (match_operand 1 "memory_operand" "")
15565 (match_operand 2 "register_operand" ""))
15566 (parallel [(set (match_operand 0 "register_operand" "")
15567 (match_dup 3))
15568 (clobber (reg:CC FLAGS_REG))])]
15569 ""
15570 {
15571 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15572 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15573
15574 /* If .md ever supports :P for Pmode, this can be directly
15575 in the pattern above. */
15576 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15577 GEN_INT (GET_MODE_SIZE (GET_MODE
15578 (operands[2]))));
15579 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15580 {
15581 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15582 operands[3]));
15583 DONE;
15584 }
15585 })
15586
15587 (define_expand "strset_singleop"
15588 [(parallel [(set (match_operand 1 "memory_operand" "")
15589 (match_operand 2 "register_operand" ""))
15590 (set (match_operand 0 "register_operand" "")
15591 (match_operand 3 "" ""))])]
15592 ""
15593 "ix86_current_function_needs_cld = 1;")
15594
15595 (define_insn "*strsetdi_rex_1"
15596 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15597 (match_operand:DI 2 "register_operand" "a"))
15598 (set (match_operand:DI 0 "register_operand" "=D")
15599 (plus:DI (match_dup 1)
15600 (const_int 8)))]
15601 "TARGET_64BIT"
15602 "stosq"
15603 [(set_attr "type" "str")
15604 (set_attr "memory" "store")
15605 (set_attr "mode" "DI")])
15606
15607 (define_insn "*strsetsi_1"
15608 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15609 (match_operand:SI 2 "register_operand" "a"))
15610 (set (match_operand:P 0 "register_operand" "=D")
15611 (plus:P (match_dup 1)
15612 (const_int 4)))]
15613 ""
15614 "stos{l|d}"
15615 [(set_attr "type" "str")
15616 (set_attr "memory" "store")
15617 (set_attr "mode" "SI")])
15618
15619 (define_insn "*strsethi_1"
15620 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15621 (match_operand:HI 2 "register_operand" "a"))
15622 (set (match_operand:P 0 "register_operand" "=D")
15623 (plus:P (match_dup 1)
15624 (const_int 2)))]
15625 ""
15626 "stosw"
15627 [(set_attr "type" "str")
15628 (set_attr "memory" "store")
15629 (set_attr "mode" "HI")])
15630
15631 (define_insn "*strsetqi_1"
15632 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15633 (match_operand:QI 2 "register_operand" "a"))
15634 (set (match_operand:P 0 "register_operand" "=D")
15635 (plus:P (match_dup 1)
15636 (const_int 1)))]
15637 ""
15638 "stosb"
15639 [(set_attr "type" "str")
15640 (set_attr "memory" "store")
15641 (set (attr "prefix_rex")
15642 (if_then_else
15643 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15644 (const_string "0")
15645 (const_string "*")))
15646 (set_attr "mode" "QI")])
15647
15648 (define_expand "rep_stos"
15649 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15650 (set (match_operand 0 "register_operand" "")
15651 (match_operand 4 "" ""))
15652 (set (match_operand 2 "memory_operand" "") (const_int 0))
15653 (use (match_operand 3 "register_operand" ""))
15654 (use (match_dup 1))])]
15655 ""
15656 "ix86_current_function_needs_cld = 1;")
15657
15658 (define_insn "*rep_stosdi_rex64"
15659 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15660 (set (match_operand:DI 0 "register_operand" "=D")
15661 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15662 (const_int 3))
15663 (match_operand:DI 3 "register_operand" "0")))
15664 (set (mem:BLK (match_dup 3))
15665 (const_int 0))
15666 (use (match_operand:DI 2 "register_operand" "a"))
15667 (use (match_dup 4))]
15668 "TARGET_64BIT"
15669 "rep{%;} stosq"
15670 [(set_attr "type" "str")
15671 (set_attr "prefix_rep" "1")
15672 (set_attr "memory" "store")
15673 (set_attr "mode" "DI")])
15674
15675 (define_insn "*rep_stossi"
15676 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15677 (set (match_operand:P 0 "register_operand" "=D")
15678 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15679 (const_int 2))
15680 (match_operand:P 3 "register_operand" "0")))
15681 (set (mem:BLK (match_dup 3))
15682 (const_int 0))
15683 (use (match_operand:SI 2 "register_operand" "a"))
15684 (use (match_dup 4))]
15685 ""
15686 "rep{%;} stos{l|d}"
15687 [(set_attr "type" "str")
15688 (set_attr "prefix_rep" "1")
15689 (set_attr "memory" "store")
15690 (set_attr "mode" "SI")])
15691
15692 (define_insn "*rep_stosqi"
15693 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15694 (set (match_operand:P 0 "register_operand" "=D")
15695 (plus:P (match_operand:P 3 "register_operand" "0")
15696 (match_operand:P 4 "register_operand" "1")))
15697 (set (mem:BLK (match_dup 3))
15698 (const_int 0))
15699 (use (match_operand:QI 2 "register_operand" "a"))
15700 (use (match_dup 4))]
15701 ""
15702 "rep{%;} stosb"
15703 [(set_attr "type" "str")
15704 (set_attr "prefix_rep" "1")
15705 (set_attr "memory" "store")
15706 (set (attr "prefix_rex")
15707 (if_then_else
15708 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15709 (const_string "0")
15710 (const_string "*")))
15711 (set_attr "mode" "QI")])
15712
15713 (define_expand "cmpstrnsi"
15714 [(set (match_operand:SI 0 "register_operand" "")
15715 (compare:SI (match_operand:BLK 1 "general_operand" "")
15716 (match_operand:BLK 2 "general_operand" "")))
15717 (use (match_operand 3 "general_operand" ""))
15718 (use (match_operand 4 "immediate_operand" ""))]
15719 ""
15720 {
15721 rtx addr1, addr2, out, outlow, count, countreg, align;
15722
15723 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15724 FAIL;
15725
15726 /* Can't use this if the user has appropriated esi or edi. */
15727 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15728 FAIL;
15729
15730 out = operands[0];
15731 if (!REG_P (out))
15732 out = gen_reg_rtx (SImode);
15733
15734 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15735 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15736 if (addr1 != XEXP (operands[1], 0))
15737 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15738 if (addr2 != XEXP (operands[2], 0))
15739 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15740
15741 count = operands[3];
15742 countreg = ix86_zero_extend_to_Pmode (count);
15743
15744 /* %%% Iff we are testing strict equality, we can use known alignment
15745 to good advantage. This may be possible with combine, particularly
15746 once cc0 is dead. */
15747 align = operands[4];
15748
15749 if (CONST_INT_P (count))
15750 {
15751 if (INTVAL (count) == 0)
15752 {
15753 emit_move_insn (operands[0], const0_rtx);
15754 DONE;
15755 }
15756 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15757 operands[1], operands[2]));
15758 }
15759 else
15760 {
15761 rtx (*gen_cmp) (rtx, rtx);
15762
15763 gen_cmp = (TARGET_64BIT
15764 ? gen_cmpdi_1 : gen_cmpsi_1);
15765
15766 emit_insn (gen_cmp (countreg, countreg));
15767 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15768 operands[1], operands[2]));
15769 }
15770
15771 outlow = gen_lowpart (QImode, out);
15772 emit_insn (gen_cmpintqi (outlow));
15773 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15774
15775 if (operands[0] != out)
15776 emit_move_insn (operands[0], out);
15777
15778 DONE;
15779 })
15780
15781 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15782
15783 (define_expand "cmpintqi"
15784 [(set (match_dup 1)
15785 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15786 (set (match_dup 2)
15787 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15788 (parallel [(set (match_operand:QI 0 "register_operand" "")
15789 (minus:QI (match_dup 1)
15790 (match_dup 2)))
15791 (clobber (reg:CC FLAGS_REG))])]
15792 ""
15793 {
15794 operands[1] = gen_reg_rtx (QImode);
15795 operands[2] = gen_reg_rtx (QImode);
15796 })
15797
15798 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15799 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15800
15801 (define_expand "cmpstrnqi_nz_1"
15802 [(parallel [(set (reg:CC FLAGS_REG)
15803 (compare:CC (match_operand 4 "memory_operand" "")
15804 (match_operand 5 "memory_operand" "")))
15805 (use (match_operand 2 "register_operand" ""))
15806 (use (match_operand:SI 3 "immediate_operand" ""))
15807 (clobber (match_operand 0 "register_operand" ""))
15808 (clobber (match_operand 1 "register_operand" ""))
15809 (clobber (match_dup 2))])]
15810 ""
15811 "ix86_current_function_needs_cld = 1;")
15812
15813 (define_insn "*cmpstrnqi_nz_1"
15814 [(set (reg:CC FLAGS_REG)
15815 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15816 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15817 (use (match_operand:P 6 "register_operand" "2"))
15818 (use (match_operand:SI 3 "immediate_operand" "i"))
15819 (clobber (match_operand:P 0 "register_operand" "=S"))
15820 (clobber (match_operand:P 1 "register_operand" "=D"))
15821 (clobber (match_operand:P 2 "register_operand" "=c"))]
15822 ""
15823 "repz{%;} cmpsb"
15824 [(set_attr "type" "str")
15825 (set_attr "mode" "QI")
15826 (set (attr "prefix_rex")
15827 (if_then_else
15828 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15829 (const_string "0")
15830 (const_string "*")))
15831 (set_attr "prefix_rep" "1")])
15832
15833 ;; The same, but the count is not known to not be zero.
15834
15835 (define_expand "cmpstrnqi_1"
15836 [(parallel [(set (reg:CC FLAGS_REG)
15837 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15838 (const_int 0))
15839 (compare:CC (match_operand 4 "memory_operand" "")
15840 (match_operand 5 "memory_operand" ""))
15841 (const_int 0)))
15842 (use (match_operand:SI 3 "immediate_operand" ""))
15843 (use (reg:CC FLAGS_REG))
15844 (clobber (match_operand 0 "register_operand" ""))
15845 (clobber (match_operand 1 "register_operand" ""))
15846 (clobber (match_dup 2))])]
15847 ""
15848 "ix86_current_function_needs_cld = 1;")
15849
15850 (define_insn "*cmpstrnqi_1"
15851 [(set (reg:CC FLAGS_REG)
15852 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15853 (const_int 0))
15854 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15855 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15856 (const_int 0)))
15857 (use (match_operand:SI 3 "immediate_operand" "i"))
15858 (use (reg:CC FLAGS_REG))
15859 (clobber (match_operand:P 0 "register_operand" "=S"))
15860 (clobber (match_operand:P 1 "register_operand" "=D"))
15861 (clobber (match_operand:P 2 "register_operand" "=c"))]
15862 ""
15863 "repz{%;} cmpsb"
15864 [(set_attr "type" "str")
15865 (set_attr "mode" "QI")
15866 (set (attr "prefix_rex")
15867 (if_then_else
15868 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15869 (const_string "0")
15870 (const_string "*")))
15871 (set_attr "prefix_rep" "1")])
15872
15873 (define_expand "strlen<mode>"
15874 [(set (match_operand:SWI48x 0 "register_operand" "")
15875 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15876 (match_operand:QI 2 "immediate_operand" "")
15877 (match_operand 3 "immediate_operand" "")]
15878 UNSPEC_SCAS))]
15879 ""
15880 {
15881 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15882 DONE;
15883 else
15884 FAIL;
15885 })
15886
15887 (define_expand "strlenqi_1"
15888 [(parallel [(set (match_operand 0 "register_operand" "")
15889 (match_operand 2 "" ""))
15890 (clobber (match_operand 1 "register_operand" ""))
15891 (clobber (reg:CC FLAGS_REG))])]
15892 ""
15893 "ix86_current_function_needs_cld = 1;")
15894
15895 (define_insn "*strlenqi_1"
15896 [(set (match_operand:P 0 "register_operand" "=&c")
15897 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15898 (match_operand:QI 2 "register_operand" "a")
15899 (match_operand:P 3 "immediate_operand" "i")
15900 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15901 (clobber (match_operand:P 1 "register_operand" "=D"))
15902 (clobber (reg:CC FLAGS_REG))]
15903 ""
15904 "repnz{%;} scasb"
15905 [(set_attr "type" "str")
15906 (set_attr "mode" "QI")
15907 (set (attr "prefix_rex")
15908 (if_then_else
15909 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15910 (const_string "0")
15911 (const_string "*")))
15912 (set_attr "prefix_rep" "1")])
15913
15914 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15915 ;; handled in combine, but it is not currently up to the task.
15916 ;; When used for their truth value, the cmpstrn* expanders generate
15917 ;; code like this:
15918 ;;
15919 ;; repz cmpsb
15920 ;; seta %al
15921 ;; setb %dl
15922 ;; cmpb %al, %dl
15923 ;; jcc label
15924 ;;
15925 ;; The intermediate three instructions are unnecessary.
15926
15927 ;; This one handles cmpstrn*_nz_1...
15928 (define_peephole2
15929 [(parallel[
15930 (set (reg:CC FLAGS_REG)
15931 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15932 (mem:BLK (match_operand 5 "register_operand" ""))))
15933 (use (match_operand 6 "register_operand" ""))
15934 (use (match_operand:SI 3 "immediate_operand" ""))
15935 (clobber (match_operand 0 "register_operand" ""))
15936 (clobber (match_operand 1 "register_operand" ""))
15937 (clobber (match_operand 2 "register_operand" ""))])
15938 (set (match_operand:QI 7 "register_operand" "")
15939 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15940 (set (match_operand:QI 8 "register_operand" "")
15941 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15942 (set (reg FLAGS_REG)
15943 (compare (match_dup 7) (match_dup 8)))
15944 ]
15945 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15946 [(parallel[
15947 (set (reg:CC FLAGS_REG)
15948 (compare:CC (mem:BLK (match_dup 4))
15949 (mem:BLK (match_dup 5))))
15950 (use (match_dup 6))
15951 (use (match_dup 3))
15952 (clobber (match_dup 0))
15953 (clobber (match_dup 1))
15954 (clobber (match_dup 2))])])
15955
15956 ;; ...and this one handles cmpstrn*_1.
15957 (define_peephole2
15958 [(parallel[
15959 (set (reg:CC FLAGS_REG)
15960 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15961 (const_int 0))
15962 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15963 (mem:BLK (match_operand 5 "register_operand" "")))
15964 (const_int 0)))
15965 (use (match_operand:SI 3 "immediate_operand" ""))
15966 (use (reg:CC FLAGS_REG))
15967 (clobber (match_operand 0 "register_operand" ""))
15968 (clobber (match_operand 1 "register_operand" ""))
15969 (clobber (match_operand 2 "register_operand" ""))])
15970 (set (match_operand:QI 7 "register_operand" "")
15971 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15972 (set (match_operand:QI 8 "register_operand" "")
15973 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15974 (set (reg FLAGS_REG)
15975 (compare (match_dup 7) (match_dup 8)))
15976 ]
15977 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15978 [(parallel[
15979 (set (reg:CC FLAGS_REG)
15980 (if_then_else:CC (ne (match_dup 6)
15981 (const_int 0))
15982 (compare:CC (mem:BLK (match_dup 4))
15983 (mem:BLK (match_dup 5)))
15984 (const_int 0)))
15985 (use (match_dup 3))
15986 (use (reg:CC FLAGS_REG))
15987 (clobber (match_dup 0))
15988 (clobber (match_dup 1))
15989 (clobber (match_dup 2))])])
15990 \f
15991 ;; Conditional move instructions.
15992
15993 (define_expand "mov<mode>cc"
15994 [(set (match_operand:SWIM 0 "register_operand" "")
15995 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15996 (match_operand:SWIM 2 "general_operand" "")
15997 (match_operand:SWIM 3 "general_operand" "")))]
15998 ""
15999 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16000
16001 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16002 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16003 ;; So just document what we're doing explicitly.
16004
16005 (define_expand "x86_mov<mode>cc_0_m1"
16006 [(parallel
16007 [(set (match_operand:SWI48 0 "register_operand" "")
16008 (if_then_else:SWI48
16009 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16010 [(match_operand 1 "flags_reg_operand" "")
16011 (const_int 0)])
16012 (const_int -1)
16013 (const_int 0)))
16014 (clobber (reg:CC FLAGS_REG))])])
16015
16016 (define_insn "*x86_mov<mode>cc_0_m1"
16017 [(set (match_operand:SWI48 0 "register_operand" "=r")
16018 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16019 [(reg FLAGS_REG) (const_int 0)])
16020 (const_int -1)
16021 (const_int 0)))
16022 (clobber (reg:CC FLAGS_REG))]
16023 ""
16024 "sbb{<imodesuffix>}\t%0, %0"
16025 ; Since we don't have the proper number of operands for an alu insn,
16026 ; fill in all the blanks.
16027 [(set_attr "type" "alu")
16028 (set_attr "use_carry" "1")
16029 (set_attr "pent_pair" "pu")
16030 (set_attr "memory" "none")
16031 (set_attr "imm_disp" "false")
16032 (set_attr "mode" "<MODE>")
16033 (set_attr "length_immediate" "0")])
16034
16035 (define_insn "*x86_mov<mode>cc_0_m1_se"
16036 [(set (match_operand:SWI48 0 "register_operand" "=r")
16037 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16038 [(reg FLAGS_REG) (const_int 0)])
16039 (const_int 1)
16040 (const_int 0)))
16041 (clobber (reg:CC FLAGS_REG))]
16042 ""
16043 "sbb{<imodesuffix>}\t%0, %0"
16044 [(set_attr "type" "alu")
16045 (set_attr "use_carry" "1")
16046 (set_attr "pent_pair" "pu")
16047 (set_attr "memory" "none")
16048 (set_attr "imm_disp" "false")
16049 (set_attr "mode" "<MODE>")
16050 (set_attr "length_immediate" "0")])
16051
16052 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16053 [(set (match_operand:SWI48 0 "register_operand" "=r")
16054 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16055 [(reg FLAGS_REG) (const_int 0)])))]
16056 ""
16057 "sbb{<imodesuffix>}\t%0, %0"
16058 [(set_attr "type" "alu")
16059 (set_attr "use_carry" "1")
16060 (set_attr "pent_pair" "pu")
16061 (set_attr "memory" "none")
16062 (set_attr "imm_disp" "false")
16063 (set_attr "mode" "<MODE>")
16064 (set_attr "length_immediate" "0")])
16065
16066 (define_insn "*mov<mode>cc_noc"
16067 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16068 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16069 [(reg FLAGS_REG) (const_int 0)])
16070 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16071 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16072 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16073 "@
16074 cmov%O2%C1\t{%2, %0|%0, %2}
16075 cmov%O2%c1\t{%3, %0|%0, %3}"
16076 [(set_attr "type" "icmov")
16077 (set_attr "mode" "<MODE>")])
16078
16079 (define_insn_and_split "*movqicc_noc"
16080 [(set (match_operand:QI 0 "register_operand" "=r,r")
16081 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16082 [(match_operand 4 "flags_reg_operand" "")
16083 (const_int 0)])
16084 (match_operand:QI 2 "register_operand" "r,0")
16085 (match_operand:QI 3 "register_operand" "0,r")))]
16086 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16087 "#"
16088 "&& reload_completed"
16089 [(set (match_dup 0)
16090 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16091 (match_dup 2)
16092 (match_dup 3)))]
16093 "operands[0] = gen_lowpart (SImode, operands[0]);
16094 operands[2] = gen_lowpart (SImode, operands[2]);
16095 operands[3] = gen_lowpart (SImode, operands[3]);"
16096 [(set_attr "type" "icmov")
16097 (set_attr "mode" "SI")])
16098
16099 (define_expand "mov<mode>cc"
16100 [(set (match_operand:X87MODEF 0 "register_operand" "")
16101 (if_then_else:X87MODEF
16102 (match_operand 1 "ix86_fp_comparison_operator" "")
16103 (match_operand:X87MODEF 2 "register_operand" "")
16104 (match_operand:X87MODEF 3 "register_operand" "")))]
16105 "(TARGET_80387 && TARGET_CMOVE)
16106 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16107 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16108
16109 (define_insn "*movxfcc_1"
16110 [(set (match_operand:XF 0 "register_operand" "=f,f")
16111 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16112 [(reg FLAGS_REG) (const_int 0)])
16113 (match_operand:XF 2 "register_operand" "f,0")
16114 (match_operand:XF 3 "register_operand" "0,f")))]
16115 "TARGET_80387 && TARGET_CMOVE"
16116 "@
16117 fcmov%F1\t{%2, %0|%0, %2}
16118 fcmov%f1\t{%3, %0|%0, %3}"
16119 [(set_attr "type" "fcmov")
16120 (set_attr "mode" "XF")])
16121
16122 (define_insn "*movdfcc_1_rex64"
16123 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16124 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16125 [(reg FLAGS_REG) (const_int 0)])
16126 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16127 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16128 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16129 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16130 "@
16131 fcmov%F1\t{%2, %0|%0, %2}
16132 fcmov%f1\t{%3, %0|%0, %3}
16133 cmov%O2%C1\t{%2, %0|%0, %2}
16134 cmov%O2%c1\t{%3, %0|%0, %3}"
16135 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16136 (set_attr "mode" "DF,DF,DI,DI")])
16137
16138 (define_insn "*movdfcc_1"
16139 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16140 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16141 [(reg FLAGS_REG) (const_int 0)])
16142 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16143 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16144 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16145 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16146 "@
16147 fcmov%F1\t{%2, %0|%0, %2}
16148 fcmov%f1\t{%3, %0|%0, %3}
16149 #
16150 #"
16151 [(set_attr "type" "fcmov,fcmov,multi,multi")
16152 (set_attr "mode" "DF,DF,DI,DI")])
16153
16154 (define_split
16155 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16156 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16157 [(match_operand 4 "flags_reg_operand" "")
16158 (const_int 0)])
16159 (match_operand:DF 2 "nonimmediate_operand" "")
16160 (match_operand:DF 3 "nonimmediate_operand" "")))]
16161 "!TARGET_64BIT && reload_completed"
16162 [(set (match_dup 2)
16163 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16164 (match_dup 5)
16165 (match_dup 6)))
16166 (set (match_dup 3)
16167 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16168 (match_dup 7)
16169 (match_dup 8)))]
16170 {
16171 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16172 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16173 })
16174
16175 (define_insn "*movsfcc_1_387"
16176 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16177 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16178 [(reg FLAGS_REG) (const_int 0)])
16179 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16180 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16181 "TARGET_80387 && TARGET_CMOVE
16182 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16183 "@
16184 fcmov%F1\t{%2, %0|%0, %2}
16185 fcmov%f1\t{%3, %0|%0, %3}
16186 cmov%O2%C1\t{%2, %0|%0, %2}
16187 cmov%O2%c1\t{%3, %0|%0, %3}"
16188 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16189 (set_attr "mode" "SF,SF,SI,SI")])
16190
16191 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16192 ;; the scalar versions to have only XMM registers as operands.
16193
16194 ;; XOP conditional move
16195 (define_insn "*xop_pcmov_<mode>"
16196 [(set (match_operand:MODEF 0 "register_operand" "=x")
16197 (if_then_else:MODEF
16198 (match_operand:MODEF 1 "register_operand" "x")
16199 (match_operand:MODEF 2 "register_operand" "x")
16200 (match_operand:MODEF 3 "register_operand" "x")))]
16201 "TARGET_XOP"
16202 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16203 [(set_attr "type" "sse4arg")])
16204
16205 ;; These versions of the min/max patterns are intentionally ignorant of
16206 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16207 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16208 ;; are undefined in this condition, we're certain this is correct.
16209
16210 (define_insn "<code><mode>3"
16211 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16212 (smaxmin:MODEF
16213 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16214 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16215 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16216 "@
16217 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16218 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16219 [(set_attr "isa" "noavx,avx")
16220 (set_attr "prefix" "orig,vex")
16221 (set_attr "type" "sseadd")
16222 (set_attr "mode" "<MODE>")])
16223
16224 ;; These versions of the min/max patterns implement exactly the operations
16225 ;; min = (op1 < op2 ? op1 : op2)
16226 ;; max = (!(op1 < op2) ? op1 : op2)
16227 ;; Their operands are not commutative, and thus they may be used in the
16228 ;; presence of -0.0 and NaN.
16229
16230 (define_insn "*ieee_smin<mode>3"
16231 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16232 (unspec:MODEF
16233 [(match_operand:MODEF 1 "register_operand" "0,x")
16234 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16235 UNSPEC_IEEE_MIN))]
16236 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16237 "@
16238 min<ssemodesuffix>\t{%2, %0|%0, %2}
16239 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16240 [(set_attr "isa" "noavx,avx")
16241 (set_attr "prefix" "orig,vex")
16242 (set_attr "type" "sseadd")
16243 (set_attr "mode" "<MODE>")])
16244
16245 (define_insn "*ieee_smax<mode>3"
16246 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16247 (unspec:MODEF
16248 [(match_operand:MODEF 1 "register_operand" "0,x")
16249 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16250 UNSPEC_IEEE_MAX))]
16251 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16252 "@
16253 max<ssemodesuffix>\t{%2, %0|%0, %2}
16254 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16255 [(set_attr "isa" "noavx,avx")
16256 (set_attr "prefix" "orig,vex")
16257 (set_attr "type" "sseadd")
16258 (set_attr "mode" "<MODE>")])
16259
16260 ;; Make two stack loads independent:
16261 ;; fld aa fld aa
16262 ;; fld %st(0) -> fld bb
16263 ;; fmul bb fmul %st(1), %st
16264 ;;
16265 ;; Actually we only match the last two instructions for simplicity.
16266 (define_peephole2
16267 [(set (match_operand 0 "fp_register_operand" "")
16268 (match_operand 1 "fp_register_operand" ""))
16269 (set (match_dup 0)
16270 (match_operator 2 "binary_fp_operator"
16271 [(match_dup 0)
16272 (match_operand 3 "memory_operand" "")]))]
16273 "REGNO (operands[0]) != REGNO (operands[1])"
16274 [(set (match_dup 0) (match_dup 3))
16275 (set (match_dup 0) (match_dup 4))]
16276
16277 ;; The % modifier is not operational anymore in peephole2's, so we have to
16278 ;; swap the operands manually in the case of addition and multiplication.
16279 "if (COMMUTATIVE_ARITH_P (operands[2]))
16280 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16281 GET_MODE (operands[2]),
16282 operands[0], operands[1]);
16283 else
16284 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16285 GET_MODE (operands[2]),
16286 operands[1], operands[0]);")
16287
16288 ;; Conditional addition patterns
16289 (define_expand "add<mode>cc"
16290 [(match_operand:SWI 0 "register_operand" "")
16291 (match_operand 1 "ordered_comparison_operator" "")
16292 (match_operand:SWI 2 "register_operand" "")
16293 (match_operand:SWI 3 "const_int_operand" "")]
16294 ""
16295 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16296 \f
16297 ;; Misc patterns (?)
16298
16299 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16300 ;; Otherwise there will be nothing to keep
16301 ;;
16302 ;; [(set (reg ebp) (reg esp))]
16303 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16304 ;; (clobber (eflags)]
16305 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16306 ;;
16307 ;; in proper program order.
16308
16309 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16310 [(set (match_operand:P 0 "register_operand" "=r,r")
16311 (plus:P (match_operand:P 1 "register_operand" "0,r")
16312 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16313 (clobber (reg:CC FLAGS_REG))
16314 (clobber (mem:BLK (scratch)))]
16315 ""
16316 {
16317 switch (get_attr_type (insn))
16318 {
16319 case TYPE_IMOV:
16320 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16321
16322 case TYPE_ALU:
16323 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16324 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16325 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16326
16327 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16328
16329 default:
16330 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16331 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16332 }
16333 }
16334 [(set (attr "type")
16335 (cond [(and (eq_attr "alternative" "0")
16336 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16337 (const_string "alu")
16338 (match_operand:<MODE> 2 "const0_operand" "")
16339 (const_string "imov")
16340 ]
16341 (const_string "lea")))
16342 (set (attr "length_immediate")
16343 (cond [(eq_attr "type" "imov")
16344 (const_string "0")
16345 (and (eq_attr "type" "alu")
16346 (match_operand 2 "const128_operand" ""))
16347 (const_string "1")
16348 ]
16349 (const_string "*")))
16350 (set_attr "mode" "<MODE>")])
16351
16352 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16353 [(set (match_operand:P 0 "register_operand" "=r")
16354 (minus:P (match_operand:P 1 "register_operand" "0")
16355 (match_operand:P 2 "register_operand" "r")))
16356 (clobber (reg:CC FLAGS_REG))
16357 (clobber (mem:BLK (scratch)))]
16358 ""
16359 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16360 [(set_attr "type" "alu")
16361 (set_attr "mode" "<MODE>")])
16362
16363 (define_insn "allocate_stack_worker_probe_<mode>"
16364 [(set (match_operand:P 0 "register_operand" "=a")
16365 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16366 UNSPECV_STACK_PROBE))
16367 (clobber (reg:CC FLAGS_REG))]
16368 "ix86_target_stack_probe ()"
16369 "call\t___chkstk_ms"
16370 [(set_attr "type" "multi")
16371 (set_attr "length" "5")])
16372
16373 (define_expand "allocate_stack"
16374 [(match_operand 0 "register_operand" "")
16375 (match_operand 1 "general_operand" "")]
16376 "ix86_target_stack_probe ()"
16377 {
16378 rtx x;
16379
16380 #ifndef CHECK_STACK_LIMIT
16381 #define CHECK_STACK_LIMIT 0
16382 #endif
16383
16384 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16385 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16386 {
16387 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16388 stack_pointer_rtx, 0, OPTAB_DIRECT);
16389 if (x != stack_pointer_rtx)
16390 emit_move_insn (stack_pointer_rtx, x);
16391 }
16392 else
16393 {
16394 x = copy_to_mode_reg (Pmode, operands[1]);
16395 if (TARGET_64BIT)
16396 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16397 else
16398 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16399 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16400 stack_pointer_rtx, 0, OPTAB_DIRECT);
16401 if (x != stack_pointer_rtx)
16402 emit_move_insn (stack_pointer_rtx, x);
16403 }
16404
16405 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16406 DONE;
16407 })
16408
16409 ;; Use IOR for stack probes, this is shorter.
16410 (define_expand "probe_stack"
16411 [(match_operand 0 "memory_operand" "")]
16412 ""
16413 {
16414 rtx (*gen_ior3) (rtx, rtx, rtx);
16415
16416 gen_ior3 = (GET_MODE (operands[0]) == DImode
16417 ? gen_iordi3 : gen_iorsi3);
16418
16419 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16420 DONE;
16421 })
16422
16423 (define_insn "adjust_stack_and_probe<mode>"
16424 [(set (match_operand:P 0 "register_operand" "=r")
16425 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16426 UNSPECV_PROBE_STACK_RANGE))
16427 (set (reg:P SP_REG)
16428 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16429 (clobber (reg:CC FLAGS_REG))
16430 (clobber (mem:BLK (scratch)))]
16431 ""
16432 "* return output_adjust_stack_and_probe (operands[0]);"
16433 [(set_attr "type" "multi")])
16434
16435 (define_insn "probe_stack_range<mode>"
16436 [(set (match_operand:P 0 "register_operand" "=r")
16437 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16438 (match_operand:P 2 "const_int_operand" "n")]
16439 UNSPECV_PROBE_STACK_RANGE))
16440 (clobber (reg:CC FLAGS_REG))]
16441 ""
16442 "* return output_probe_stack_range (operands[0], operands[2]);"
16443 [(set_attr "type" "multi")])
16444
16445 (define_expand "builtin_setjmp_receiver"
16446 [(label_ref (match_operand 0 "" ""))]
16447 "!TARGET_64BIT && flag_pic"
16448 {
16449 #if TARGET_MACHO
16450 if (TARGET_MACHO)
16451 {
16452 rtx xops[3];
16453 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16454 rtx label_rtx = gen_label_rtx ();
16455 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16456 xops[0] = xops[1] = picreg;
16457 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16458 ix86_expand_binary_operator (MINUS, SImode, xops);
16459 }
16460 else
16461 #endif
16462 emit_insn (gen_set_got (pic_offset_table_rtx));
16463 DONE;
16464 })
16465 \f
16466 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16467
16468 (define_split
16469 [(set (match_operand 0 "register_operand" "")
16470 (match_operator 3 "promotable_binary_operator"
16471 [(match_operand 1 "register_operand" "")
16472 (match_operand 2 "aligned_operand" "")]))
16473 (clobber (reg:CC FLAGS_REG))]
16474 "! TARGET_PARTIAL_REG_STALL && reload_completed
16475 && ((GET_MODE (operands[0]) == HImode
16476 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16477 /* ??? next two lines just !satisfies_constraint_K (...) */
16478 || !CONST_INT_P (operands[2])
16479 || satisfies_constraint_K (operands[2])))
16480 || (GET_MODE (operands[0]) == QImode
16481 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16482 [(parallel [(set (match_dup 0)
16483 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16484 (clobber (reg:CC FLAGS_REG))])]
16485 "operands[0] = gen_lowpart (SImode, operands[0]);
16486 operands[1] = gen_lowpart (SImode, operands[1]);
16487 if (GET_CODE (operands[3]) != ASHIFT)
16488 operands[2] = gen_lowpart (SImode, operands[2]);
16489 PUT_MODE (operands[3], SImode);")
16490
16491 ; Promote the QImode tests, as i386 has encoding of the AND
16492 ; instruction with 32-bit sign-extended immediate and thus the
16493 ; instruction size is unchanged, except in the %eax case for
16494 ; which it is increased by one byte, hence the ! optimize_size.
16495 (define_split
16496 [(set (match_operand 0 "flags_reg_operand" "")
16497 (match_operator 2 "compare_operator"
16498 [(and (match_operand 3 "aligned_operand" "")
16499 (match_operand 4 "const_int_operand" ""))
16500 (const_int 0)]))
16501 (set (match_operand 1 "register_operand" "")
16502 (and (match_dup 3) (match_dup 4)))]
16503 "! TARGET_PARTIAL_REG_STALL && reload_completed
16504 && optimize_insn_for_speed_p ()
16505 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16506 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16507 /* Ensure that the operand will remain sign-extended immediate. */
16508 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16509 [(parallel [(set (match_dup 0)
16510 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16511 (const_int 0)]))
16512 (set (match_dup 1)
16513 (and:SI (match_dup 3) (match_dup 4)))])]
16514 {
16515 operands[4]
16516 = gen_int_mode (INTVAL (operands[4])
16517 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16518 operands[1] = gen_lowpart (SImode, operands[1]);
16519 operands[3] = gen_lowpart (SImode, operands[3]);
16520 })
16521
16522 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16523 ; the TEST instruction with 32-bit sign-extended immediate and thus
16524 ; the instruction size would at least double, which is not what we
16525 ; want even with ! optimize_size.
16526 (define_split
16527 [(set (match_operand 0 "flags_reg_operand" "")
16528 (match_operator 1 "compare_operator"
16529 [(and (match_operand:HI 2 "aligned_operand" "")
16530 (match_operand:HI 3 "const_int_operand" ""))
16531 (const_int 0)]))]
16532 "! TARGET_PARTIAL_REG_STALL && reload_completed
16533 && ! TARGET_FAST_PREFIX
16534 && optimize_insn_for_speed_p ()
16535 /* Ensure that the operand will remain sign-extended immediate. */
16536 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16537 [(set (match_dup 0)
16538 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16539 (const_int 0)]))]
16540 {
16541 operands[3]
16542 = gen_int_mode (INTVAL (operands[3])
16543 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16544 operands[2] = gen_lowpart (SImode, operands[2]);
16545 })
16546
16547 (define_split
16548 [(set (match_operand 0 "register_operand" "")
16549 (neg (match_operand 1 "register_operand" "")))
16550 (clobber (reg:CC FLAGS_REG))]
16551 "! TARGET_PARTIAL_REG_STALL && reload_completed
16552 && (GET_MODE (operands[0]) == HImode
16553 || (GET_MODE (operands[0]) == QImode
16554 && (TARGET_PROMOTE_QImode
16555 || optimize_insn_for_size_p ())))"
16556 [(parallel [(set (match_dup 0)
16557 (neg:SI (match_dup 1)))
16558 (clobber (reg:CC FLAGS_REG))])]
16559 "operands[0] = gen_lowpart (SImode, operands[0]);
16560 operands[1] = gen_lowpart (SImode, operands[1]);")
16561
16562 (define_split
16563 [(set (match_operand 0 "register_operand" "")
16564 (not (match_operand 1 "register_operand" "")))]
16565 "! TARGET_PARTIAL_REG_STALL && reload_completed
16566 && (GET_MODE (operands[0]) == HImode
16567 || (GET_MODE (operands[0]) == QImode
16568 && (TARGET_PROMOTE_QImode
16569 || optimize_insn_for_size_p ())))"
16570 [(set (match_dup 0)
16571 (not:SI (match_dup 1)))]
16572 "operands[0] = gen_lowpart (SImode, operands[0]);
16573 operands[1] = gen_lowpart (SImode, operands[1]);")
16574
16575 (define_split
16576 [(set (match_operand 0 "register_operand" "")
16577 (if_then_else (match_operator 1 "ordered_comparison_operator"
16578 [(reg FLAGS_REG) (const_int 0)])
16579 (match_operand 2 "register_operand" "")
16580 (match_operand 3 "register_operand" "")))]
16581 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16582 && (GET_MODE (operands[0]) == HImode
16583 || (GET_MODE (operands[0]) == QImode
16584 && (TARGET_PROMOTE_QImode
16585 || optimize_insn_for_size_p ())))"
16586 [(set (match_dup 0)
16587 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16588 "operands[0] = gen_lowpart (SImode, operands[0]);
16589 operands[2] = gen_lowpart (SImode, operands[2]);
16590 operands[3] = gen_lowpart (SImode, operands[3]);")
16591 \f
16592 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16593 ;; transform a complex memory operation into two memory to register operations.
16594
16595 ;; Don't push memory operands
16596 (define_peephole2
16597 [(set (match_operand:SWI 0 "push_operand" "")
16598 (match_operand:SWI 1 "memory_operand" ""))
16599 (match_scratch:SWI 2 "<r>")]
16600 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16601 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16602 [(set (match_dup 2) (match_dup 1))
16603 (set (match_dup 0) (match_dup 2))])
16604
16605 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16606 ;; SImode pushes.
16607 (define_peephole2
16608 [(set (match_operand:SF 0 "push_operand" "")
16609 (match_operand:SF 1 "memory_operand" ""))
16610 (match_scratch:SF 2 "r")]
16611 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16612 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16613 [(set (match_dup 2) (match_dup 1))
16614 (set (match_dup 0) (match_dup 2))])
16615
16616 ;; Don't move an immediate directly to memory when the instruction
16617 ;; gets too big.
16618 (define_peephole2
16619 [(match_scratch:SWI124 1 "<r>")
16620 (set (match_operand:SWI124 0 "memory_operand" "")
16621 (const_int 0))]
16622 "optimize_insn_for_speed_p ()
16623 && !TARGET_USE_MOV0
16624 && TARGET_SPLIT_LONG_MOVES
16625 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16626 && peep2_regno_dead_p (0, FLAGS_REG)"
16627 [(parallel [(set (match_dup 2) (const_int 0))
16628 (clobber (reg:CC FLAGS_REG))])
16629 (set (match_dup 0) (match_dup 1))]
16630 "operands[2] = gen_lowpart (SImode, operands[1]);")
16631
16632 (define_peephole2
16633 [(match_scratch:SWI124 2 "<r>")
16634 (set (match_operand:SWI124 0 "memory_operand" "")
16635 (match_operand:SWI124 1 "immediate_operand" ""))]
16636 "optimize_insn_for_speed_p ()
16637 && TARGET_SPLIT_LONG_MOVES
16638 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16639 [(set (match_dup 2) (match_dup 1))
16640 (set (match_dup 0) (match_dup 2))])
16641
16642 ;; Don't compare memory with zero, load and use a test instead.
16643 (define_peephole2
16644 [(set (match_operand 0 "flags_reg_operand" "")
16645 (match_operator 1 "compare_operator"
16646 [(match_operand:SI 2 "memory_operand" "")
16647 (const_int 0)]))
16648 (match_scratch:SI 3 "r")]
16649 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16650 [(set (match_dup 3) (match_dup 2))
16651 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16652
16653 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16654 ;; Don't split NOTs with a displacement operand, because resulting XOR
16655 ;; will not be pairable anyway.
16656 ;;
16657 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16658 ;; represented using a modRM byte. The XOR replacement is long decoded,
16659 ;; so this split helps here as well.
16660 ;;
16661 ;; Note: Can't do this as a regular split because we can't get proper
16662 ;; lifetime information then.
16663
16664 (define_peephole2
16665 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16666 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16667 "optimize_insn_for_speed_p ()
16668 && ((TARGET_NOT_UNPAIRABLE
16669 && (!MEM_P (operands[0])
16670 || !memory_displacement_operand (operands[0], <MODE>mode)))
16671 || (TARGET_NOT_VECTORMODE
16672 && long_memory_operand (operands[0], <MODE>mode)))
16673 && peep2_regno_dead_p (0, FLAGS_REG)"
16674 [(parallel [(set (match_dup 0)
16675 (xor:SWI124 (match_dup 1) (const_int -1)))
16676 (clobber (reg:CC FLAGS_REG))])])
16677
16678 ;; Non pairable "test imm, reg" instructions can be translated to
16679 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16680 ;; byte opcode instead of two, have a short form for byte operands),
16681 ;; so do it for other CPUs as well. Given that the value was dead,
16682 ;; this should not create any new dependencies. Pass on the sub-word
16683 ;; versions if we're concerned about partial register stalls.
16684
16685 (define_peephole2
16686 [(set (match_operand 0 "flags_reg_operand" "")
16687 (match_operator 1 "compare_operator"
16688 [(and:SI (match_operand:SI 2 "register_operand" "")
16689 (match_operand:SI 3 "immediate_operand" ""))
16690 (const_int 0)]))]
16691 "ix86_match_ccmode (insn, CCNOmode)
16692 && (true_regnum (operands[2]) != AX_REG
16693 || satisfies_constraint_K (operands[3]))
16694 && peep2_reg_dead_p (1, operands[2])"
16695 [(parallel
16696 [(set (match_dup 0)
16697 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16698 (const_int 0)]))
16699 (set (match_dup 2)
16700 (and:SI (match_dup 2) (match_dup 3)))])])
16701
16702 ;; We don't need to handle HImode case, because it will be promoted to SImode
16703 ;; on ! TARGET_PARTIAL_REG_STALL
16704
16705 (define_peephole2
16706 [(set (match_operand 0 "flags_reg_operand" "")
16707 (match_operator 1 "compare_operator"
16708 [(and:QI (match_operand:QI 2 "register_operand" "")
16709 (match_operand:QI 3 "immediate_operand" ""))
16710 (const_int 0)]))]
16711 "! TARGET_PARTIAL_REG_STALL
16712 && ix86_match_ccmode (insn, CCNOmode)
16713 && true_regnum (operands[2]) != AX_REG
16714 && peep2_reg_dead_p (1, operands[2])"
16715 [(parallel
16716 [(set (match_dup 0)
16717 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16718 (const_int 0)]))
16719 (set (match_dup 2)
16720 (and:QI (match_dup 2) (match_dup 3)))])])
16721
16722 (define_peephole2
16723 [(set (match_operand 0 "flags_reg_operand" "")
16724 (match_operator 1 "compare_operator"
16725 [(and:SI
16726 (zero_extract:SI
16727 (match_operand 2 "ext_register_operand" "")
16728 (const_int 8)
16729 (const_int 8))
16730 (match_operand 3 "const_int_operand" ""))
16731 (const_int 0)]))]
16732 "! TARGET_PARTIAL_REG_STALL
16733 && ix86_match_ccmode (insn, CCNOmode)
16734 && true_regnum (operands[2]) != AX_REG
16735 && peep2_reg_dead_p (1, operands[2])"
16736 [(parallel [(set (match_dup 0)
16737 (match_op_dup 1
16738 [(and:SI
16739 (zero_extract:SI
16740 (match_dup 2)
16741 (const_int 8)
16742 (const_int 8))
16743 (match_dup 3))
16744 (const_int 0)]))
16745 (set (zero_extract:SI (match_dup 2)
16746 (const_int 8)
16747 (const_int 8))
16748 (and:SI
16749 (zero_extract:SI
16750 (match_dup 2)
16751 (const_int 8)
16752 (const_int 8))
16753 (match_dup 3)))])])
16754
16755 ;; Don't do logical operations with memory inputs.
16756 (define_peephole2
16757 [(match_scratch:SI 2 "r")
16758 (parallel [(set (match_operand:SI 0 "register_operand" "")
16759 (match_operator:SI 3 "arith_or_logical_operator"
16760 [(match_dup 0)
16761 (match_operand:SI 1 "memory_operand" "")]))
16762 (clobber (reg:CC FLAGS_REG))])]
16763 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16764 [(set (match_dup 2) (match_dup 1))
16765 (parallel [(set (match_dup 0)
16766 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16767 (clobber (reg:CC FLAGS_REG))])])
16768
16769 (define_peephole2
16770 [(match_scratch:SI 2 "r")
16771 (parallel [(set (match_operand:SI 0 "register_operand" "")
16772 (match_operator:SI 3 "arith_or_logical_operator"
16773 [(match_operand:SI 1 "memory_operand" "")
16774 (match_dup 0)]))
16775 (clobber (reg:CC FLAGS_REG))])]
16776 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16777 [(set (match_dup 2) (match_dup 1))
16778 (parallel [(set (match_dup 0)
16779 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16780 (clobber (reg:CC FLAGS_REG))])])
16781
16782 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16783 ;; refers to the destination of the load!
16784
16785 (define_peephole2
16786 [(set (match_operand:SI 0 "register_operand" "")
16787 (match_operand:SI 1 "register_operand" ""))
16788 (parallel [(set (match_dup 0)
16789 (match_operator:SI 3 "commutative_operator"
16790 [(match_dup 0)
16791 (match_operand:SI 2 "memory_operand" "")]))
16792 (clobber (reg:CC FLAGS_REG))])]
16793 "REGNO (operands[0]) != REGNO (operands[1])
16794 && GENERAL_REGNO_P (REGNO (operands[0]))
16795 && GENERAL_REGNO_P (REGNO (operands[1]))"
16796 [(set (match_dup 0) (match_dup 4))
16797 (parallel [(set (match_dup 0)
16798 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16799 (clobber (reg:CC FLAGS_REG))])]
16800 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16801
16802 (define_peephole2
16803 [(set (match_operand 0 "register_operand" "")
16804 (match_operand 1 "register_operand" ""))
16805 (set (match_dup 0)
16806 (match_operator 3 "commutative_operator"
16807 [(match_dup 0)
16808 (match_operand 2 "memory_operand" "")]))]
16809 "REGNO (operands[0]) != REGNO (operands[1])
16810 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16811 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16812 [(set (match_dup 0) (match_dup 2))
16813 (set (match_dup 0)
16814 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16815
16816 ; Don't do logical operations with memory outputs
16817 ;
16818 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16819 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16820 ; the same decoder scheduling characteristics as the original.
16821
16822 (define_peephole2
16823 [(match_scratch:SI 2 "r")
16824 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16825 (match_operator:SI 3 "arith_or_logical_operator"
16826 [(match_dup 0)
16827 (match_operand:SI 1 "nonmemory_operand" "")]))
16828 (clobber (reg:CC FLAGS_REG))])]
16829 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16830 /* Do not split stack checking probes. */
16831 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16832 [(set (match_dup 2) (match_dup 0))
16833 (parallel [(set (match_dup 2)
16834 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16835 (clobber (reg:CC FLAGS_REG))])
16836 (set (match_dup 0) (match_dup 2))])
16837
16838 (define_peephole2
16839 [(match_scratch:SI 2 "r")
16840 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16841 (match_operator:SI 3 "arith_or_logical_operator"
16842 [(match_operand:SI 1 "nonmemory_operand" "")
16843 (match_dup 0)]))
16844 (clobber (reg:CC FLAGS_REG))])]
16845 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16846 /* Do not split stack checking probes. */
16847 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16848 [(set (match_dup 2) (match_dup 0))
16849 (parallel [(set (match_dup 2)
16850 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16851 (clobber (reg:CC FLAGS_REG))])
16852 (set (match_dup 0) (match_dup 2))])
16853
16854 ;; Attempt to always use XOR for zeroing registers.
16855 (define_peephole2
16856 [(set (match_operand 0 "register_operand" "")
16857 (match_operand 1 "const0_operand" ""))]
16858 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16859 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16860 && GENERAL_REG_P (operands[0])
16861 && peep2_regno_dead_p (0, FLAGS_REG)"
16862 [(parallel [(set (match_dup 0) (const_int 0))
16863 (clobber (reg:CC FLAGS_REG))])]
16864 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16865
16866 (define_peephole2
16867 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16868 (const_int 0))]
16869 "(GET_MODE (operands[0]) == QImode
16870 || GET_MODE (operands[0]) == HImode)
16871 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16872 && peep2_regno_dead_p (0, FLAGS_REG)"
16873 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16874 (clobber (reg:CC FLAGS_REG))])])
16875
16876 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16877 (define_peephole2
16878 [(set (match_operand:SWI248 0 "register_operand" "")
16879 (const_int -1))]
16880 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16881 && peep2_regno_dead_p (0, FLAGS_REG)"
16882 [(parallel [(set (match_dup 0) (const_int -1))
16883 (clobber (reg:CC FLAGS_REG))])]
16884 {
16885 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16886 operands[0] = gen_lowpart (SImode, operands[0]);
16887 })
16888
16889 ;; Attempt to convert simple lea to add/shift.
16890 ;; These can be created by move expanders.
16891
16892 (define_peephole2
16893 [(set (match_operand:SWI48 0 "register_operand" "")
16894 (plus:SWI48 (match_dup 0)
16895 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16896 "peep2_regno_dead_p (0, FLAGS_REG)"
16897 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16898 (clobber (reg:CC FLAGS_REG))])])
16899
16900 (define_peephole2
16901 [(set (match_operand:SI 0 "register_operand" "")
16902 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16903 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16904 "TARGET_64BIT
16905 && peep2_regno_dead_p (0, FLAGS_REG)
16906 && REGNO (operands[0]) == REGNO (operands[1])"
16907 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16908 (clobber (reg:CC FLAGS_REG))])]
16909 "operands[2] = gen_lowpart (SImode, operands[2]);")
16910
16911 (define_peephole2
16912 [(set (match_operand:SWI48 0 "register_operand" "")
16913 (mult:SWI48 (match_dup 0)
16914 (match_operand:SWI48 1 "const_int_operand" "")))]
16915 "exact_log2 (INTVAL (operands[1])) >= 0
16916 && peep2_regno_dead_p (0, FLAGS_REG)"
16917 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16918 (clobber (reg:CC FLAGS_REG))])]
16919 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16920
16921 (define_peephole2
16922 [(set (match_operand:SI 0 "register_operand" "")
16923 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16924 (match_operand:DI 2 "const_int_operand" "")) 0))]
16925 "TARGET_64BIT
16926 && exact_log2 (INTVAL (operands[2])) >= 0
16927 && REGNO (operands[0]) == REGNO (operands[1])
16928 && peep2_regno_dead_p (0, FLAGS_REG)"
16929 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16930 (clobber (reg:CC FLAGS_REG))])]
16931 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16932
16933 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16934 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16935 ;; On many CPUs it is also faster, since special hardware to avoid esp
16936 ;; dependencies is present.
16937
16938 ;; While some of these conversions may be done using splitters, we use
16939 ;; peepholes in order to allow combine_stack_adjustments pass to see
16940 ;; nonobfuscated RTL.
16941
16942 ;; Convert prologue esp subtractions to push.
16943 ;; We need register to push. In order to keep verify_flow_info happy we have
16944 ;; two choices
16945 ;; - use scratch and clobber it in order to avoid dependencies
16946 ;; - use already live register
16947 ;; We can't use the second way right now, since there is no reliable way how to
16948 ;; verify that given register is live. First choice will also most likely in
16949 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16950 ;; call clobbered registers are dead. We may want to use base pointer as an
16951 ;; alternative when no register is available later.
16952
16953 (define_peephole2
16954 [(match_scratch:P 1 "r")
16955 (parallel [(set (reg:P SP_REG)
16956 (plus:P (reg:P SP_REG)
16957 (match_operand:P 0 "const_int_operand" "")))
16958 (clobber (reg:CC FLAGS_REG))
16959 (clobber (mem:BLK (scratch)))])]
16960 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16961 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16962 [(clobber (match_dup 1))
16963 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16964 (clobber (mem:BLK (scratch)))])])
16965
16966 (define_peephole2
16967 [(match_scratch:P 1 "r")
16968 (parallel [(set (reg:P SP_REG)
16969 (plus:P (reg:P SP_REG)
16970 (match_operand:P 0 "const_int_operand" "")))
16971 (clobber (reg:CC FLAGS_REG))
16972 (clobber (mem:BLK (scratch)))])]
16973 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16974 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16975 [(clobber (match_dup 1))
16976 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16977 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16978 (clobber (mem:BLK (scratch)))])])
16979
16980 ;; Convert esp subtractions to push.
16981 (define_peephole2
16982 [(match_scratch:P 1 "r")
16983 (parallel [(set (reg:P SP_REG)
16984 (plus:P (reg:P SP_REG)
16985 (match_operand:P 0 "const_int_operand" "")))
16986 (clobber (reg:CC FLAGS_REG))])]
16987 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16988 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16989 [(clobber (match_dup 1))
16990 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16991
16992 (define_peephole2
16993 [(match_scratch:P 1 "r")
16994 (parallel [(set (reg:P SP_REG)
16995 (plus:P (reg:P SP_REG)
16996 (match_operand:P 0 "const_int_operand" "")))
16997 (clobber (reg:CC FLAGS_REG))])]
16998 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16999 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17000 [(clobber (match_dup 1))
17001 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17002 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17003
17004 ;; Convert epilogue deallocator to pop.
17005 (define_peephole2
17006 [(match_scratch:P 1 "r")
17007 (parallel [(set (reg:P SP_REG)
17008 (plus:P (reg:P SP_REG)
17009 (match_operand:P 0 "const_int_operand" "")))
17010 (clobber (reg:CC FLAGS_REG))
17011 (clobber (mem:BLK (scratch)))])]
17012 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17013 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17014 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17015 (clobber (mem:BLK (scratch)))])])
17016
17017 ;; Two pops case is tricky, since pop causes dependency
17018 ;; on destination register. We use two registers if available.
17019 (define_peephole2
17020 [(match_scratch:P 1 "r")
17021 (match_scratch:P 2 "r")
17022 (parallel [(set (reg:P SP_REG)
17023 (plus:P (reg:P SP_REG)
17024 (match_operand:P 0 "const_int_operand" "")))
17025 (clobber (reg:CC FLAGS_REG))
17026 (clobber (mem:BLK (scratch)))])]
17027 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17028 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17029 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17030 (clobber (mem:BLK (scratch)))])
17031 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17032
17033 (define_peephole2
17034 [(match_scratch:P 1 "r")
17035 (parallel [(set (reg:P SP_REG)
17036 (plus:P (reg:P SP_REG)
17037 (match_operand:P 0 "const_int_operand" "")))
17038 (clobber (reg:CC FLAGS_REG))
17039 (clobber (mem:BLK (scratch)))])]
17040 "optimize_insn_for_size_p ()
17041 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17042 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17043 (clobber (mem:BLK (scratch)))])
17044 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17045
17046 ;; Convert esp additions to pop.
17047 (define_peephole2
17048 [(match_scratch:P 1 "r")
17049 (parallel [(set (reg:P SP_REG)
17050 (plus:P (reg:P SP_REG)
17051 (match_operand:P 0 "const_int_operand" "")))
17052 (clobber (reg:CC FLAGS_REG))])]
17053 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17054 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17055
17056 ;; Two pops case is tricky, since pop causes dependency
17057 ;; on destination register. We use two registers if available.
17058 (define_peephole2
17059 [(match_scratch:P 1 "r")
17060 (match_scratch:P 2 "r")
17061 (parallel [(set (reg:P SP_REG)
17062 (plus:P (reg:P SP_REG)
17063 (match_operand:P 0 "const_int_operand" "")))
17064 (clobber (reg:CC FLAGS_REG))])]
17065 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17066 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17067 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17068
17069 (define_peephole2
17070 [(match_scratch:P 1 "r")
17071 (parallel [(set (reg:P SP_REG)
17072 (plus:P (reg:P SP_REG)
17073 (match_operand:P 0 "const_int_operand" "")))
17074 (clobber (reg:CC FLAGS_REG))])]
17075 "optimize_insn_for_size_p ()
17076 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17077 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17078 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17079 \f
17080 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17081 ;; required and register dies. Similarly for 128 to -128.
17082 (define_peephole2
17083 [(set (match_operand 0 "flags_reg_operand" "")
17084 (match_operator 1 "compare_operator"
17085 [(match_operand 2 "register_operand" "")
17086 (match_operand 3 "const_int_operand" "")]))]
17087 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17088 && incdec_operand (operands[3], GET_MODE (operands[3])))
17089 || (!TARGET_FUSE_CMP_AND_BRANCH
17090 && INTVAL (operands[3]) == 128))
17091 && ix86_match_ccmode (insn, CCGCmode)
17092 && peep2_reg_dead_p (1, operands[2])"
17093 [(parallel [(set (match_dup 0)
17094 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17095 (clobber (match_dup 2))])])
17096 \f
17097 ;; Convert imul by three, five and nine into lea
17098 (define_peephole2
17099 [(parallel
17100 [(set (match_operand:SWI48 0 "register_operand" "")
17101 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17102 (match_operand:SWI48 2 "const_int_operand" "")))
17103 (clobber (reg:CC FLAGS_REG))])]
17104 "INTVAL (operands[2]) == 3
17105 || INTVAL (operands[2]) == 5
17106 || INTVAL (operands[2]) == 9"
17107 [(set (match_dup 0)
17108 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17109 (match_dup 1)))]
17110 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17111
17112 (define_peephole2
17113 [(parallel
17114 [(set (match_operand:SWI48 0 "register_operand" "")
17115 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17116 (match_operand:SWI48 2 "const_int_operand" "")))
17117 (clobber (reg:CC FLAGS_REG))])]
17118 "optimize_insn_for_speed_p ()
17119 && (INTVAL (operands[2]) == 3
17120 || INTVAL (operands[2]) == 5
17121 || INTVAL (operands[2]) == 9)"
17122 [(set (match_dup 0) (match_dup 1))
17123 (set (match_dup 0)
17124 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17125 (match_dup 0)))]
17126 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17127
17128 ;; imul $32bit_imm, mem, reg is vector decoded, while
17129 ;; imul $32bit_imm, reg, reg is direct decoded.
17130 (define_peephole2
17131 [(match_scratch:SWI48 3 "r")
17132 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17133 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17134 (match_operand:SWI48 2 "immediate_operand" "")))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17137 && !satisfies_constraint_K (operands[2])"
17138 [(set (match_dup 3) (match_dup 1))
17139 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17140 (clobber (reg:CC FLAGS_REG))])])
17141
17142 (define_peephole2
17143 [(match_scratch:SI 3 "r")
17144 (parallel [(set (match_operand:DI 0 "register_operand" "")
17145 (zero_extend:DI
17146 (mult:SI (match_operand:SI 1 "memory_operand" "")
17147 (match_operand:SI 2 "immediate_operand" ""))))
17148 (clobber (reg:CC FLAGS_REG))])]
17149 "TARGET_64BIT
17150 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17151 && !satisfies_constraint_K (operands[2])"
17152 [(set (match_dup 3) (match_dup 1))
17153 (parallel [(set (match_dup 0)
17154 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17155 (clobber (reg:CC FLAGS_REG))])])
17156
17157 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17158 ;; Convert it into imul reg, reg
17159 ;; It would be better to force assembler to encode instruction using long
17160 ;; immediate, but there is apparently no way to do so.
17161 (define_peephole2
17162 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17163 (mult:SWI248
17164 (match_operand:SWI248 1 "nonimmediate_operand" "")
17165 (match_operand:SWI248 2 "const_int_operand" "")))
17166 (clobber (reg:CC FLAGS_REG))])
17167 (match_scratch:SWI248 3 "r")]
17168 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17169 && satisfies_constraint_K (operands[2])"
17170 [(set (match_dup 3) (match_dup 2))
17171 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17172 (clobber (reg:CC FLAGS_REG))])]
17173 {
17174 if (!rtx_equal_p (operands[0], operands[1]))
17175 emit_move_insn (operands[0], operands[1]);
17176 })
17177
17178 ;; After splitting up read-modify operations, array accesses with memory
17179 ;; operands might end up in form:
17180 ;; sall $2, %eax
17181 ;; movl 4(%esp), %edx
17182 ;; addl %edx, %eax
17183 ;; instead of pre-splitting:
17184 ;; sall $2, %eax
17185 ;; addl 4(%esp), %eax
17186 ;; Turn it into:
17187 ;; movl 4(%esp), %edx
17188 ;; leal (%edx,%eax,4), %eax
17189
17190 (define_peephole2
17191 [(match_scratch:P 5 "r")
17192 (parallel [(set (match_operand 0 "register_operand" "")
17193 (ashift (match_operand 1 "register_operand" "")
17194 (match_operand 2 "const_int_operand" "")))
17195 (clobber (reg:CC FLAGS_REG))])
17196 (parallel [(set (match_operand 3 "register_operand" "")
17197 (plus (match_dup 0)
17198 (match_operand 4 "x86_64_general_operand" "")))
17199 (clobber (reg:CC FLAGS_REG))])]
17200 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17201 /* Validate MODE for lea. */
17202 && ((!TARGET_PARTIAL_REG_STALL
17203 && (GET_MODE (operands[0]) == QImode
17204 || GET_MODE (operands[0]) == HImode))
17205 || GET_MODE (operands[0]) == SImode
17206 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17207 && (rtx_equal_p (operands[0], operands[3])
17208 || peep2_reg_dead_p (2, operands[0]))
17209 /* We reorder load and the shift. */
17210 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17211 [(set (match_dup 5) (match_dup 4))
17212 (set (match_dup 0) (match_dup 1))]
17213 {
17214 enum machine_mode op1mode = GET_MODE (operands[1]);
17215 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17216 int scale = 1 << INTVAL (operands[2]);
17217 rtx index = gen_lowpart (Pmode, operands[1]);
17218 rtx base = gen_lowpart (Pmode, operands[5]);
17219 rtx dest = gen_lowpart (mode, operands[3]);
17220
17221 operands[1] = gen_rtx_PLUS (Pmode, base,
17222 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17223 operands[5] = base;
17224 if (mode != Pmode)
17225 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17226 if (op1mode != Pmode)
17227 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17228 operands[0] = dest;
17229 })
17230 \f
17231 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17232 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17233 ;; caught for use by garbage collectors and the like. Using an insn that
17234 ;; maps to SIGILL makes it more likely the program will rightfully die.
17235 ;; Keeping with tradition, "6" is in honor of #UD.
17236 (define_insn "trap"
17237 [(trap_if (const_int 1) (const_int 6))]
17238 ""
17239 { return ASM_SHORT "0x0b0f"; }
17240 [(set_attr "length" "2")])
17241
17242 (define_expand "prefetch"
17243 [(prefetch (match_operand 0 "address_operand" "")
17244 (match_operand:SI 1 "const_int_operand" "")
17245 (match_operand:SI 2 "const_int_operand" ""))]
17246 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17247 {
17248 int rw = INTVAL (operands[1]);
17249 int locality = INTVAL (operands[2]);
17250
17251 gcc_assert (rw == 0 || rw == 1);
17252 gcc_assert (locality >= 0 && locality <= 3);
17253 gcc_assert (GET_MODE (operands[0]) == Pmode
17254 || GET_MODE (operands[0]) == VOIDmode);
17255
17256 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17257 supported by SSE counterpart or the SSE prefetch is not available
17258 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17259 of locality. */
17260 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17261 operands[2] = GEN_INT (3);
17262 else
17263 operands[1] = const0_rtx;
17264 })
17265
17266 (define_insn "*prefetch_sse_<mode>"
17267 [(prefetch (match_operand:P 0 "address_operand" "p")
17268 (const_int 0)
17269 (match_operand:SI 1 "const_int_operand" ""))]
17270 "TARGET_PREFETCH_SSE"
17271 {
17272 static const char * const patterns[4] = {
17273 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17274 };
17275
17276 int locality = INTVAL (operands[1]);
17277 gcc_assert (locality >= 0 && locality <= 3);
17278
17279 return patterns[locality];
17280 }
17281 [(set_attr "type" "sse")
17282 (set_attr "atom_sse_attr" "prefetch")
17283 (set (attr "length_address")
17284 (symbol_ref "memory_address_length (operands[0])"))
17285 (set_attr "memory" "none")])
17286
17287 (define_insn "*prefetch_3dnow_<mode>"
17288 [(prefetch (match_operand:P 0 "address_operand" "p")
17289 (match_operand:SI 1 "const_int_operand" "n")
17290 (const_int 3))]
17291 "TARGET_3DNOW"
17292 {
17293 if (INTVAL (operands[1]) == 0)
17294 return "prefetch\t%a0";
17295 else
17296 return "prefetchw\t%a0";
17297 }
17298 [(set_attr "type" "mmx")
17299 (set (attr "length_address")
17300 (symbol_ref "memory_address_length (operands[0])"))
17301 (set_attr "memory" "none")])
17302
17303 (define_expand "stack_protect_set"
17304 [(match_operand 0 "memory_operand" "")
17305 (match_operand 1 "memory_operand" "")]
17306 ""
17307 {
17308 rtx (*insn)(rtx, rtx);
17309
17310 #ifdef TARGET_THREAD_SSP_OFFSET
17311 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17312 insn = (TARGET_64BIT
17313 ? gen_stack_tls_protect_set_di
17314 : gen_stack_tls_protect_set_si);
17315 #else
17316 insn = (TARGET_64BIT
17317 ? gen_stack_protect_set_di
17318 : gen_stack_protect_set_si);
17319 #endif
17320
17321 emit_insn (insn (operands[0], operands[1]));
17322 DONE;
17323 })
17324
17325 (define_insn "stack_protect_set_<mode>"
17326 [(set (match_operand:P 0 "memory_operand" "=m")
17327 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17328 (set (match_scratch:P 2 "=&r") (const_int 0))
17329 (clobber (reg:CC FLAGS_REG))]
17330 ""
17331 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17332 [(set_attr "type" "multi")])
17333
17334 (define_insn "stack_tls_protect_set_<mode>"
17335 [(set (match_operand:P 0 "memory_operand" "=m")
17336 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17337 UNSPEC_SP_TLS_SET))
17338 (set (match_scratch:P 2 "=&r") (const_int 0))
17339 (clobber (reg:CC FLAGS_REG))]
17340 ""
17341 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17342 [(set_attr "type" "multi")])
17343
17344 (define_expand "stack_protect_test"
17345 [(match_operand 0 "memory_operand" "")
17346 (match_operand 1 "memory_operand" "")
17347 (match_operand 2 "" "")]
17348 ""
17349 {
17350 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17351
17352 rtx (*insn)(rtx, rtx, rtx);
17353
17354 #ifdef TARGET_THREAD_SSP_OFFSET
17355 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17356 insn = (TARGET_64BIT
17357 ? gen_stack_tls_protect_test_di
17358 : gen_stack_tls_protect_test_si);
17359 #else
17360 insn = (TARGET_64BIT
17361 ? gen_stack_protect_test_di
17362 : gen_stack_protect_test_si);
17363 #endif
17364
17365 emit_insn (insn (flags, operands[0], operands[1]));
17366
17367 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17368 flags, const0_rtx, operands[2]));
17369 DONE;
17370 })
17371
17372 (define_insn "stack_protect_test_<mode>"
17373 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17374 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17375 (match_operand:P 2 "memory_operand" "m")]
17376 UNSPEC_SP_TEST))
17377 (clobber (match_scratch:P 3 "=&r"))]
17378 ""
17379 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17380 [(set_attr "type" "multi")])
17381
17382 (define_insn "stack_tls_protect_test_<mode>"
17383 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17384 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17385 (match_operand:P 2 "const_int_operand" "i")]
17386 UNSPEC_SP_TLS_TEST))
17387 (clobber (match_scratch:P 3 "=r"))]
17388 ""
17389 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17390 [(set_attr "type" "multi")])
17391
17392 (define_insn "sse4_2_crc32<mode>"
17393 [(set (match_operand:SI 0 "register_operand" "=r")
17394 (unspec:SI
17395 [(match_operand:SI 1 "register_operand" "0")
17396 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17397 UNSPEC_CRC32))]
17398 "TARGET_SSE4_2 || TARGET_CRC32"
17399 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17400 [(set_attr "type" "sselog1")
17401 (set_attr "prefix_rep" "1")
17402 (set_attr "prefix_extra" "1")
17403 (set (attr "prefix_data16")
17404 (if_then_else (match_operand:HI 2 "" "")
17405 (const_string "1")
17406 (const_string "*")))
17407 (set (attr "prefix_rex")
17408 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17409 (const_string "1")
17410 (const_string "*")))
17411 (set_attr "mode" "SI")])
17412
17413 (define_insn "sse4_2_crc32di"
17414 [(set (match_operand:DI 0 "register_operand" "=r")
17415 (unspec:DI
17416 [(match_operand:DI 1 "register_operand" "0")
17417 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17418 UNSPEC_CRC32))]
17419 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17420 "crc32{q}\t{%2, %0|%0, %2}"
17421 [(set_attr "type" "sselog1")
17422 (set_attr "prefix_rep" "1")
17423 (set_attr "prefix_extra" "1")
17424 (set_attr "mode" "DI")])
17425
17426 (define_expand "rdpmc"
17427 [(match_operand:DI 0 "register_operand" "")
17428 (match_operand:SI 1 "register_operand" "")]
17429 ""
17430 {
17431 rtx reg = gen_reg_rtx (DImode);
17432 rtx si;
17433
17434 /* Force operand 1 into ECX. */
17435 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17436 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17437 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17438 UNSPECV_RDPMC);
17439
17440 if (TARGET_64BIT)
17441 {
17442 rtvec vec = rtvec_alloc (2);
17443 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17444 rtx upper = gen_reg_rtx (DImode);
17445 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17446 gen_rtvec (1, const0_rtx),
17447 UNSPECV_RDPMC);
17448 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17449 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17450 emit_insn (load);
17451 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17452 NULL, 1, OPTAB_DIRECT);
17453 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17454 OPTAB_DIRECT);
17455 }
17456 else
17457 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17458 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17459 DONE;
17460 })
17461
17462 (define_insn "*rdpmc"
17463 [(set (match_operand:DI 0 "register_operand" "=A")
17464 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17465 UNSPECV_RDPMC))]
17466 "!TARGET_64BIT"
17467 "rdpmc"
17468 [(set_attr "type" "other")
17469 (set_attr "length" "2")])
17470
17471 (define_insn "*rdpmc_rex64"
17472 [(set (match_operand:DI 0 "register_operand" "=a")
17473 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17474 UNSPECV_RDPMC))
17475 (set (match_operand:DI 1 "register_operand" "=d")
17476 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17477 "TARGET_64BIT"
17478 "rdpmc"
17479 [(set_attr "type" "other")
17480 (set_attr "length" "2")])
17481
17482 (define_expand "rdtsc"
17483 [(set (match_operand:DI 0 "register_operand" "")
17484 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17485 ""
17486 {
17487 if (TARGET_64BIT)
17488 {
17489 rtvec vec = rtvec_alloc (2);
17490 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17491 rtx upper = gen_reg_rtx (DImode);
17492 rtx lower = gen_reg_rtx (DImode);
17493 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17494 gen_rtvec (1, const0_rtx),
17495 UNSPECV_RDTSC);
17496 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17497 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17498 emit_insn (load);
17499 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17500 NULL, 1, OPTAB_DIRECT);
17501 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17502 OPTAB_DIRECT);
17503 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17504 DONE;
17505 }
17506 })
17507
17508 (define_insn "*rdtsc"
17509 [(set (match_operand:DI 0 "register_operand" "=A")
17510 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17511 "!TARGET_64BIT"
17512 "rdtsc"
17513 [(set_attr "type" "other")
17514 (set_attr "length" "2")])
17515
17516 (define_insn "*rdtsc_rex64"
17517 [(set (match_operand:DI 0 "register_operand" "=a")
17518 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17519 (set (match_operand:DI 1 "register_operand" "=d")
17520 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17521 "TARGET_64BIT"
17522 "rdtsc"
17523 [(set_attr "type" "other")
17524 (set_attr "length" "2")])
17525
17526 (define_expand "rdtscp"
17527 [(match_operand:DI 0 "register_operand" "")
17528 (match_operand:SI 1 "memory_operand" "")]
17529 ""
17530 {
17531 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17532 gen_rtvec (1, const0_rtx),
17533 UNSPECV_RDTSCP);
17534 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17535 gen_rtvec (1, const0_rtx),
17536 UNSPECV_RDTSCP);
17537 rtx reg = gen_reg_rtx (DImode);
17538 rtx tmp = gen_reg_rtx (SImode);
17539
17540 if (TARGET_64BIT)
17541 {
17542 rtvec vec = rtvec_alloc (3);
17543 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17544 rtx upper = gen_reg_rtx (DImode);
17545 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17546 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17547 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17548 emit_insn (load);
17549 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17550 NULL, 1, OPTAB_DIRECT);
17551 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17552 OPTAB_DIRECT);
17553 }
17554 else
17555 {
17556 rtvec vec = rtvec_alloc (2);
17557 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17558 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17559 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17560 emit_insn (load);
17561 }
17562 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17563 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17564 DONE;
17565 })
17566
17567 (define_insn "*rdtscp"
17568 [(set (match_operand:DI 0 "register_operand" "=A")
17569 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17570 (set (match_operand:SI 1 "register_operand" "=c")
17571 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17572 "!TARGET_64BIT"
17573 "rdtscp"
17574 [(set_attr "type" "other")
17575 (set_attr "length" "3")])
17576
17577 (define_insn "*rdtscp_rex64"
17578 [(set (match_operand:DI 0 "register_operand" "=a")
17579 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17580 (set (match_operand:DI 1 "register_operand" "=d")
17581 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17582 (set (match_operand:SI 2 "register_operand" "=c")
17583 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17584 "TARGET_64BIT"
17585 "rdtscp"
17586 [(set_attr "type" "other")
17587 (set_attr "length" "3")])
17588
17589 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17590 ;;
17591 ;; LWP instructions
17592 ;;
17593 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17594
17595 (define_expand "lwp_llwpcb"
17596 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17597 UNSPECV_LLWP_INTRINSIC)]
17598 "TARGET_LWP")
17599
17600 (define_insn "*lwp_llwpcb<mode>1"
17601 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17602 UNSPECV_LLWP_INTRINSIC)]
17603 "TARGET_LWP"
17604 "llwpcb\t%0"
17605 [(set_attr "type" "lwp")
17606 (set_attr "mode" "<MODE>")
17607 (set_attr "length" "5")])
17608
17609 (define_expand "lwp_slwpcb"
17610 [(set (match_operand 0 "register_operand" "=r")
17611 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17612 "TARGET_LWP"
17613 {
17614 rtx (*insn)(rtx);
17615
17616 insn = (TARGET_64BIT
17617 ? gen_lwp_slwpcbdi
17618 : gen_lwp_slwpcbsi);
17619
17620 emit_insn (insn (operands[0]));
17621 DONE;
17622 })
17623
17624 (define_insn "lwp_slwpcb<mode>"
17625 [(set (match_operand:P 0 "register_operand" "=r")
17626 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17627 "TARGET_LWP"
17628 "slwpcb\t%0"
17629 [(set_attr "type" "lwp")
17630 (set_attr "mode" "<MODE>")
17631 (set_attr "length" "5")])
17632
17633 (define_expand "lwp_lwpval<mode>3"
17634 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17635 (match_operand:SI 2 "nonimmediate_operand" "rm")
17636 (match_operand:SI 3 "const_int_operand" "i")]
17637 UNSPECV_LWPVAL_INTRINSIC)]
17638 "TARGET_LWP"
17639 "/* Avoid unused variable warning. */
17640 (void) operand0;")
17641
17642 (define_insn "*lwp_lwpval<mode>3_1"
17643 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17644 (match_operand:SI 1 "nonimmediate_operand" "rm")
17645 (match_operand:SI 2 "const_int_operand" "i")]
17646 UNSPECV_LWPVAL_INTRINSIC)]
17647 "TARGET_LWP"
17648 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17649 [(set_attr "type" "lwp")
17650 (set_attr "mode" "<MODE>")
17651 (set (attr "length")
17652 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17653
17654 (define_expand "lwp_lwpins<mode>3"
17655 [(set (reg:CCC FLAGS_REG)
17656 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17657 (match_operand:SI 2 "nonimmediate_operand" "rm")
17658 (match_operand:SI 3 "const_int_operand" "i")]
17659 UNSPECV_LWPINS_INTRINSIC))
17660 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17661 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17662 "TARGET_LWP")
17663
17664 (define_insn "*lwp_lwpins<mode>3_1"
17665 [(set (reg:CCC FLAGS_REG)
17666 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17667 (match_operand:SI 1 "nonimmediate_operand" "rm")
17668 (match_operand:SI 2 "const_int_operand" "i")]
17669 UNSPECV_LWPINS_INTRINSIC))]
17670 "TARGET_LWP"
17671 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17672 [(set_attr "type" "lwp")
17673 (set_attr "mode" "<MODE>")
17674 (set (attr "length")
17675 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17676
17677 (define_insn "rdfsbase<mode>"
17678 [(set (match_operand:SWI48 0 "register_operand" "=r")
17679 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17680 "TARGET_64BIT && TARGET_FSGSBASE"
17681 "rdfsbase %0"
17682 [(set_attr "type" "other")
17683 (set_attr "prefix_extra" "2")])
17684
17685 (define_insn "rdgsbase<mode>"
17686 [(set (match_operand:SWI48 0 "register_operand" "=r")
17687 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17688 "TARGET_64BIT && TARGET_FSGSBASE"
17689 "rdgsbase %0"
17690 [(set_attr "type" "other")
17691 (set_attr "prefix_extra" "2")])
17692
17693 (define_insn "wrfsbase<mode>"
17694 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17695 UNSPECV_WRFSBASE)]
17696 "TARGET_64BIT && TARGET_FSGSBASE"
17697 "wrfsbase %0"
17698 [(set_attr "type" "other")
17699 (set_attr "prefix_extra" "2")])
17700
17701 (define_insn "wrgsbase<mode>"
17702 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17703 UNSPECV_WRGSBASE)]
17704 "TARGET_64BIT && TARGET_FSGSBASE"
17705 "wrgsbase %0"
17706 [(set_attr "type" "other")
17707 (set_attr "prefix_extra" "2")])
17708
17709 (define_insn "rdrand<mode>_1"
17710 [(set (match_operand:SWI248 0 "register_operand" "=r")
17711 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17712 (set (reg:CCC FLAGS_REG)
17713 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17714 "TARGET_RDRND"
17715 "rdrand\t%0"
17716 [(set_attr "type" "other")
17717 (set_attr "prefix_extra" "1")])
17718
17719 (include "mmx.md")
17720 (include "sse.md")
17721 (include "sync.md")