sse.md (*avx_<umaxmin:code><mode>3): Split from *avx_<maxmin:code><mode>3.
[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
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
80 ;; Prologue support
81 UNSPEC_STACK_ALLOC
82 UNSPEC_SET_GOT
83 UNSPEC_REG_SAVE
84 UNSPEC_DEF_CFA
85 UNSPEC_SET_RIP
86 UNSPEC_SET_GOT_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_STACK_CHECK
89
90 ;; TLS support
91 UNSPEC_TP
92 UNSPEC_TLS_GD
93 UNSPEC_TLS_LD_BASE
94 UNSPEC_TLSDESC
95
96 ;; Other random patterns
97 UNSPEC_SCAS
98 UNSPEC_FNSTSW
99 UNSPEC_SAHF
100 UNSPEC_PARITY
101 UNSPEC_FSTCW
102 UNSPEC_ADD_CARRY
103 UNSPEC_FLDCW
104 UNSPEC_REP
105 UNSPEC_LD_MPIC ; load_macho_picbase
106 UNSPEC_TRUNC_NOOP
107 UNSPEC_DIV_ALREADY_SPLIT
108
109 ;; For SSE/MMX support:
110 UNSPEC_FIX_NOTRUNC
111 UNSPEC_MASKMOV
112 UNSPEC_MOVMSK
113 UNSPEC_MOVNT
114 UNSPEC_MOVU
115 UNSPEC_RCP
116 UNSPEC_RSQRT
117 UNSPEC_SFENCE
118 UNSPEC_PFRCP
119 UNSPEC_PFRCPIT1
120 UNSPEC_PFRCPIT2
121 UNSPEC_PFRSQRT
122 UNSPEC_PFRSQIT1
123 UNSPEC_MFENCE
124 UNSPEC_LFENCE
125 UNSPEC_PSADBW
126 UNSPEC_LDDQU
127 UNSPEC_MS_TO_SYSV_CALL
128
129 ;; Generic math support
130 UNSPEC_COPYSIGN
131 UNSPEC_IEEE_MIN ; not commutative
132 UNSPEC_IEEE_MAX ; not commutative
133
134 ;; x87 Floating point
135 UNSPEC_SIN
136 UNSPEC_COS
137 UNSPEC_FPATAN
138 UNSPEC_FYL2X
139 UNSPEC_FYL2XP1
140 UNSPEC_FRNDINT
141 UNSPEC_FIST
142 UNSPEC_F2XM1
143 UNSPEC_TAN
144 UNSPEC_FXAM
145
146 ;; x87 Rounding
147 UNSPEC_FRNDINT_FLOOR
148 UNSPEC_FRNDINT_CEIL
149 UNSPEC_FRNDINT_TRUNC
150 UNSPEC_FRNDINT_MASK_PM
151 UNSPEC_FIST_FLOOR
152 UNSPEC_FIST_CEIL
153
154 ;; x87 Double output FP
155 UNSPEC_SINCOS_COS
156 UNSPEC_SINCOS_SIN
157 UNSPEC_XTRACT_FRACT
158 UNSPEC_XTRACT_EXP
159 UNSPEC_FSCALE_FRACT
160 UNSPEC_FSCALE_EXP
161 UNSPEC_FPREM_F
162 UNSPEC_FPREM_U
163 UNSPEC_FPREM1_F
164 UNSPEC_FPREM1_U
165
166 UNSPEC_C2_FLAG
167 UNSPEC_FXAM_MEM
168
169 ;; SSP patterns
170 UNSPEC_SP_SET
171 UNSPEC_SP_TEST
172 UNSPEC_SP_TLS_SET
173 UNSPEC_SP_TLS_TEST
174
175 ;; SSSE3
176 UNSPEC_PSHUFB
177 UNSPEC_PSIGN
178 UNSPEC_PALIGNR
179
180 ;; For SSE4A support
181 UNSPEC_EXTRQI
182 UNSPEC_EXTRQ
183 UNSPEC_INSERTQI
184 UNSPEC_INSERTQ
185
186 ;; For SSE4.1 support
187 UNSPEC_BLENDV
188 UNSPEC_INSERTPS
189 UNSPEC_DP
190 UNSPEC_MOVNTDQA
191 UNSPEC_MPSADBW
192 UNSPEC_PHMINPOSUW
193 UNSPEC_PTEST
194 UNSPEC_ROUND
195
196 ;; For SSE4.2 support
197 UNSPEC_CRC32
198 UNSPEC_PCMPESTR
199 UNSPEC_PCMPISTR
200
201 ;; For FMA4 support
202 UNSPEC_FMA4_INTRINSIC
203 UNSPEC_FMA4_FMADDSUB
204 UNSPEC_FMA4_FMSUBADD
205 UNSPEC_XOP_UNSIGNED_CMP
206 UNSPEC_XOP_TRUEFALSE
207 UNSPEC_XOP_PERMUTE
208 UNSPEC_FRCZ
209
210 ;; For AES support
211 UNSPEC_AESENC
212 UNSPEC_AESENCLAST
213 UNSPEC_AESDEC
214 UNSPEC_AESDECLAST
215 UNSPEC_AESIMC
216 UNSPEC_AESKEYGENASSIST
217
218 ;; For PCLMUL support
219 UNSPEC_PCLMUL
220
221 ;; For AVX support
222 UNSPEC_PCMP
223 UNSPEC_VPERMIL
224 UNSPEC_VPERMIL2
225 UNSPEC_VPERMIL2F128
226 UNSPEC_MASKLOAD
227 UNSPEC_MASKSTORE
228 UNSPEC_CAST
229 UNSPEC_VTESTP
230 UNSPEC_VCVTPH2PS
231 UNSPEC_VCVTPS2PH
232 ])
233
234 (define_c_enum "unspecv" [
235 UNSPECV_BLOCKAGE
236 UNSPECV_STACK_PROBE
237 UNSPECV_PROBE_STACK_RANGE
238 UNSPECV_EMMS
239 UNSPECV_LDMXCSR
240 UNSPECV_STMXCSR
241 UNSPECV_FEMMS
242 UNSPECV_CLFLUSH
243 UNSPECV_ALIGN
244 UNSPECV_MONITOR
245 UNSPECV_MWAIT
246 UNSPECV_CMPXCHG
247 UNSPECV_XCHG
248 UNSPECV_LOCK
249 UNSPECV_PROLOGUE_USE
250 UNSPECV_CLD
251 UNSPECV_NOPS
252 UNSPECV_VZEROALL
253 UNSPECV_VZEROUPPER
254 UNSPECV_RDTSC
255 UNSPECV_RDTSCP
256 UNSPECV_RDPMC
257 UNSPECV_LLWP_INTRINSIC
258 UNSPECV_SLWP_INTRINSIC
259 UNSPECV_LWPVAL_INTRINSIC
260 UNSPECV_LWPINS_INTRINSIC
261 UNSPECV_RDFSBASE
262 UNSPECV_RDGSBASE
263 UNSPECV_WRFSBASE
264 UNSPECV_WRGSBASE
265 UNSPECV_RDRAND
266 ])
267
268 ;; Constants to represent pcomtrue/pcomfalse variants
269 (define_constants
270 [(PCOM_FALSE 0)
271 (PCOM_TRUE 1)
272 (COM_FALSE_S 2)
273 (COM_FALSE_P 3)
274 (COM_TRUE_S 4)
275 (COM_TRUE_P 5)
276 ])
277
278 ;; Constants used in the XOP pperm instruction
279 (define_constants
280 [(PPERM_SRC 0x00) /* copy source */
281 (PPERM_INVERT 0x20) /* invert source */
282 (PPERM_REVERSE 0x40) /* bit reverse source */
283 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
284 (PPERM_ZERO 0x80) /* all 0's */
285 (PPERM_ONES 0xa0) /* all 1's */
286 (PPERM_SIGN 0xc0) /* propagate sign bit */
287 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
288 (PPERM_SRC1 0x00) /* use first source byte */
289 (PPERM_SRC2 0x10) /* use second source byte */
290 ])
291
292 ;; Registers by name.
293 (define_constants
294 [(AX_REG 0)
295 (DX_REG 1)
296 (CX_REG 2)
297 (BX_REG 3)
298 (SI_REG 4)
299 (DI_REG 5)
300 (BP_REG 6)
301 (SP_REG 7)
302 (ST0_REG 8)
303 (ST1_REG 9)
304 (ST2_REG 10)
305 (ST3_REG 11)
306 (ST4_REG 12)
307 (ST5_REG 13)
308 (ST6_REG 14)
309 (ST7_REG 15)
310 (FLAGS_REG 17)
311 (FPSR_REG 18)
312 (FPCR_REG 19)
313 (XMM0_REG 21)
314 (XMM1_REG 22)
315 (XMM2_REG 23)
316 (XMM3_REG 24)
317 (XMM4_REG 25)
318 (XMM5_REG 26)
319 (XMM6_REG 27)
320 (XMM7_REG 28)
321 (MM0_REG 29)
322 (MM1_REG 30)
323 (MM2_REG 31)
324 (MM3_REG 32)
325 (MM4_REG 33)
326 (MM5_REG 34)
327 (MM6_REG 35)
328 (MM7_REG 36)
329 (R8_REG 37)
330 (R9_REG 38)
331 (R10_REG 39)
332 (R11_REG 40)
333 (R12_REG 41)
334 (R13_REG 42)
335 (XMM8_REG 45)
336 (XMM9_REG 46)
337 (XMM10_REG 47)
338 (XMM11_REG 48)
339 (XMM12_REG 49)
340 (XMM13_REG 50)
341 (XMM14_REG 51)
342 (XMM15_REG 52)
343 ])
344
345 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
346 ;; from i386.c.
347
348 ;; In C guard expressions, put expressions which may be compile-time
349 ;; constants first. This allows for better optimization. For
350 ;; example, write "TARGET_64BIT && reload_completed", not
351 ;; "reload_completed && TARGET_64BIT".
352
353 \f
354 ;; Processor type.
355 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
356 generic64,amdfam10,bdver1"
357 (const (symbol_ref "ix86_schedule")))
358
359 ;; A basic instruction type. Refinements due to arguments to be
360 ;; provided in other attributes.
361 (define_attr "type"
362 "other,multi,
363 alu,alu1,negnot,imov,imovx,lea,
364 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
365 icmp,test,ibr,setcc,icmov,
366 push,pop,call,callv,leave,
367 str,bitmanip,
368 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
369 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
370 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
371 ssemuladd,sse4arg,lwp,
372 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
373 (const_string "other"))
374
375 ;; Main data type used by the insn
376 (define_attr "mode"
377 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
378 (const_string "unknown"))
379
380 ;; The CPU unit operations uses.
381 (define_attr "unit" "integer,i387,sse,mmx,unknown"
382 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
383 (const_string "i387")
384 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
385 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
386 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
387 (const_string "sse")
388 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
389 (const_string "mmx")
390 (eq_attr "type" "other")
391 (const_string "unknown")]
392 (const_string "integer")))
393
394 ;; The (bounding maximum) length of an instruction immediate.
395 (define_attr "length_immediate" ""
396 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
397 bitmanip")
398 (const_int 0)
399 (eq_attr "unit" "i387,sse,mmx")
400 (const_int 0)
401 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
402 imul,icmp,push,pop")
403 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
404 (eq_attr "type" "imov,test")
405 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
406 (eq_attr "type" "call")
407 (if_then_else (match_operand 0 "constant_call_address_operand" "")
408 (const_int 4)
409 (const_int 0))
410 (eq_attr "type" "callv")
411 (if_then_else (match_operand 1 "constant_call_address_operand" "")
412 (const_int 4)
413 (const_int 0))
414 ;; We don't know the size before shorten_branches. Expect
415 ;; the instruction to fit for better scheduling.
416 (eq_attr "type" "ibr")
417 (const_int 1)
418 ]
419 (symbol_ref "/* Update immediate_length and other attributes! */
420 gcc_unreachable (),1")))
421
422 ;; The (bounding maximum) length of an instruction address.
423 (define_attr "length_address" ""
424 (cond [(eq_attr "type" "str,other,multi,fxch")
425 (const_int 0)
426 (and (eq_attr "type" "call")
427 (match_operand 0 "constant_call_address_operand" ""))
428 (const_int 0)
429 (and (eq_attr "type" "callv")
430 (match_operand 1 "constant_call_address_operand" ""))
431 (const_int 0)
432 ]
433 (symbol_ref "ix86_attr_length_address_default (insn)")))
434
435 ;; Set when length prefix is used.
436 (define_attr "prefix_data16" ""
437 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
438 (const_int 0)
439 (eq_attr "mode" "HI")
440 (const_int 1)
441 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
442 (const_int 1)
443 ]
444 (const_int 0)))
445
446 ;; Set when string REP prefix is used.
447 (define_attr "prefix_rep" ""
448 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
449 (const_int 0)
450 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
451 (const_int 1)
452 ]
453 (const_int 0)))
454
455 ;; Set when 0f opcode prefix is used.
456 (define_attr "prefix_0f" ""
457 (if_then_else
458 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
459 (eq_attr "unit" "sse,mmx"))
460 (const_int 1)
461 (const_int 0)))
462
463 ;; Set when REX opcode prefix is used.
464 (define_attr "prefix_rex" ""
465 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
466 (const_int 0)
467 (and (eq_attr "mode" "DI")
468 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
469 (eq_attr "unit" "!mmx")))
470 (const_int 1)
471 (and (eq_attr "mode" "QI")
472 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
473 (const_int 0)))
474 (const_int 1)
475 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
476 (const_int 0))
477 (const_int 1)
478 (and (eq_attr "type" "imovx")
479 (match_operand:QI 1 "ext_QIreg_operand" ""))
480 (const_int 1)
481 ]
482 (const_int 0)))
483
484 ;; There are also additional prefixes in 3DNOW, SSSE3.
485 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
486 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
487 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
488 (define_attr "prefix_extra" ""
489 (cond [(eq_attr "type" "ssemuladd,sse4arg")
490 (const_int 2)
491 (eq_attr "type" "sseiadd1,ssecvt1")
492 (const_int 1)
493 ]
494 (const_int 0)))
495
496 ;; Prefix used: original, VEX or maybe VEX.
497 (define_attr "prefix" "orig,vex,maybe_vex"
498 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
499 (const_string "vex")
500 (const_string "orig")))
501
502 ;; VEX W bit is used.
503 (define_attr "prefix_vex_w" "" (const_int 0))
504
505 ;; The length of VEX prefix
506 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
507 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
508 ;; still prefix_0f 1, with prefix_extra 1.
509 (define_attr "length_vex" ""
510 (if_then_else (and (eq_attr "prefix_0f" "1")
511 (eq_attr "prefix_extra" "0"))
512 (if_then_else (eq_attr "prefix_vex_w" "1")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
514 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
515 (if_then_else (eq_attr "prefix_vex_w" "1")
516 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
517 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
518
519 ;; Set when modrm byte is used.
520 (define_attr "modrm" ""
521 (cond [(eq_attr "type" "str,leave")
522 (const_int 0)
523 (eq_attr "unit" "i387")
524 (const_int 0)
525 (and (eq_attr "type" "incdec")
526 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
527 (ior (match_operand:SI 1 "register_operand" "")
528 (match_operand:HI 1 "register_operand" ""))))
529 (const_int 0)
530 (and (eq_attr "type" "push")
531 (not (match_operand 1 "memory_operand" "")))
532 (const_int 0)
533 (and (eq_attr "type" "pop")
534 (not (match_operand 0 "memory_operand" "")))
535 (const_int 0)
536 (and (eq_attr "type" "imov")
537 (and (not (eq_attr "mode" "DI"))
538 (ior (and (match_operand 0 "register_operand" "")
539 (match_operand 1 "immediate_operand" ""))
540 (ior (and (match_operand 0 "ax_reg_operand" "")
541 (match_operand 1 "memory_displacement_only_operand" ""))
542 (and (match_operand 0 "memory_displacement_only_operand" "")
543 (match_operand 1 "ax_reg_operand" ""))))))
544 (const_int 0)
545 (and (eq_attr "type" "call")
546 (match_operand 0 "constant_call_address_operand" ""))
547 (const_int 0)
548 (and (eq_attr "type" "callv")
549 (match_operand 1 "constant_call_address_operand" ""))
550 (const_int 0)
551 (and (eq_attr "type" "alu,alu1,icmp,test")
552 (match_operand 0 "ax_reg_operand" ""))
553 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
554 ]
555 (const_int 1)))
556
557 ;; The (bounding maximum) length of an instruction in bytes.
558 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
559 ;; Later we may want to split them and compute proper length as for
560 ;; other insns.
561 (define_attr "length" ""
562 (cond [(eq_attr "type" "other,multi,fistp,frndint")
563 (const_int 16)
564 (eq_attr "type" "fcmp")
565 (const_int 4)
566 (eq_attr "unit" "i387")
567 (plus (const_int 2)
568 (plus (attr "prefix_data16")
569 (attr "length_address")))
570 (ior (eq_attr "prefix" "vex")
571 (and (eq_attr "prefix" "maybe_vex")
572 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
573 (plus (attr "length_vex")
574 (plus (attr "length_immediate")
575 (plus (attr "modrm")
576 (attr "length_address"))))]
577 (plus (plus (attr "modrm")
578 (plus (attr "prefix_0f")
579 (plus (attr "prefix_rex")
580 (plus (attr "prefix_extra")
581 (const_int 1)))))
582 (plus (attr "prefix_rep")
583 (plus (attr "prefix_data16")
584 (plus (attr "length_immediate")
585 (attr "length_address")))))))
586
587 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
588 ;; `store' if there is a simple memory reference therein, or `unknown'
589 ;; if the instruction is complex.
590
591 (define_attr "memory" "none,load,store,both,unknown"
592 (cond [(eq_attr "type" "other,multi,str,lwp")
593 (const_string "unknown")
594 (eq_attr "type" "lea,fcmov,fpspc")
595 (const_string "none")
596 (eq_attr "type" "fistp,leave")
597 (const_string "both")
598 (eq_attr "type" "frndint")
599 (const_string "load")
600 (eq_attr "type" "push")
601 (if_then_else (match_operand 1 "memory_operand" "")
602 (const_string "both")
603 (const_string "store"))
604 (eq_attr "type" "pop")
605 (if_then_else (match_operand 0 "memory_operand" "")
606 (const_string "both")
607 (const_string "load"))
608 (eq_attr "type" "setcc")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "store")
611 (const_string "none"))
612 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
613 (if_then_else (ior (match_operand 0 "memory_operand" "")
614 (match_operand 1 "memory_operand" ""))
615 (const_string "load")
616 (const_string "none"))
617 (eq_attr "type" "ibr")
618 (if_then_else (match_operand 0 "memory_operand" "")
619 (const_string "load")
620 (const_string "none"))
621 (eq_attr "type" "call")
622 (if_then_else (match_operand 0 "constant_call_address_operand" "")
623 (const_string "none")
624 (const_string "load"))
625 (eq_attr "type" "callv")
626 (if_then_else (match_operand 1 "constant_call_address_operand" "")
627 (const_string "none")
628 (const_string "load"))
629 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "both")
632 (and (match_operand 0 "memory_operand" "")
633 (match_operand 1 "memory_operand" ""))
634 (const_string "both")
635 (match_operand 0 "memory_operand" "")
636 (const_string "store")
637 (match_operand 1 "memory_operand" "")
638 (const_string "load")
639 (and (eq_attr "type"
640 "!alu1,negnot,ishift1,
641 imov,imovx,icmp,test,bitmanip,
642 fmov,fcmp,fsgn,
643 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
644 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
645 (match_operand 2 "memory_operand" ""))
646 (const_string "load")
647 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
648 (match_operand 3 "memory_operand" ""))
649 (const_string "load")
650 ]
651 (const_string "none")))
652
653 ;; Indicates if an instruction has both an immediate and a displacement.
654
655 (define_attr "imm_disp" "false,true,unknown"
656 (cond [(eq_attr "type" "other,multi")
657 (const_string "unknown")
658 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
659 (and (match_operand 0 "memory_displacement_operand" "")
660 (match_operand 1 "immediate_operand" "")))
661 (const_string "true")
662 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
663 (and (match_operand 0 "memory_displacement_operand" "")
664 (match_operand 2 "immediate_operand" "")))
665 (const_string "true")
666 ]
667 (const_string "false")))
668
669 ;; Indicates if an FP operation has an integer source.
670
671 (define_attr "fp_int_src" "false,true"
672 (const_string "false"))
673
674 ;; Defines rounding mode of an FP operation.
675
676 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
677 (const_string "any"))
678
679 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
680 (define_attr "use_carry" "0,1" (const_string "0"))
681
682 ;; Define attribute to indicate unaligned ssemov insns
683 (define_attr "movu" "0,1" (const_string "0"))
684
685 ;; Describe a user's asm statement.
686 (define_asm_attributes
687 [(set_attr "length" "128")
688 (set_attr "type" "multi")])
689
690 (define_code_iterator plusminus [plus minus])
691
692 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
693
694 ;; Base name for define_insn
695 (define_code_attr plusminus_insn
696 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
697 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
698
699 ;; Base name for insn mnemonic.
700 (define_code_attr plusminus_mnemonic
701 [(plus "add") (ss_plus "adds") (us_plus "addus")
702 (minus "sub") (ss_minus "subs") (us_minus "subus")])
703 (define_code_attr plusminus_carry_mnemonic
704 [(plus "adc") (minus "sbb")])
705
706 ;; Mark commutative operators as such in constraints.
707 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
708 (minus "") (ss_minus "") (us_minus "")])
709
710 ;; Mapping of signed max and min
711 (define_code_iterator smaxmin [smax smin])
712
713 ;; Mapping of unsigned max and min
714 (define_code_iterator umaxmin [umax umin])
715
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
718 (umax "maxu") (umin "minu")])
719 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727
728 ;; Mapping of shift-right operators
729 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730
731 ;; Base name for define_insn
732 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733
734 ;; Base name for insn mnemonic.
735 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736
737 ;; Mapping of rotate operators
738 (define_code_iterator any_rotate [rotate rotatert])
739
740 ;; Base name for define_insn
741 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742
743 ;; Base name for insn mnemonic.
744 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745
746 ;; Mapping of abs neg operators
747 (define_code_iterator absneg [abs neg])
748
749 ;; Base name for x87 insn mnemonic.
750 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751
752 ;; Used in signed and unsigned widening multiplications.
753 (define_code_iterator any_extend [sign_extend zero_extend])
754
755 ;; Various insn prefixes for signed and unsigned operations.
756 (define_code_attr u [(sign_extend "") (zero_extend "u")
757 (div "") (udiv "u")])
758 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759
760 ;; Used in signed and unsigned divisions.
761 (define_code_iterator any_div [div udiv])
762
763 ;; Instruction prefix for signed and unsigned operations.
764 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
765 (div "i") (udiv "")])
766
767 ;; 64bit single word integer modes.
768 (define_mode_iterator SWI1248x [QI HI SI DI])
769
770 ;; 64bit single word integer modes without QImode and HImode.
771 (define_mode_iterator SWI48x [SI DI])
772
773 ;; Single word integer modes.
774 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
775
776 ;; Single word integer modes without SImode and DImode.
777 (define_mode_iterator SWI12 [QI HI])
778
779 ;; Single word integer modes without DImode.
780 (define_mode_iterator SWI124 [QI HI SI])
781
782 ;; Single word integer modes without QImode and DImode.
783 (define_mode_iterator SWI24 [HI SI])
784
785 ;; Single word integer modes without QImode.
786 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
787
788 ;; Single word integer modes without QImode and HImode.
789 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
790
791 ;; All math-dependant single and double word integer modes.
792 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
793 (HI "TARGET_HIMODE_MATH")
794 SI DI (TI "TARGET_64BIT")])
795
796 ;; Math-dependant single word integer modes.
797 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
798 (HI "TARGET_HIMODE_MATH")
799 SI (DI "TARGET_64BIT")])
800
801 ;; Math-dependant single word integer modes without DImode.
802 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
803 (HI "TARGET_HIMODE_MATH")
804 SI])
805
806 ;; Math-dependant single word integer modes without QImode.
807 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
808 SI (DI "TARGET_64BIT")])
809
810 ;; Double word integer modes.
811 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
812 (TI "TARGET_64BIT")])
813
814 ;; Double word integer modes as mode attribute.
815 (define_mode_attr DWI [(SI "DI") (DI "TI")])
816 (define_mode_attr dwi [(SI "di") (DI "ti")])
817
818 ;; Half mode for double word integer modes.
819 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
820 (DI "TARGET_64BIT")])
821
822 ;; Instruction suffix for integer modes.
823 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
824
825 ;; Pointer size prefix for integer modes (Intel asm dialect)
826 (define_mode_attr iptrsize [(QI "BYTE")
827 (HI "WORD")
828 (SI "DWORD")
829 (DI "QWORD")])
830
831 ;; Register class for integer modes.
832 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
833
834 ;; Immediate operand constraint for integer modes.
835 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
836
837 ;; General operand constraint for word modes.
838 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
839
840 ;; Immediate operand constraint for double integer modes.
841 (define_mode_attr di [(SI "iF") (DI "e")])
842
843 ;; Immediate operand constraint for shifts.
844 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
845
846 ;; General operand predicate for integer modes.
847 (define_mode_attr general_operand
848 [(QI "general_operand")
849 (HI "general_operand")
850 (SI "general_operand")
851 (DI "x86_64_general_operand")
852 (TI "x86_64_general_operand")])
853
854 ;; General sign/zero extend operand predicate for integer modes.
855 (define_mode_attr general_szext_operand
856 [(QI "general_operand")
857 (HI "general_operand")
858 (SI "general_operand")
859 (DI "x86_64_szext_general_operand")])
860
861 ;; Immediate operand predicate for integer modes.
862 (define_mode_attr immediate_operand
863 [(QI "immediate_operand")
864 (HI "immediate_operand")
865 (SI "immediate_operand")
866 (DI "x86_64_immediate_operand")])
867
868 ;; Nonmemory operand predicate for integer modes.
869 (define_mode_attr nonmemory_operand
870 [(QI "nonmemory_operand")
871 (HI "nonmemory_operand")
872 (SI "nonmemory_operand")
873 (DI "x86_64_nonmemory_operand")])
874
875 ;; Operand predicate for shifts.
876 (define_mode_attr shift_operand
877 [(QI "nonimmediate_operand")
878 (HI "nonimmediate_operand")
879 (SI "nonimmediate_operand")
880 (DI "shiftdi_operand")
881 (TI "register_operand")])
882
883 ;; Operand predicate for shift argument.
884 (define_mode_attr shift_immediate_operand
885 [(QI "const_1_to_31_operand")
886 (HI "const_1_to_31_operand")
887 (SI "const_1_to_31_operand")
888 (DI "const_1_to_63_operand")])
889
890 ;; Input operand predicate for arithmetic left shifts.
891 (define_mode_attr ashl_input_operand
892 [(QI "nonimmediate_operand")
893 (HI "nonimmediate_operand")
894 (SI "nonimmediate_operand")
895 (DI "ashldi_input_operand")
896 (TI "reg_or_pm1_operand")])
897
898 ;; SSE and x87 SFmode and DFmode floating point modes
899 (define_mode_iterator MODEF [SF DF])
900
901 ;; All x87 floating point modes
902 (define_mode_iterator X87MODEF [SF DF XF])
903
904 ;; All integer modes handled by x87 fisttp operator.
905 (define_mode_iterator X87MODEI [HI SI DI])
906
907 ;; All integer modes handled by integer x87 operators.
908 (define_mode_iterator X87MODEI12 [HI SI])
909
910 ;; All integer modes handled by SSE cvtts?2si* operators.
911 (define_mode_iterator SSEMODEI24 [SI DI])
912
913 ;; SSE asm suffix for floating point modes
914 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
915
916 ;; SSE vector mode corresponding to a scalar mode
917 (define_mode_attr ssevecmode
918 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
919
920 ;; Instruction suffix for REX 64bit operators.
921 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
922
923 ;; This mode iterator allows :P to be used for patterns that operate on
924 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
925 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
926 \f
927 ;; Scheduling descriptions
928
929 (include "pentium.md")
930 (include "ppro.md")
931 (include "k6.md")
932 (include "athlon.md")
933 (include "geode.md")
934 (include "atom.md")
935
936 \f
937 ;; Operand and operator predicates and constraints
938
939 (include "predicates.md")
940 (include "constraints.md")
941
942 \f
943 ;; Compare and branch/compare and store instructions.
944
945 (define_expand "cbranch<mode>4"
946 [(set (reg:CC FLAGS_REG)
947 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
948 (match_operand:SDWIM 2 "<general_operand>" "")))
949 (set (pc) (if_then_else
950 (match_operator 0 "ordered_comparison_operator"
951 [(reg:CC FLAGS_REG) (const_int 0)])
952 (label_ref (match_operand 3 "" ""))
953 (pc)))]
954 ""
955 {
956 if (MEM_P (operands[1]) && MEM_P (operands[2]))
957 operands[1] = force_reg (<MODE>mode, operands[1]);
958 ix86_expand_branch (GET_CODE (operands[0]),
959 operands[1], operands[2], operands[3]);
960 DONE;
961 })
962
963 (define_expand "cstore<mode>4"
964 [(set (reg:CC FLAGS_REG)
965 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
966 (match_operand:SWIM 3 "<general_operand>" "")))
967 (set (match_operand:QI 0 "register_operand" "")
968 (match_operator 1 "ordered_comparison_operator"
969 [(reg:CC FLAGS_REG) (const_int 0)]))]
970 ""
971 {
972 if (MEM_P (operands[2]) && MEM_P (operands[3]))
973 operands[2] = force_reg (<MODE>mode, operands[2]);
974 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
975 operands[2], operands[3]);
976 DONE;
977 })
978
979 (define_expand "cmp<mode>_1"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
982 (match_operand:SWI48 1 "<general_operand>" "")))])
983
984 (define_insn "*cmp<mode>_ccno_1"
985 [(set (reg FLAGS_REG)
986 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
987 (match_operand:SWI 1 "const0_operand" "")))]
988 "ix86_match_ccmode (insn, CCNOmode)"
989 "@
990 test{<imodesuffix>}\t%0, %0
991 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
992 [(set_attr "type" "test,icmp")
993 (set_attr "length_immediate" "0,1")
994 (set_attr "mode" "<MODE>")])
995
996 (define_insn "*cmp<mode>_1"
997 [(set (reg FLAGS_REG)
998 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
999 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1000 "ix86_match_ccmode (insn, CCmode)"
1001 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1002 [(set_attr "type" "icmp")
1003 (set_attr "mode" "<MODE>")])
1004
1005 (define_insn "*cmp<mode>_minus_1"
1006 [(set (reg FLAGS_REG)
1007 (compare
1008 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1009 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1010 (const_int 0)))]
1011 "ix86_match_ccmode (insn, CCGOCmode)"
1012 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1013 [(set_attr "type" "icmp")
1014 (set_attr "mode" "<MODE>")])
1015
1016 (define_insn "*cmpqi_ext_1"
1017 [(set (reg FLAGS_REG)
1018 (compare
1019 (match_operand:QI 0 "general_operand" "Qm")
1020 (subreg:QI
1021 (zero_extract:SI
1022 (match_operand 1 "ext_register_operand" "Q")
1023 (const_int 8)
1024 (const_int 8)) 0)))]
1025 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1026 "cmp{b}\t{%h1, %0|%0, %h1}"
1027 [(set_attr "type" "icmp")
1028 (set_attr "mode" "QI")])
1029
1030 (define_insn "*cmpqi_ext_1_rex64"
1031 [(set (reg FLAGS_REG)
1032 (compare
1033 (match_operand:QI 0 "register_operand" "Q")
1034 (subreg:QI
1035 (zero_extract:SI
1036 (match_operand 1 "ext_register_operand" "Q")
1037 (const_int 8)
1038 (const_int 8)) 0)))]
1039 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1040 "cmp{b}\t{%h1, %0|%0, %h1}"
1041 [(set_attr "type" "icmp")
1042 (set_attr "mode" "QI")])
1043
1044 (define_insn "*cmpqi_ext_2"
1045 [(set (reg FLAGS_REG)
1046 (compare
1047 (subreg:QI
1048 (zero_extract:SI
1049 (match_operand 0 "ext_register_operand" "Q")
1050 (const_int 8)
1051 (const_int 8)) 0)
1052 (match_operand:QI 1 "const0_operand" "")))]
1053 "ix86_match_ccmode (insn, CCNOmode)"
1054 "test{b}\t%h0, %h0"
1055 [(set_attr "type" "test")
1056 (set_attr "length_immediate" "0")
1057 (set_attr "mode" "QI")])
1058
1059 (define_expand "cmpqi_ext_3"
1060 [(set (reg:CC FLAGS_REG)
1061 (compare:CC
1062 (subreg:QI
1063 (zero_extract:SI
1064 (match_operand 0 "ext_register_operand" "")
1065 (const_int 8)
1066 (const_int 8)) 0)
1067 (match_operand:QI 1 "immediate_operand" "")))])
1068
1069 (define_insn "*cmpqi_ext_3_insn"
1070 [(set (reg FLAGS_REG)
1071 (compare
1072 (subreg:QI
1073 (zero_extract:SI
1074 (match_operand 0 "ext_register_operand" "Q")
1075 (const_int 8)
1076 (const_int 8)) 0)
1077 (match_operand:QI 1 "general_operand" "Qmn")))]
1078 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1079 "cmp{b}\t{%1, %h0|%h0, %1}"
1080 [(set_attr "type" "icmp")
1081 (set_attr "modrm" "1")
1082 (set_attr "mode" "QI")])
1083
1084 (define_insn "*cmpqi_ext_3_insn_rex64"
1085 [(set (reg FLAGS_REG)
1086 (compare
1087 (subreg:QI
1088 (zero_extract:SI
1089 (match_operand 0 "ext_register_operand" "Q")
1090 (const_int 8)
1091 (const_int 8)) 0)
1092 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1093 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1094 "cmp{b}\t{%1, %h0|%h0, %1}"
1095 [(set_attr "type" "icmp")
1096 (set_attr "modrm" "1")
1097 (set_attr "mode" "QI")])
1098
1099 (define_insn "*cmpqi_ext_4"
1100 [(set (reg FLAGS_REG)
1101 (compare
1102 (subreg:QI
1103 (zero_extract:SI
1104 (match_operand 0 "ext_register_operand" "Q")
1105 (const_int 8)
1106 (const_int 8)) 0)
1107 (subreg:QI
1108 (zero_extract:SI
1109 (match_operand 1 "ext_register_operand" "Q")
1110 (const_int 8)
1111 (const_int 8)) 0)))]
1112 "ix86_match_ccmode (insn, CCmode)"
1113 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1114 [(set_attr "type" "icmp")
1115 (set_attr "mode" "QI")])
1116
1117 ;; These implement float point compares.
1118 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1119 ;; which would allow mix and match FP modes on the compares. Which is what
1120 ;; the old patterns did, but with many more of them.
1121
1122 (define_expand "cbranchxf4"
1123 [(set (reg:CC FLAGS_REG)
1124 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1125 (match_operand:XF 2 "nonmemory_operand" "")))
1126 (set (pc) (if_then_else
1127 (match_operator 0 "ix86_fp_comparison_operator"
1128 [(reg:CC FLAGS_REG)
1129 (const_int 0)])
1130 (label_ref (match_operand 3 "" ""))
1131 (pc)))]
1132 "TARGET_80387"
1133 {
1134 ix86_expand_branch (GET_CODE (operands[0]),
1135 operands[1], operands[2], operands[3]);
1136 DONE;
1137 })
1138
1139 (define_expand "cstorexf4"
1140 [(set (reg:CC FLAGS_REG)
1141 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1142 (match_operand:XF 3 "nonmemory_operand" "")))
1143 (set (match_operand:QI 0 "register_operand" "")
1144 (match_operator 1 "ix86_fp_comparison_operator"
1145 [(reg:CC FLAGS_REG)
1146 (const_int 0)]))]
1147 "TARGET_80387"
1148 {
1149 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1150 operands[2], operands[3]);
1151 DONE;
1152 })
1153
1154 (define_expand "cbranch<mode>4"
1155 [(set (reg:CC FLAGS_REG)
1156 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1157 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1158 (set (pc) (if_then_else
1159 (match_operator 0 "ix86_fp_comparison_operator"
1160 [(reg:CC FLAGS_REG)
1161 (const_int 0)])
1162 (label_ref (match_operand 3 "" ""))
1163 (pc)))]
1164 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1165 {
1166 ix86_expand_branch (GET_CODE (operands[0]),
1167 operands[1], operands[2], operands[3]);
1168 DONE;
1169 })
1170
1171 (define_expand "cstore<mode>4"
1172 [(set (reg:CC FLAGS_REG)
1173 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1174 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1175 (set (match_operand:QI 0 "register_operand" "")
1176 (match_operator 1 "ix86_fp_comparison_operator"
1177 [(reg:CC FLAGS_REG)
1178 (const_int 0)]))]
1179 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1180 {
1181 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1182 operands[2], operands[3]);
1183 DONE;
1184 })
1185
1186 (define_expand "cbranchcc4"
1187 [(set (pc) (if_then_else
1188 (match_operator 0 "comparison_operator"
1189 [(match_operand 1 "flags_reg_operand" "")
1190 (match_operand 2 "const0_operand" "")])
1191 (label_ref (match_operand 3 "" ""))
1192 (pc)))]
1193 ""
1194 {
1195 ix86_expand_branch (GET_CODE (operands[0]),
1196 operands[1], operands[2], operands[3]);
1197 DONE;
1198 })
1199
1200 (define_expand "cstorecc4"
1201 [(set (match_operand:QI 0 "register_operand" "")
1202 (match_operator 1 "comparison_operator"
1203 [(match_operand 2 "flags_reg_operand" "")
1204 (match_operand 3 "const0_operand" "")]))]
1205 ""
1206 {
1207 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1208 operands[2], operands[3]);
1209 DONE;
1210 })
1211
1212
1213 ;; FP compares, step 1:
1214 ;; Set the FP condition codes.
1215 ;;
1216 ;; CCFPmode compare with exceptions
1217 ;; CCFPUmode compare with no exceptions
1218
1219 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1220 ;; used to manage the reg stack popping would not be preserved.
1221
1222 (define_insn "*cmpfp_0"
1223 [(set (match_operand:HI 0 "register_operand" "=a")
1224 (unspec:HI
1225 [(compare:CCFP
1226 (match_operand 1 "register_operand" "f")
1227 (match_operand 2 "const0_operand" ""))]
1228 UNSPEC_FNSTSW))]
1229 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1230 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1231 "* return output_fp_compare (insn, operands, 0, 0);"
1232 [(set_attr "type" "multi")
1233 (set_attr "unit" "i387")
1234 (set (attr "mode")
1235 (cond [(match_operand:SF 1 "" "")
1236 (const_string "SF")
1237 (match_operand:DF 1 "" "")
1238 (const_string "DF")
1239 ]
1240 (const_string "XF")))])
1241
1242 (define_insn_and_split "*cmpfp_0_cc"
1243 [(set (reg:CCFP FLAGS_REG)
1244 (compare:CCFP
1245 (match_operand 1 "register_operand" "f")
1246 (match_operand 2 "const0_operand" "")))
1247 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1248 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1249 && TARGET_SAHF && !TARGET_CMOVE
1250 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1251 "#"
1252 "&& reload_completed"
1253 [(set (match_dup 0)
1254 (unspec:HI
1255 [(compare:CCFP (match_dup 1)(match_dup 2))]
1256 UNSPEC_FNSTSW))
1257 (set (reg:CC FLAGS_REG)
1258 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1259 ""
1260 [(set_attr "type" "multi")
1261 (set_attr "unit" "i387")
1262 (set (attr "mode")
1263 (cond [(match_operand:SF 1 "" "")
1264 (const_string "SF")
1265 (match_operand:DF 1 "" "")
1266 (const_string "DF")
1267 ]
1268 (const_string "XF")))])
1269
1270 (define_insn "*cmpfp_xf"
1271 [(set (match_operand:HI 0 "register_operand" "=a")
1272 (unspec:HI
1273 [(compare:CCFP
1274 (match_operand:XF 1 "register_operand" "f")
1275 (match_operand:XF 2 "register_operand" "f"))]
1276 UNSPEC_FNSTSW))]
1277 "TARGET_80387"
1278 "* return output_fp_compare (insn, operands, 0, 0);"
1279 [(set_attr "type" "multi")
1280 (set_attr "unit" "i387")
1281 (set_attr "mode" "XF")])
1282
1283 (define_insn_and_split "*cmpfp_xf_cc"
1284 [(set (reg:CCFP FLAGS_REG)
1285 (compare:CCFP
1286 (match_operand:XF 1 "register_operand" "f")
1287 (match_operand:XF 2 "register_operand" "f")))
1288 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1289 "TARGET_80387
1290 && TARGET_SAHF && !TARGET_CMOVE"
1291 "#"
1292 "&& reload_completed"
1293 [(set (match_dup 0)
1294 (unspec:HI
1295 [(compare:CCFP (match_dup 1)(match_dup 2))]
1296 UNSPEC_FNSTSW))
1297 (set (reg:CC FLAGS_REG)
1298 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1299 ""
1300 [(set_attr "type" "multi")
1301 (set_attr "unit" "i387")
1302 (set_attr "mode" "XF")])
1303
1304 (define_insn "*cmpfp_<mode>"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1306 (unspec:HI
1307 [(compare:CCFP
1308 (match_operand:MODEF 1 "register_operand" "f")
1309 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1310 UNSPEC_FNSTSW))]
1311 "TARGET_80387"
1312 "* return output_fp_compare (insn, operands, 0, 0);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "<MODE>")])
1316
1317 (define_insn_and_split "*cmpfp_<mode>_cc"
1318 [(set (reg:CCFP FLAGS_REG)
1319 (compare:CCFP
1320 (match_operand:MODEF 1 "register_operand" "f")
1321 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
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" "<MODE>")])
1337
1338 (define_insn "*cmpfp_u"
1339 [(set (match_operand:HI 0 "register_operand" "=a")
1340 (unspec:HI
1341 [(compare:CCFPU
1342 (match_operand 1 "register_operand" "f")
1343 (match_operand 2 "register_operand" "f"))]
1344 UNSPEC_FNSTSW))]
1345 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1346 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1347 "* return output_fp_compare (insn, operands, 0, 1);"
1348 [(set_attr "type" "multi")
1349 (set_attr "unit" "i387")
1350 (set (attr "mode")
1351 (cond [(match_operand:SF 1 "" "")
1352 (const_string "SF")
1353 (match_operand:DF 1 "" "")
1354 (const_string "DF")
1355 ]
1356 (const_string "XF")))])
1357
1358 (define_insn_and_split "*cmpfp_u_cc"
1359 [(set (reg:CCFPU FLAGS_REG)
1360 (compare:CCFPU
1361 (match_operand 1 "register_operand" "f")
1362 (match_operand 2 "register_operand" "f")))
1363 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1364 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1365 && TARGET_SAHF && !TARGET_CMOVE
1366 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1367 "#"
1368 "&& reload_completed"
1369 [(set (match_dup 0)
1370 (unspec:HI
1371 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1372 UNSPEC_FNSTSW))
1373 (set (reg:CC FLAGS_REG)
1374 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1375 ""
1376 [(set_attr "type" "multi")
1377 (set_attr "unit" "i387")
1378 (set (attr "mode")
1379 (cond [(match_operand:SF 1 "" "")
1380 (const_string "SF")
1381 (match_operand:DF 1 "" "")
1382 (const_string "DF")
1383 ]
1384 (const_string "XF")))])
1385
1386 (define_insn "*cmpfp_<mode>"
1387 [(set (match_operand:HI 0 "register_operand" "=a")
1388 (unspec:HI
1389 [(compare:CCFP
1390 (match_operand 1 "register_operand" "f")
1391 (match_operator 3 "float_operator"
1392 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1393 UNSPEC_FNSTSW))]
1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1396 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1397 "* return output_fp_compare (insn, operands, 0, 0);"
1398 [(set_attr "type" "multi")
1399 (set_attr "unit" "i387")
1400 (set_attr "fp_int_src" "true")
1401 (set_attr "mode" "<MODE>")])
1402
1403 (define_insn_and_split "*cmpfp_<mode>_cc"
1404 [(set (reg:CCFP FLAGS_REG)
1405 (compare:CCFP
1406 (match_operand 1 "register_operand" "f")
1407 (match_operator 3 "float_operator"
1408 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1409 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1410 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1411 && TARGET_SAHF && !TARGET_CMOVE
1412 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1413 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1414 "#"
1415 "&& reload_completed"
1416 [(set (match_dup 0)
1417 (unspec:HI
1418 [(compare:CCFP
1419 (match_dup 1)
1420 (match_op_dup 3 [(match_dup 2)]))]
1421 UNSPEC_FNSTSW))
1422 (set (reg:CC FLAGS_REG)
1423 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1424 ""
1425 [(set_attr "type" "multi")
1426 (set_attr "unit" "i387")
1427 (set_attr "fp_int_src" "true")
1428 (set_attr "mode" "<MODE>")])
1429
1430 ;; FP compares, step 2
1431 ;; Move the fpsw to ax.
1432
1433 (define_insn "x86_fnstsw_1"
1434 [(set (match_operand:HI 0 "register_operand" "=a")
1435 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1436 "TARGET_80387"
1437 "fnstsw\t%0"
1438 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1439 (set_attr "mode" "SI")
1440 (set_attr "unit" "i387")])
1441
1442 ;; FP compares, step 3
1443 ;; Get ax into flags, general case.
1444
1445 (define_insn "x86_sahf_1"
1446 [(set (reg:CC FLAGS_REG)
1447 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1448 UNSPEC_SAHF))]
1449 "TARGET_SAHF"
1450 {
1451 #ifndef HAVE_AS_IX86_SAHF
1452 if (TARGET_64BIT)
1453 return ASM_BYTE "0x9e";
1454 else
1455 #endif
1456 return "sahf";
1457 }
1458 [(set_attr "length" "1")
1459 (set_attr "athlon_decode" "vector")
1460 (set_attr "amdfam10_decode" "direct")
1461 (set_attr "mode" "SI")])
1462
1463 ;; Pentium Pro can do steps 1 through 3 in one go.
1464 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1465 (define_insn "*cmpfp_i_mixed"
1466 [(set (reg:CCFP FLAGS_REG)
1467 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1468 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1469 "TARGET_MIX_SSE_I387
1470 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1471 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1472 "* return output_fp_compare (insn, operands, 1, 0);"
1473 [(set_attr "type" "fcmp,ssecomi")
1474 (set_attr "prefix" "orig,maybe_vex")
1475 (set (attr "mode")
1476 (if_then_else (match_operand:SF 1 "" "")
1477 (const_string "SF")
1478 (const_string "DF")))
1479 (set (attr "prefix_rep")
1480 (if_then_else (eq_attr "type" "ssecomi")
1481 (const_string "0")
1482 (const_string "*")))
1483 (set (attr "prefix_data16")
1484 (cond [(eq_attr "type" "fcmp")
1485 (const_string "*")
1486 (eq_attr "mode" "DF")
1487 (const_string "1")
1488 ]
1489 (const_string "0")))
1490 (set_attr "athlon_decode" "vector")
1491 (set_attr "amdfam10_decode" "direct")])
1492
1493 (define_insn "*cmpfp_i_sse"
1494 [(set (reg:CCFP FLAGS_REG)
1495 (compare:CCFP (match_operand 0 "register_operand" "x")
1496 (match_operand 1 "nonimmediate_operand" "xm")))]
1497 "TARGET_SSE_MATH
1498 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1499 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1500 "* return output_fp_compare (insn, operands, 1, 0);"
1501 [(set_attr "type" "ssecomi")
1502 (set_attr "prefix" "maybe_vex")
1503 (set (attr "mode")
1504 (if_then_else (match_operand:SF 1 "" "")
1505 (const_string "SF")
1506 (const_string "DF")))
1507 (set_attr "prefix_rep" "0")
1508 (set (attr "prefix_data16")
1509 (if_then_else (eq_attr "mode" "DF")
1510 (const_string "1")
1511 (const_string "0")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")])
1514
1515 (define_insn "*cmpfp_i_i387"
1516 [(set (reg:CCFP FLAGS_REG)
1517 (compare:CCFP (match_operand 0 "register_operand" "f")
1518 (match_operand 1 "register_operand" "f")))]
1519 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1520 && TARGET_CMOVE
1521 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1522 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523 "* return output_fp_compare (insn, operands, 1, 0);"
1524 [(set_attr "type" "fcmp")
1525 (set (attr "mode")
1526 (cond [(match_operand:SF 1 "" "")
1527 (const_string "SF")
1528 (match_operand:DF 1 "" "")
1529 (const_string "DF")
1530 ]
1531 (const_string "XF")))
1532 (set_attr "athlon_decode" "vector")
1533 (set_attr "amdfam10_decode" "direct")])
1534
1535 (define_insn "*cmpfp_iu_mixed"
1536 [(set (reg:CCFPU FLAGS_REG)
1537 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1538 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1539 "TARGET_MIX_SSE_I387
1540 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1541 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1542 "* return output_fp_compare (insn, operands, 1, 1);"
1543 [(set_attr "type" "fcmp,ssecomi")
1544 (set_attr "prefix" "orig,maybe_vex")
1545 (set (attr "mode")
1546 (if_then_else (match_operand:SF 1 "" "")
1547 (const_string "SF")
1548 (const_string "DF")))
1549 (set (attr "prefix_rep")
1550 (if_then_else (eq_attr "type" "ssecomi")
1551 (const_string "0")
1552 (const_string "*")))
1553 (set (attr "prefix_data16")
1554 (cond [(eq_attr "type" "fcmp")
1555 (const_string "*")
1556 (eq_attr "mode" "DF")
1557 (const_string "1")
1558 ]
1559 (const_string "0")))
1560 (set_attr "athlon_decode" "vector")
1561 (set_attr "amdfam10_decode" "direct")])
1562
1563 (define_insn "*cmpfp_iu_sse"
1564 [(set (reg:CCFPU FLAGS_REG)
1565 (compare:CCFPU (match_operand 0 "register_operand" "x")
1566 (match_operand 1 "nonimmediate_operand" "xm")))]
1567 "TARGET_SSE_MATH
1568 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1569 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1570 "* return output_fp_compare (insn, operands, 1, 1);"
1571 [(set_attr "type" "ssecomi")
1572 (set_attr "prefix" "maybe_vex")
1573 (set (attr "mode")
1574 (if_then_else (match_operand:SF 1 "" "")
1575 (const_string "SF")
1576 (const_string "DF")))
1577 (set_attr "prefix_rep" "0")
1578 (set (attr "prefix_data16")
1579 (if_then_else (eq_attr "mode" "DF")
1580 (const_string "1")
1581 (const_string "0")))
1582 (set_attr "athlon_decode" "vector")
1583 (set_attr "amdfam10_decode" "direct")])
1584
1585 (define_insn "*cmpfp_iu_387"
1586 [(set (reg:CCFPU FLAGS_REG)
1587 (compare:CCFPU (match_operand 0 "register_operand" "f")
1588 (match_operand 1 "register_operand" "f")))]
1589 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1590 && TARGET_CMOVE
1591 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1592 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1593 "* return output_fp_compare (insn, operands, 1, 1);"
1594 [(set_attr "type" "fcmp")
1595 (set (attr "mode")
1596 (cond [(match_operand:SF 1 "" "")
1597 (const_string "SF")
1598 (match_operand:DF 1 "" "")
1599 (const_string "DF")
1600 ]
1601 (const_string "XF")))
1602 (set_attr "athlon_decode" "vector")
1603 (set_attr "amdfam10_decode" "direct")])
1604 \f
1605 ;; Push/pop instructions.
1606
1607 (define_insn "*pushdi2_rex64"
1608 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1609 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1610 "TARGET_64BIT"
1611 "@
1612 push{q}\t%1
1613 #"
1614 [(set_attr "type" "push,multi")
1615 (set_attr "mode" "DI")])
1616
1617 ;; Convert impossible pushes of immediate to existing instructions.
1618 ;; First try to get scratch register and go through it. In case this
1619 ;; fails, push sign extended lower part first and then overwrite
1620 ;; upper part by 32bit move.
1621 (define_peephole2
1622 [(match_scratch:DI 2 "r")
1623 (set (match_operand:DI 0 "push_operand" "")
1624 (match_operand:DI 1 "immediate_operand" ""))]
1625 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1626 && !x86_64_immediate_operand (operands[1], DImode)"
1627 [(set (match_dup 2) (match_dup 1))
1628 (set (match_dup 0) (match_dup 2))])
1629
1630 ;; We need to define this as both peepholer and splitter for case
1631 ;; peephole2 pass is not run.
1632 ;; "&& 1" is needed to keep it from matching the previous pattern.
1633 (define_peephole2
1634 [(set (match_operand:DI 0 "push_operand" "")
1635 (match_operand:DI 1 "immediate_operand" ""))]
1636 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1637 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1638 [(set (match_dup 0) (match_dup 1))
1639 (set (match_dup 2) (match_dup 3))]
1640 {
1641 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1642
1643 operands[1] = gen_lowpart (DImode, operands[2]);
1644 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1645 GEN_INT (4)));
1646 })
1647
1648 (define_split
1649 [(set (match_operand:DI 0 "push_operand" "")
1650 (match_operand:DI 1 "immediate_operand" ""))]
1651 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1652 ? epilogue_completed : reload_completed)
1653 && !symbolic_operand (operands[1], DImode)
1654 && !x86_64_immediate_operand (operands[1], DImode)"
1655 [(set (match_dup 0) (match_dup 1))
1656 (set (match_dup 2) (match_dup 3))]
1657 {
1658 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1659
1660 operands[1] = gen_lowpart (DImode, operands[2]);
1661 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1662 GEN_INT (4)));
1663 })
1664
1665 (define_insn "*pushdi2"
1666 [(set (match_operand:DI 0 "push_operand" "=<")
1667 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1668 "!TARGET_64BIT"
1669 "#")
1670
1671 (define_split
1672 [(set (match_operand:DI 0 "push_operand" "")
1673 (match_operand:DI 1 "general_operand" ""))]
1674 "!TARGET_64BIT && reload_completed
1675 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1676 [(const_int 0)]
1677 "ix86_split_long_move (operands); DONE;")
1678
1679 (define_insn "*pushsi2"
1680 [(set (match_operand:SI 0 "push_operand" "=<")
1681 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1682 "!TARGET_64BIT"
1683 "push{l}\t%1"
1684 [(set_attr "type" "push")
1685 (set_attr "mode" "SI")])
1686
1687 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1688 ;; "push a byte/word". But actually we use pushl, which has the effect
1689 ;; of rounding the amount pushed up to a word.
1690
1691 ;; For TARGET_64BIT we always round up to 8 bytes.
1692 (define_insn "*push<mode>2_rex64"
1693 [(set (match_operand:SWI124 0 "push_operand" "=X")
1694 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1695 "TARGET_64BIT"
1696 "push{q}\t%q1"
1697 [(set_attr "type" "push")
1698 (set_attr "mode" "DI")])
1699
1700 (define_insn "*push<mode>2"
1701 [(set (match_operand:SWI12 0 "push_operand" "=X")
1702 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1703 "!TARGET_64BIT"
1704 "push{l}\t%k1"
1705 [(set_attr "type" "push")
1706 (set_attr "mode" "SI")])
1707
1708 (define_insn "*push<mode>2_prologue"
1709 [(set (match_operand:P 0 "push_operand" "=<")
1710 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1711 (clobber (mem:BLK (scratch)))]
1712 ""
1713 "push{<imodesuffix>}\t%1"
1714 [(set_attr "type" "push")
1715 (set_attr "mode" "<MODE>")])
1716
1717 (define_insn "*pop<mode>1"
1718 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1719 (match_operand:P 1 "pop_operand" ">"))]
1720 ""
1721 "pop{<imodesuffix>}\t%0"
1722 [(set_attr "type" "pop")
1723 (set_attr "mode" "<MODE>")])
1724
1725 (define_insn "*pop<mode>1_epilogue"
1726 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1727 (match_operand:P 1 "pop_operand" ">"))
1728 (clobber (mem:BLK (scratch)))]
1729 ""
1730 "pop{<imodesuffix>}\t%0"
1731 [(set_attr "type" "pop")
1732 (set_attr "mode" "<MODE>")])
1733 \f
1734 ;; Move instructions.
1735
1736 (define_expand "movoi"
1737 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1738 (match_operand:OI 1 "general_operand" ""))]
1739 "TARGET_AVX"
1740 "ix86_expand_move (OImode, operands); DONE;")
1741
1742 (define_expand "movti"
1743 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1744 (match_operand:TI 1 "nonimmediate_operand" ""))]
1745 "TARGET_64BIT || TARGET_SSE"
1746 {
1747 if (TARGET_64BIT)
1748 ix86_expand_move (TImode, operands);
1749 else if (push_operand (operands[0], TImode))
1750 ix86_expand_push (TImode, operands[1]);
1751 else
1752 ix86_expand_vector_move (TImode, operands);
1753 DONE;
1754 })
1755
1756 ;; This expands to what emit_move_complex would generate if we didn't
1757 ;; have a movti pattern. Having this avoids problems with reload on
1758 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1759 ;; to have around all the time.
1760 (define_expand "movcdi"
1761 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1762 (match_operand:CDI 1 "general_operand" ""))]
1763 ""
1764 {
1765 if (push_operand (operands[0], CDImode))
1766 emit_move_complex_push (CDImode, operands[0], operands[1]);
1767 else
1768 emit_move_complex_parts (operands[0], operands[1]);
1769 DONE;
1770 })
1771
1772 (define_expand "mov<mode>"
1773 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1774 (match_operand:SWI1248x 1 "general_operand" ""))]
1775 ""
1776 "ix86_expand_move (<MODE>mode, operands); DONE;")
1777
1778 (define_insn "*mov<mode>_xor"
1779 [(set (match_operand:SWI48 0 "register_operand" "=r")
1780 (match_operand:SWI48 1 "const0_operand" ""))
1781 (clobber (reg:CC FLAGS_REG))]
1782 "reload_completed"
1783 "xor{l}\t%k0, %k0"
1784 [(set_attr "type" "alu1")
1785 (set_attr "mode" "SI")
1786 (set_attr "length_immediate" "0")])
1787
1788 (define_insn "*mov<mode>_or"
1789 [(set (match_operand:SWI48 0 "register_operand" "=r")
1790 (match_operand:SWI48 1 "const_int_operand" ""))
1791 (clobber (reg:CC FLAGS_REG))]
1792 "reload_completed
1793 && operands[1] == constm1_rtx"
1794 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1795 [(set_attr "type" "alu1")
1796 (set_attr "mode" "<MODE>")
1797 (set_attr "length_immediate" "1")])
1798
1799 (define_insn "*movoi_internal_avx"
1800 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1801 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1802 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1803 {
1804 switch (which_alternative)
1805 {
1806 case 0:
1807 return "vxorps\t%0, %0, %0";
1808 case 1:
1809 case 2:
1810 if (misaligned_operand (operands[0], OImode)
1811 || misaligned_operand (operands[1], OImode))
1812 return "vmovdqu\t{%1, %0|%0, %1}";
1813 else
1814 return "vmovdqa\t{%1, %0|%0, %1}";
1815 default:
1816 gcc_unreachable ();
1817 }
1818 }
1819 [(set_attr "type" "sselog1,ssemov,ssemov")
1820 (set_attr "prefix" "vex")
1821 (set_attr "mode" "OI")])
1822
1823 (define_insn "*movti_internal_rex64"
1824 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1825 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1826 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1827 {
1828 switch (which_alternative)
1829 {
1830 case 0:
1831 case 1:
1832 return "#";
1833 case 2:
1834 if (get_attr_mode (insn) == MODE_V4SF)
1835 return "%vxorps\t%0, %d0";
1836 else
1837 return "%vpxor\t%0, %d0";
1838 case 3:
1839 case 4:
1840 /* TDmode values are passed as TImode on the stack. Moving them
1841 to stack may result in unaligned memory access. */
1842 if (misaligned_operand (operands[0], TImode)
1843 || misaligned_operand (operands[1], TImode))
1844 {
1845 if (get_attr_mode (insn) == MODE_V4SF)
1846 return "%vmovups\t{%1, %0|%0, %1}";
1847 else
1848 return "%vmovdqu\t{%1, %0|%0, %1}";
1849 }
1850 else
1851 {
1852 if (get_attr_mode (insn) == MODE_V4SF)
1853 return "%vmovaps\t{%1, %0|%0, %1}";
1854 else
1855 return "%vmovdqa\t{%1, %0|%0, %1}";
1856 }
1857 default:
1858 gcc_unreachable ();
1859 }
1860 }
1861 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1862 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1863 (set (attr "mode")
1864 (cond [(eq_attr "alternative" "2,3")
1865 (if_then_else
1866 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1867 (const_int 0))
1868 (const_string "V4SF")
1869 (const_string "TI"))
1870 (eq_attr "alternative" "4")
1871 (if_then_else
1872 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1873 (const_int 0))
1874 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1875 (const_int 0)))
1876 (const_string "V4SF")
1877 (const_string "TI"))]
1878 (const_string "DI")))])
1879
1880 (define_split
1881 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1882 (match_operand:TI 1 "general_operand" ""))]
1883 "reload_completed
1884 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1885 [(const_int 0)]
1886 "ix86_split_long_move (operands); DONE;")
1887
1888 (define_insn "*movti_internal_sse"
1889 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1890 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1891 "TARGET_SSE && !TARGET_64BIT
1892 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1893 {
1894 switch (which_alternative)
1895 {
1896 case 0:
1897 if (get_attr_mode (insn) == MODE_V4SF)
1898 return "%vxorps\t%0, %d0";
1899 else
1900 return "%vpxor\t%0, %d0";
1901 case 1:
1902 case 2:
1903 /* TDmode values are passed as TImode on the stack. Moving them
1904 to stack may result in unaligned memory access. */
1905 if (misaligned_operand (operands[0], TImode)
1906 || misaligned_operand (operands[1], TImode))
1907 {
1908 if (get_attr_mode (insn) == MODE_V4SF)
1909 return "%vmovups\t{%1, %0|%0, %1}";
1910 else
1911 return "%vmovdqu\t{%1, %0|%0, %1}";
1912 }
1913 else
1914 {
1915 if (get_attr_mode (insn) == MODE_V4SF)
1916 return "%vmovaps\t{%1, %0|%0, %1}";
1917 else
1918 return "%vmovdqa\t{%1, %0|%0, %1}";
1919 }
1920 default:
1921 gcc_unreachable ();
1922 }
1923 }
1924 [(set_attr "type" "sselog1,ssemov,ssemov")
1925 (set_attr "prefix" "maybe_vex")
1926 (set (attr "mode")
1927 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1928 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1929 (const_int 0)))
1930 (const_string "V4SF")
1931 (and (eq_attr "alternative" "2")
1932 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1933 (const_int 0)))
1934 (const_string "V4SF")]
1935 (const_string "TI")))])
1936
1937 (define_insn "*movdi_internal_rex64"
1938 [(set (match_operand:DI 0 "nonimmediate_operand"
1939 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1940 (match_operand:DI 1 "general_operand"
1941 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1942 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943 {
1944 switch (get_attr_type (insn))
1945 {
1946 case TYPE_SSECVT:
1947 if (SSE_REG_P (operands[0]))
1948 return "movq2dq\t{%1, %0|%0, %1}";
1949 else
1950 return "movdq2q\t{%1, %0|%0, %1}";
1951
1952 case TYPE_SSEMOV:
1953 if (TARGET_AVX)
1954 {
1955 if (get_attr_mode (insn) == MODE_TI)
1956 return "vmovdqa\t{%1, %0|%0, %1}";
1957 else
1958 return "vmovq\t{%1, %0|%0, %1}";
1959 }
1960
1961 if (get_attr_mode (insn) == MODE_TI)
1962 return "movdqa\t{%1, %0|%0, %1}";
1963 /* FALLTHRU */
1964
1965 case TYPE_MMXMOV:
1966 /* Moves from and into integer register is done using movd
1967 opcode with REX prefix. */
1968 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1969 return "movd\t{%1, %0|%0, %1}";
1970 return "movq\t{%1, %0|%0, %1}";
1971
1972 case TYPE_SSELOG1:
1973 return "%vpxor\t%0, %d0";
1974
1975 case TYPE_MMX:
1976 return "pxor\t%0, %0";
1977
1978 case TYPE_MULTI:
1979 return "#";
1980
1981 case TYPE_LEA:
1982 return "lea{q}\t{%a1, %0|%0, %a1}";
1983
1984 default:
1985 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1986 if (get_attr_mode (insn) == MODE_SI)
1987 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1988 else if (which_alternative == 2)
1989 return "movabs{q}\t{%1, %0|%0, %1}";
1990 else
1991 return "mov{q}\t{%1, %0|%0, %1}";
1992 }
1993 }
1994 [(set (attr "type")
1995 (cond [(eq_attr "alternative" "5")
1996 (const_string "mmx")
1997 (eq_attr "alternative" "6,7,8,9,10")
1998 (const_string "mmxmov")
1999 (eq_attr "alternative" "11")
2000 (const_string "sselog1")
2001 (eq_attr "alternative" "12,13,14,15,16")
2002 (const_string "ssemov")
2003 (eq_attr "alternative" "17,18")
2004 (const_string "ssecvt")
2005 (eq_attr "alternative" "4")
2006 (const_string "multi")
2007 (match_operand:DI 1 "pic_32bit_operand" "")
2008 (const_string "lea")
2009 ]
2010 (const_string "imov")))
2011 (set (attr "modrm")
2012 (if_then_else
2013 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2014 (const_string "0")
2015 (const_string "*")))
2016 (set (attr "length_immediate")
2017 (if_then_else
2018 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2019 (const_string "8")
2020 (const_string "*")))
2021 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2022 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2023 (set (attr "prefix")
2024 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2025 (const_string "maybe_vex")
2026 (const_string "orig")))
2027 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2028
2029 ;; Convert impossible stores of immediate to existing instructions.
2030 ;; First try to get scratch register and go through it. In case this
2031 ;; fails, move by 32bit parts.
2032 (define_peephole2
2033 [(match_scratch:DI 2 "r")
2034 (set (match_operand:DI 0 "memory_operand" "")
2035 (match_operand:DI 1 "immediate_operand" ""))]
2036 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2037 && !x86_64_immediate_operand (operands[1], DImode)"
2038 [(set (match_dup 2) (match_dup 1))
2039 (set (match_dup 0) (match_dup 2))])
2040
2041 ;; We need to define this as both peepholer and splitter for case
2042 ;; peephole2 pass is not run.
2043 ;; "&& 1" is needed to keep it from matching the previous pattern.
2044 (define_peephole2
2045 [(set (match_operand:DI 0 "memory_operand" "")
2046 (match_operand:DI 1 "immediate_operand" ""))]
2047 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2048 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2049 [(set (match_dup 2) (match_dup 3))
2050 (set (match_dup 4) (match_dup 5))]
2051 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2052
2053 (define_split
2054 [(set (match_operand:DI 0 "memory_operand" "")
2055 (match_operand:DI 1 "immediate_operand" ""))]
2056 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2057 ? epilogue_completed : reload_completed)
2058 && !symbolic_operand (operands[1], DImode)
2059 && !x86_64_immediate_operand (operands[1], DImode)"
2060 [(set (match_dup 2) (match_dup 3))
2061 (set (match_dup 4) (match_dup 5))]
2062 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2063
2064 (define_insn "*movdi_internal"
2065 [(set (match_operand:DI 0 "nonimmediate_operand"
2066 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2067 (match_operand:DI 1 "general_operand"
2068 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2069 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2070 "@
2071 #
2072 #
2073 pxor\t%0, %0
2074 movq\t{%1, %0|%0, %1}
2075 movq\t{%1, %0|%0, %1}
2076 %vpxor\t%0, %d0
2077 %vmovq\t{%1, %0|%0, %1}
2078 %vmovdqa\t{%1, %0|%0, %1}
2079 %vmovq\t{%1, %0|%0, %1}
2080 xorps\t%0, %0
2081 movlps\t{%1, %0|%0, %1}
2082 movaps\t{%1, %0|%0, %1}
2083 movlps\t{%1, %0|%0, %1}"
2084 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2085 (set (attr "prefix")
2086 (if_then_else (eq_attr "alternative" "5,6,7,8")
2087 (const_string "vex")
2088 (const_string "orig")))
2089 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2090
2091 (define_split
2092 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2093 (match_operand:DI 1 "general_operand" ""))]
2094 "!TARGET_64BIT && reload_completed
2095 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2096 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2097 [(const_int 0)]
2098 "ix86_split_long_move (operands); DONE;")
2099
2100 (define_insn "*movsi_internal"
2101 [(set (match_operand:SI 0 "nonimmediate_operand"
2102 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2103 (match_operand:SI 1 "general_operand"
2104 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2105 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2106 {
2107 switch (get_attr_type (insn))
2108 {
2109 case TYPE_SSELOG1:
2110 if (get_attr_mode (insn) == MODE_TI)
2111 return "%vpxor\t%0, %d0";
2112 return "%vxorps\t%0, %d0";
2113
2114 case TYPE_SSEMOV:
2115 switch (get_attr_mode (insn))
2116 {
2117 case MODE_TI:
2118 return "%vmovdqa\t{%1, %0|%0, %1}";
2119 case MODE_V4SF:
2120 return "%vmovaps\t{%1, %0|%0, %1}";
2121 case MODE_SI:
2122 return "%vmovd\t{%1, %0|%0, %1}";
2123 case MODE_SF:
2124 return "%vmovss\t{%1, %0|%0, %1}";
2125 default:
2126 gcc_unreachable ();
2127 }
2128
2129 case TYPE_MMX:
2130 return "pxor\t%0, %0";
2131
2132 case TYPE_MMXMOV:
2133 if (get_attr_mode (insn) == MODE_DI)
2134 return "movq\t{%1, %0|%0, %1}";
2135 return "movd\t{%1, %0|%0, %1}";
2136
2137 case TYPE_LEA:
2138 return "lea{l}\t{%a1, %0|%0, %a1}";
2139
2140 default:
2141 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2142 return "mov{l}\t{%1, %0|%0, %1}";
2143 }
2144 }
2145 [(set (attr "type")
2146 (cond [(eq_attr "alternative" "2")
2147 (const_string "mmx")
2148 (eq_attr "alternative" "3,4,5")
2149 (const_string "mmxmov")
2150 (eq_attr "alternative" "6")
2151 (const_string "sselog1")
2152 (eq_attr "alternative" "7,8,9,10,11")
2153 (const_string "ssemov")
2154 (match_operand:DI 1 "pic_32bit_operand" "")
2155 (const_string "lea")
2156 ]
2157 (const_string "imov")))
2158 (set (attr "prefix")
2159 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2160 (const_string "orig")
2161 (const_string "maybe_vex")))
2162 (set (attr "prefix_data16")
2163 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2164 (const_string "1")
2165 (const_string "*")))
2166 (set (attr "mode")
2167 (cond [(eq_attr "alternative" "2,3")
2168 (const_string "DI")
2169 (eq_attr "alternative" "6,7")
2170 (if_then_else
2171 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2172 (const_string "V4SF")
2173 (const_string "TI"))
2174 (and (eq_attr "alternative" "8,9,10,11")
2175 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2176 (const_string "SF")
2177 ]
2178 (const_string "SI")))])
2179
2180 (define_insn "*movhi_internal"
2181 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2182 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2183 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2184 {
2185 switch (get_attr_type (insn))
2186 {
2187 case TYPE_IMOVX:
2188 /* movzwl is faster than movw on p2 due to partial word stalls,
2189 though not as fast as an aligned movl. */
2190 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2191 default:
2192 if (get_attr_mode (insn) == MODE_SI)
2193 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2194 else
2195 return "mov{w}\t{%1, %0|%0, %1}";
2196 }
2197 }
2198 [(set (attr "type")
2199 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2200 (const_int 0))
2201 (const_string "imov")
2202 (and (eq_attr "alternative" "0")
2203 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2204 (const_int 0))
2205 (eq (symbol_ref "TARGET_HIMODE_MATH")
2206 (const_int 0))))
2207 (const_string "imov")
2208 (and (eq_attr "alternative" "1,2")
2209 (match_operand:HI 1 "aligned_operand" ""))
2210 (const_string "imov")
2211 (and (ne (symbol_ref "TARGET_MOVX")
2212 (const_int 0))
2213 (eq_attr "alternative" "0,2"))
2214 (const_string "imovx")
2215 ]
2216 (const_string "imov")))
2217 (set (attr "mode")
2218 (cond [(eq_attr "type" "imovx")
2219 (const_string "SI")
2220 (and (eq_attr "alternative" "1,2")
2221 (match_operand:HI 1 "aligned_operand" ""))
2222 (const_string "SI")
2223 (and (eq_attr "alternative" "0")
2224 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2225 (const_int 0))
2226 (eq (symbol_ref "TARGET_HIMODE_MATH")
2227 (const_int 0))))
2228 (const_string "SI")
2229 ]
2230 (const_string "HI")))])
2231
2232 ;; Situation is quite tricky about when to choose full sized (SImode) move
2233 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2234 ;; partial register dependency machines (such as AMD Athlon), where QImode
2235 ;; moves issue extra dependency and for partial register stalls machines
2236 ;; that don't use QImode patterns (and QImode move cause stall on the next
2237 ;; instruction).
2238 ;;
2239 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2240 ;; register stall machines with, where we use QImode instructions, since
2241 ;; partial register stall can be caused there. Then we use movzx.
2242 (define_insn "*movqi_internal"
2243 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2244 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2245 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2246 {
2247 switch (get_attr_type (insn))
2248 {
2249 case TYPE_IMOVX:
2250 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2251 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2252 default:
2253 if (get_attr_mode (insn) == MODE_SI)
2254 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2255 else
2256 return "mov{b}\t{%1, %0|%0, %1}";
2257 }
2258 }
2259 [(set (attr "type")
2260 (cond [(and (eq_attr "alternative" "5")
2261 (not (match_operand:QI 1 "aligned_operand" "")))
2262 (const_string "imovx")
2263 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2264 (const_int 0))
2265 (const_string "imov")
2266 (and (eq_attr "alternative" "3")
2267 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2268 (const_int 0))
2269 (eq (symbol_ref "TARGET_QIMODE_MATH")
2270 (const_int 0))))
2271 (const_string "imov")
2272 (eq_attr "alternative" "3,5")
2273 (const_string "imovx")
2274 (and (ne (symbol_ref "TARGET_MOVX")
2275 (const_int 0))
2276 (eq_attr "alternative" "2"))
2277 (const_string "imovx")
2278 ]
2279 (const_string "imov")))
2280 (set (attr "mode")
2281 (cond [(eq_attr "alternative" "3,4,5")
2282 (const_string "SI")
2283 (eq_attr "alternative" "6")
2284 (const_string "QI")
2285 (eq_attr "type" "imovx")
2286 (const_string "SI")
2287 (and (eq_attr "type" "imov")
2288 (and (eq_attr "alternative" "0,1")
2289 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2290 (const_int 0))
2291 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2292 (const_int 0))
2293 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2294 (const_int 0))))))
2295 (const_string "SI")
2296 ;; Avoid partial register stalls when not using QImode arithmetic
2297 (and (eq_attr "type" "imov")
2298 (and (eq_attr "alternative" "0,1")
2299 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2300 (const_int 0))
2301 (eq (symbol_ref "TARGET_QIMODE_MATH")
2302 (const_int 0)))))
2303 (const_string "SI")
2304 ]
2305 (const_string "QI")))])
2306
2307 ;; Stores and loads of ax to arbitrary constant address.
2308 ;; We fake an second form of instruction to force reload to load address
2309 ;; into register when rax is not available
2310 (define_insn "*movabs<mode>_1"
2311 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2312 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2313 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2314 "@
2315 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2316 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2317 [(set_attr "type" "imov")
2318 (set_attr "modrm" "0,*")
2319 (set_attr "length_address" "8,0")
2320 (set_attr "length_immediate" "0,*")
2321 (set_attr "memory" "store")
2322 (set_attr "mode" "<MODE>")])
2323
2324 (define_insn "*movabs<mode>_2"
2325 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2326 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2327 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2328 "@
2329 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2330 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2331 [(set_attr "type" "imov")
2332 (set_attr "modrm" "0,*")
2333 (set_attr "length_address" "8,0")
2334 (set_attr "length_immediate" "0")
2335 (set_attr "memory" "load")
2336 (set_attr "mode" "<MODE>")])
2337
2338 (define_insn "*swap<mode>"
2339 [(set (match_operand:SWI48 0 "register_operand" "+r")
2340 (match_operand:SWI48 1 "register_operand" "+r"))
2341 (set (match_dup 1)
2342 (match_dup 0))]
2343 ""
2344 "xchg{<imodesuffix>}\t%1, %0"
2345 [(set_attr "type" "imov")
2346 (set_attr "mode" "<MODE>")
2347 (set_attr "pent_pair" "np")
2348 (set_attr "athlon_decode" "vector")
2349 (set_attr "amdfam10_decode" "double")])
2350
2351 (define_insn "*swap<mode>_1"
2352 [(set (match_operand:SWI12 0 "register_operand" "+r")
2353 (match_operand:SWI12 1 "register_operand" "+r"))
2354 (set (match_dup 1)
2355 (match_dup 0))]
2356 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2357 "xchg{l}\t%k1, %k0"
2358 [(set_attr "type" "imov")
2359 (set_attr "mode" "SI")
2360 (set_attr "pent_pair" "np")
2361 (set_attr "athlon_decode" "vector")
2362 (set_attr "amdfam10_decode" "double")])
2363
2364 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2365 ;; is disabled for AMDFAM10
2366 (define_insn "*swap<mode>_2"
2367 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2368 (match_operand:SWI12 1 "register_operand" "+<r>"))
2369 (set (match_dup 1)
2370 (match_dup 0))]
2371 "TARGET_PARTIAL_REG_STALL"
2372 "xchg{<imodesuffix>}\t%1, %0"
2373 [(set_attr "type" "imov")
2374 (set_attr "mode" "<MODE>")
2375 (set_attr "pent_pair" "np")
2376 (set_attr "athlon_decode" "vector")])
2377
2378 (define_expand "movstrict<mode>"
2379 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2380 (match_operand:SWI12 1 "general_operand" ""))]
2381 ""
2382 {
2383 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2384 FAIL;
2385 /* Don't generate memory->memory moves, go through a register */
2386 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2387 operands[1] = force_reg (<MODE>mode, operands[1]);
2388 })
2389
2390 (define_insn "*movstrict<mode>_1"
2391 [(set (strict_low_part
2392 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2393 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2394 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2395 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2396 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2397 [(set_attr "type" "imov")
2398 (set_attr "mode" "<MODE>")])
2399
2400 (define_insn "*movstrict<mode>_xor"
2401 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2402 (match_operand:SWI12 1 "const0_operand" ""))
2403 (clobber (reg:CC FLAGS_REG))]
2404 "reload_completed"
2405 "xor{<imodesuffix>}\t%0, %0"
2406 [(set_attr "type" "alu1")
2407 (set_attr "mode" "<MODE>")
2408 (set_attr "length_immediate" "0")])
2409
2410 (define_insn "*mov<mode>_extv_1"
2411 [(set (match_operand:SWI24 0 "register_operand" "=R")
2412 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2413 (const_int 8)
2414 (const_int 8)))]
2415 ""
2416 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2417 [(set_attr "type" "imovx")
2418 (set_attr "mode" "SI")])
2419
2420 (define_insn "*movqi_extv_1_rex64"
2421 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2422 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2423 (const_int 8)
2424 (const_int 8)))]
2425 "TARGET_64BIT"
2426 {
2427 switch (get_attr_type (insn))
2428 {
2429 case TYPE_IMOVX:
2430 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2431 default:
2432 return "mov{b}\t{%h1, %0|%0, %h1}";
2433 }
2434 }
2435 [(set (attr "type")
2436 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2437 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2438 (ne (symbol_ref "TARGET_MOVX")
2439 (const_int 0))))
2440 (const_string "imovx")
2441 (const_string "imov")))
2442 (set (attr "mode")
2443 (if_then_else (eq_attr "type" "imovx")
2444 (const_string "SI")
2445 (const_string "QI")))])
2446
2447 (define_insn "*movqi_extv_1"
2448 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2449 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2450 (const_int 8)
2451 (const_int 8)))]
2452 "!TARGET_64BIT"
2453 {
2454 switch (get_attr_type (insn))
2455 {
2456 case TYPE_IMOVX:
2457 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2458 default:
2459 return "mov{b}\t{%h1, %0|%0, %h1}";
2460 }
2461 }
2462 [(set (attr "type")
2463 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2464 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2465 (ne (symbol_ref "TARGET_MOVX")
2466 (const_int 0))))
2467 (const_string "imovx")
2468 (const_string "imov")))
2469 (set (attr "mode")
2470 (if_then_else (eq_attr "type" "imovx")
2471 (const_string "SI")
2472 (const_string "QI")))])
2473
2474 (define_insn "*mov<mode>_extzv_1"
2475 [(set (match_operand:SWI48 0 "register_operand" "=R")
2476 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2477 (const_int 8)
2478 (const_int 8)))]
2479 ""
2480 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2481 [(set_attr "type" "imovx")
2482 (set_attr "mode" "SI")])
2483
2484 (define_insn "*movqi_extzv_2_rex64"
2485 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2486 (subreg:QI
2487 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2488 (const_int 8)
2489 (const_int 8)) 0))]
2490 "TARGET_64BIT"
2491 {
2492 switch (get_attr_type (insn))
2493 {
2494 case TYPE_IMOVX:
2495 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2496 default:
2497 return "mov{b}\t{%h1, %0|%0, %h1}";
2498 }
2499 }
2500 [(set (attr "type")
2501 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2502 (ne (symbol_ref "TARGET_MOVX")
2503 (const_int 0)))
2504 (const_string "imovx")
2505 (const_string "imov")))
2506 (set (attr "mode")
2507 (if_then_else (eq_attr "type" "imovx")
2508 (const_string "SI")
2509 (const_string "QI")))])
2510
2511 (define_insn "*movqi_extzv_2"
2512 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2513 (subreg:QI
2514 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2515 (const_int 8)
2516 (const_int 8)) 0))]
2517 "!TARGET_64BIT"
2518 {
2519 switch (get_attr_type (insn))
2520 {
2521 case TYPE_IMOVX:
2522 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2523 default:
2524 return "mov{b}\t{%h1, %0|%0, %h1}";
2525 }
2526 }
2527 [(set (attr "type")
2528 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2529 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2530 (ne (symbol_ref "TARGET_MOVX")
2531 (const_int 0))))
2532 (const_string "imovx")
2533 (const_string "imov")))
2534 (set (attr "mode")
2535 (if_then_else (eq_attr "type" "imovx")
2536 (const_string "SI")
2537 (const_string "QI")))])
2538
2539 (define_expand "mov<mode>_insv_1"
2540 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2541 (const_int 8)
2542 (const_int 8))
2543 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2544
2545 (define_insn "*mov<mode>_insv_1_rex64"
2546 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2547 (const_int 8)
2548 (const_int 8))
2549 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2550 "TARGET_64BIT"
2551 "mov{b}\t{%b1, %h0|%h0, %b1}"
2552 [(set_attr "type" "imov")
2553 (set_attr "mode" "QI")])
2554
2555 (define_insn "*movsi_insv_1"
2556 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2557 (const_int 8)
2558 (const_int 8))
2559 (match_operand:SI 1 "general_operand" "Qmn"))]
2560 "!TARGET_64BIT"
2561 "mov{b}\t{%b1, %h0|%h0, %b1}"
2562 [(set_attr "type" "imov")
2563 (set_attr "mode" "QI")])
2564
2565 (define_insn "*movqi_insv_2"
2566 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2567 (const_int 8)
2568 (const_int 8))
2569 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2570 (const_int 8)))]
2571 ""
2572 "mov{b}\t{%h1, %h0|%h0, %h1}"
2573 [(set_attr "type" "imov")
2574 (set_attr "mode" "QI")])
2575 \f
2576 ;; Floating point push instructions.
2577
2578 (define_insn "*pushtf"
2579 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2580 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2581 "TARGET_SSE2"
2582 {
2583 /* This insn should be already split before reg-stack. */
2584 gcc_unreachable ();
2585 }
2586 [(set_attr "type" "multi")
2587 (set_attr "unit" "sse,*,*")
2588 (set_attr "mode" "TF,SI,SI")])
2589
2590 (define_split
2591 [(set (match_operand:TF 0 "push_operand" "")
2592 (match_operand:TF 1 "sse_reg_operand" ""))]
2593 "TARGET_SSE2 && reload_completed"
2594 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2595 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2596
2597 (define_split
2598 [(set (match_operand:TF 0 "push_operand" "")
2599 (match_operand:TF 1 "general_operand" ""))]
2600 "TARGET_SSE2 && reload_completed
2601 && !SSE_REG_P (operands[1])"
2602 [(const_int 0)]
2603 "ix86_split_long_move (operands); DONE;")
2604
2605 (define_insn "*pushxf"
2606 [(set (match_operand:XF 0 "push_operand" "=<,<")
2607 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2608 "optimize_function_for_speed_p (cfun)"
2609 {
2610 /* This insn should be already split before reg-stack. */
2611 gcc_unreachable ();
2612 }
2613 [(set_attr "type" "multi")
2614 (set_attr "unit" "i387,*")
2615 (set_attr "mode" "XF,SI")])
2616
2617 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2618 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2619 ;; Pushing using integer instructions is longer except for constants
2620 ;; and direct memory references (assuming that any given constant is pushed
2621 ;; only once, but this ought to be handled elsewhere).
2622
2623 (define_insn "*pushxf_nointeger"
2624 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2625 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2626 "optimize_function_for_size_p (cfun)"
2627 {
2628 /* This insn should be already split before reg-stack. */
2629 gcc_unreachable ();
2630 }
2631 [(set_attr "type" "multi")
2632 (set_attr "unit" "i387,*,*")
2633 (set_attr "mode" "XF,SI,SI")])
2634
2635 (define_split
2636 [(set (match_operand:XF 0 "push_operand" "")
2637 (match_operand:XF 1 "fp_register_operand" ""))]
2638 "reload_completed"
2639 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2640 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2641 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2642
2643 (define_split
2644 [(set (match_operand:XF 0 "push_operand" "")
2645 (match_operand:XF 1 "general_operand" ""))]
2646 "reload_completed
2647 && !FP_REG_P (operands[1])"
2648 [(const_int 0)]
2649 "ix86_split_long_move (operands); DONE;")
2650
2651 (define_insn "*pushdf"
2652 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2653 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2654 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2655 {
2656 /* This insn should be already split before reg-stack. */
2657 gcc_unreachable ();
2658 }
2659 [(set_attr "type" "multi")
2660 (set_attr "unit" "i387,*,*")
2661 (set_attr "mode" "DF,SI,DF")])
2662
2663 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2664 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2665 ;; On the average, pushdf using integers can be still shorter. Allow this
2666 ;; pattern for optimize_size too.
2667
2668 (define_insn "*pushdf_nointeger"
2669 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2670 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2671 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2672 {
2673 /* This insn should be already split before reg-stack. */
2674 gcc_unreachable ();
2675 }
2676 [(set_attr "type" "multi")
2677 (set_attr "unit" "i387,*,*,*")
2678 (set_attr "mode" "DF,SI,SI,DF")])
2679
2680 ;; %%% Kill this when call knows how to work this out.
2681 (define_split
2682 [(set (match_operand:DF 0 "push_operand" "")
2683 (match_operand:DF 1 "any_fp_register_operand" ""))]
2684 "reload_completed"
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2686 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2687
2688 (define_split
2689 [(set (match_operand:DF 0 "push_operand" "")
2690 (match_operand:DF 1 "general_operand" ""))]
2691 "reload_completed
2692 && !ANY_FP_REG_P (operands[1])"
2693 [(const_int 0)]
2694 "ix86_split_long_move (operands); DONE;")
2695
2696 (define_insn "*pushsf_rex64"
2697 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2698 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2699 "TARGET_64BIT"
2700 {
2701 /* Anything else should be already split before reg-stack. */
2702 gcc_assert (which_alternative == 1);
2703 return "push{q}\t%q1";
2704 }
2705 [(set_attr "type" "multi,push,multi")
2706 (set_attr "unit" "i387,*,*")
2707 (set_attr "mode" "SF,DI,SF")])
2708
2709 (define_insn "*pushsf"
2710 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2711 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2712 "!TARGET_64BIT"
2713 {
2714 /* Anything else should be already split before reg-stack. */
2715 gcc_assert (which_alternative == 1);
2716 return "push{l}\t%1";
2717 }
2718 [(set_attr "type" "multi,push,multi")
2719 (set_attr "unit" "i387,*,*")
2720 (set_attr "mode" "SF,SI,SF")])
2721
2722 (define_split
2723 [(set (match_operand:SF 0 "push_operand" "")
2724 (match_operand:SF 1 "memory_operand" ""))]
2725 "reload_completed
2726 && MEM_P (operands[1])
2727 && (operands[2] = find_constant_src (insn))"
2728 [(set (match_dup 0)
2729 (match_dup 2))])
2730
2731 ;; %%% Kill this when call knows how to work this out.
2732 (define_split
2733 [(set (match_operand:SF 0 "push_operand" "")
2734 (match_operand:SF 1 "any_fp_register_operand" ""))]
2735 "reload_completed"
2736 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2737 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2738 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2739 \f
2740 ;; Floating point move instructions.
2741
2742 (define_expand "movtf"
2743 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2744 (match_operand:TF 1 "nonimmediate_operand" ""))]
2745 "TARGET_SSE2"
2746 {
2747 ix86_expand_move (TFmode, operands);
2748 DONE;
2749 })
2750
2751 (define_expand "mov<mode>"
2752 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2753 (match_operand:X87MODEF 1 "general_operand" ""))]
2754 ""
2755 "ix86_expand_move (<MODE>mode, operands); DONE;")
2756
2757 (define_insn "*movtf_internal"
2758 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2759 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2760 "TARGET_SSE2
2761 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2762 {
2763 switch (which_alternative)
2764 {
2765 case 0:
2766 case 1:
2767 if (get_attr_mode (insn) == MODE_V4SF)
2768 return "%vmovaps\t{%1, %0|%0, %1}";
2769 else
2770 return "%vmovdqa\t{%1, %0|%0, %1}";
2771 case 2:
2772 if (get_attr_mode (insn) == MODE_V4SF)
2773 return "%vxorps\t%0, %d0";
2774 else
2775 return "%vpxor\t%0, %d0";
2776 case 3:
2777 case 4:
2778 return "#";
2779 default:
2780 gcc_unreachable ();
2781 }
2782 }
2783 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2784 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2785 (set (attr "mode")
2786 (cond [(eq_attr "alternative" "0,2")
2787 (if_then_else
2788 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2789 (const_int 0))
2790 (const_string "V4SF")
2791 (const_string "TI"))
2792 (eq_attr "alternative" "1")
2793 (if_then_else
2794 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2795 (const_int 0))
2796 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2797 (const_int 0)))
2798 (const_string "V4SF")
2799 (const_string "TI"))]
2800 (const_string "DI")))])
2801
2802 (define_split
2803 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2804 (match_operand:TF 1 "general_operand" ""))]
2805 "reload_completed
2806 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2807 [(const_int 0)]
2808 "ix86_split_long_move (operands); DONE;")
2809
2810 (define_insn "*movxf_internal"
2811 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2813 "optimize_function_for_speed_p (cfun)
2814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2815 && (reload_in_progress || reload_completed
2816 || GET_CODE (operands[1]) != CONST_DOUBLE
2817 || memory_operand (operands[0], XFmode))"
2818 {
2819 switch (which_alternative)
2820 {
2821 case 0:
2822 case 1:
2823 return output_387_reg_move (insn, operands);
2824
2825 case 2:
2826 return standard_80387_constant_opcode (operands[1]);
2827
2828 case 3: case 4:
2829 return "#";
2830
2831 default:
2832 gcc_unreachable ();
2833 }
2834 }
2835 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2836 (set_attr "mode" "XF,XF,XF,SI,SI")])
2837
2838 ;; Do not use integer registers when optimizing for size
2839 (define_insn "*movxf_internal_nointeger"
2840 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2841 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2842 "optimize_function_for_size_p (cfun)
2843 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2844 && (reload_in_progress || reload_completed
2845 || standard_80387_constant_p (operands[1])
2846 || GET_CODE (operands[1]) != CONST_DOUBLE
2847 || memory_operand (operands[0], XFmode))"
2848 {
2849 switch (which_alternative)
2850 {
2851 case 0:
2852 case 1:
2853 return output_387_reg_move (insn, operands);
2854
2855 case 2:
2856 return standard_80387_constant_opcode (operands[1]);
2857
2858 case 3: case 4:
2859 return "#";
2860 default:
2861 gcc_unreachable ();
2862 }
2863 }
2864 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2865 (set_attr "mode" "XF,XF,XF,SI,SI")])
2866
2867 (define_split
2868 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2869 (match_operand:XF 1 "general_operand" ""))]
2870 "reload_completed
2871 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2872 && ! (FP_REG_P (operands[0]) ||
2873 (GET_CODE (operands[0]) == SUBREG
2874 && FP_REG_P (SUBREG_REG (operands[0]))))
2875 && ! (FP_REG_P (operands[1]) ||
2876 (GET_CODE (operands[1]) == SUBREG
2877 && FP_REG_P (SUBREG_REG (operands[1]))))"
2878 [(const_int 0)]
2879 "ix86_split_long_move (operands); DONE;")
2880
2881 (define_insn "*movdf_internal_rex64"
2882 [(set (match_operand:DF 0 "nonimmediate_operand"
2883 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2884 (match_operand:DF 1 "general_operand"
2885 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2886 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2887 && (reload_in_progress || reload_completed
2888 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2890 && optimize_function_for_size_p (cfun)
2891 && standard_80387_constant_p (operands[1]))
2892 || GET_CODE (operands[1]) != CONST_DOUBLE
2893 || memory_operand (operands[0], DFmode))"
2894 {
2895 switch (which_alternative)
2896 {
2897 case 0:
2898 case 1:
2899 return output_387_reg_move (insn, operands);
2900
2901 case 2:
2902 return standard_80387_constant_opcode (operands[1]);
2903
2904 case 3:
2905 case 4:
2906 return "#";
2907
2908 case 5:
2909 switch (get_attr_mode (insn))
2910 {
2911 case MODE_V4SF:
2912 return "%vxorps\t%0, %d0";
2913 case MODE_V2DF:
2914 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2915 return "%vxorps\t%0, %d0";
2916 else
2917 return "%vxorpd\t%0, %d0";
2918 case MODE_TI:
2919 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2920 return "%vxorps\t%0, %d0";
2921 else
2922 return "%vpxor\t%0, %d0";
2923 default:
2924 gcc_unreachable ();
2925 }
2926 case 6:
2927 case 7:
2928 case 8:
2929 switch (get_attr_mode (insn))
2930 {
2931 case MODE_V4SF:
2932 return "%vmovaps\t{%1, %0|%0, %1}";
2933 case MODE_V2DF:
2934 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2935 return "%vmovaps\t{%1, %0|%0, %1}";
2936 else
2937 return "%vmovapd\t{%1, %0|%0, %1}";
2938 case MODE_TI:
2939 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2940 return "%vmovaps\t{%1, %0|%0, %1}";
2941 else
2942 return "%vmovdqa\t{%1, %0|%0, %1}";
2943 case MODE_DI:
2944 return "%vmovq\t{%1, %0|%0, %1}";
2945 case MODE_DF:
2946 if (TARGET_AVX)
2947 {
2948 if (REG_P (operands[0]) && REG_P (operands[1]))
2949 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2950 else
2951 return "vmovsd\t{%1, %0|%0, %1}";
2952 }
2953 else
2954 return "movsd\t{%1, %0|%0, %1}";
2955 case MODE_V1DF:
2956 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2957 case MODE_V2SF:
2958 return "%vmovlps\t{%1, %d0|%d0, %1}";
2959 default:
2960 gcc_unreachable ();
2961 }
2962
2963 case 9:
2964 case 10:
2965 return "%vmovd\t{%1, %0|%0, %1}";
2966
2967 default:
2968 gcc_unreachable();
2969 }
2970 }
2971 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2972 (set (attr "prefix")
2973 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2974 (const_string "orig")
2975 (const_string "maybe_vex")))
2976 (set (attr "prefix_data16")
2977 (if_then_else (eq_attr "mode" "V1DF")
2978 (const_string "1")
2979 (const_string "*")))
2980 (set (attr "mode")
2981 (cond [(eq_attr "alternative" "0,1,2")
2982 (const_string "DF")
2983 (eq_attr "alternative" "3,4,9,10")
2984 (const_string "DI")
2985
2986 /* For SSE1, we have many fewer alternatives. */
2987 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2988 (cond [(eq_attr "alternative" "5,6")
2989 (const_string "V4SF")
2990 ]
2991 (const_string "V2SF"))
2992
2993 /* xorps is one byte shorter. */
2994 (eq_attr "alternative" "5")
2995 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2996 (const_int 0))
2997 (const_string "V4SF")
2998 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2999 (const_int 0))
3000 (const_string "TI")
3001 ]
3002 (const_string "V2DF"))
3003
3004 /* For architectures resolving dependencies on
3005 whole SSE registers use APD move to break dependency
3006 chains, otherwise use short move to avoid extra work.
3007
3008 movaps encodes one byte shorter. */
3009 (eq_attr "alternative" "6")
3010 (cond
3011 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3012 (const_int 0))
3013 (const_string "V4SF")
3014 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3015 (const_int 0))
3016 (const_string "V2DF")
3017 ]
3018 (const_string "DF"))
3019 /* For architectures resolving dependencies on register
3020 parts we may avoid extra work to zero out upper part
3021 of register. */
3022 (eq_attr "alternative" "7")
3023 (if_then_else
3024 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3025 (const_int 0))
3026 (const_string "V1DF")
3027 (const_string "DF"))
3028 ]
3029 (const_string "DF")))])
3030
3031 (define_insn "*movdf_internal"
3032 [(set (match_operand:DF 0 "nonimmediate_operand"
3033 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3034 (match_operand:DF 1 "general_operand"
3035 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3036 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3037 && optimize_function_for_speed_p (cfun)
3038 && TARGET_INTEGER_DFMODE_MOVES
3039 && (reload_in_progress || reload_completed
3040 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3041 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3042 && optimize_function_for_size_p (cfun)
3043 && standard_80387_constant_p (operands[1]))
3044 || GET_CODE (operands[1]) != CONST_DOUBLE
3045 || memory_operand (operands[0], DFmode))"
3046 {
3047 switch (which_alternative)
3048 {
3049 case 0:
3050 case 1:
3051 return output_387_reg_move (insn, operands);
3052
3053 case 2:
3054 return standard_80387_constant_opcode (operands[1]);
3055
3056 case 3:
3057 case 4:
3058 return "#";
3059
3060 case 5:
3061 switch (get_attr_mode (insn))
3062 {
3063 case MODE_V4SF:
3064 return "xorps\t%0, %0";
3065 case MODE_V2DF:
3066 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3067 return "xorps\t%0, %0";
3068 else
3069 return "xorpd\t%0, %0";
3070 case MODE_TI:
3071 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3072 return "xorps\t%0, %0";
3073 else
3074 return "pxor\t%0, %0";
3075 default:
3076 gcc_unreachable ();
3077 }
3078 case 6:
3079 case 7:
3080 case 8:
3081 switch (get_attr_mode (insn))
3082 {
3083 case MODE_V4SF:
3084 return "movaps\t{%1, %0|%0, %1}";
3085 case MODE_V2DF:
3086 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3087 return "movaps\t{%1, %0|%0, %1}";
3088 else
3089 return "movapd\t{%1, %0|%0, %1}";
3090 case MODE_TI:
3091 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3092 return "movaps\t{%1, %0|%0, %1}";
3093 else
3094 return "movdqa\t{%1, %0|%0, %1}";
3095 case MODE_DI:
3096 return "movq\t{%1, %0|%0, %1}";
3097 case MODE_DF:
3098 return "movsd\t{%1, %0|%0, %1}";
3099 case MODE_V1DF:
3100 return "movlpd\t{%1, %0|%0, %1}";
3101 case MODE_V2SF:
3102 return "movlps\t{%1, %0|%0, %1}";
3103 default:
3104 gcc_unreachable ();
3105 }
3106
3107 default:
3108 gcc_unreachable();
3109 }
3110 }
3111 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3112 (set (attr "prefix_data16")
3113 (if_then_else (eq_attr "mode" "V1DF")
3114 (const_string "1")
3115 (const_string "*")))
3116 (set (attr "mode")
3117 (cond [(eq_attr "alternative" "0,1,2")
3118 (const_string "DF")
3119 (eq_attr "alternative" "3,4")
3120 (const_string "SI")
3121
3122 /* For SSE1, we have many fewer alternatives. */
3123 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3124 (cond [(eq_attr "alternative" "5,6")
3125 (const_string "V4SF")
3126 ]
3127 (const_string "V2SF"))
3128
3129 /* xorps is one byte shorter. */
3130 (eq_attr "alternative" "5")
3131 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3132 (const_int 0))
3133 (const_string "V4SF")
3134 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3135 (const_int 0))
3136 (const_string "TI")
3137 ]
3138 (const_string "V2DF"))
3139
3140 /* For architectures resolving dependencies on
3141 whole SSE registers use APD move to break dependency
3142 chains, otherwise use short move to avoid extra work.
3143
3144 movaps encodes one byte shorter. */
3145 (eq_attr "alternative" "6")
3146 (cond
3147 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3148 (const_int 0))
3149 (const_string "V4SF")
3150 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3151 (const_int 0))
3152 (const_string "V2DF")
3153 ]
3154 (const_string "DF"))
3155 /* For architectures resolving dependencies on register
3156 parts we may avoid extra work to zero out upper part
3157 of register. */
3158 (eq_attr "alternative" "7")
3159 (if_then_else
3160 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3161 (const_int 0))
3162 (const_string "V1DF")
3163 (const_string "DF"))
3164 ]
3165 (const_string "DF")))])
3166
3167 ;; Moving is usually shorter when only FP registers are used. This separate
3168 ;; movdf pattern avoids the use of integer registers for FP operations
3169 ;; when optimizing for size.
3170
3171 (define_insn "*movdf_internal_nointeger"
3172 [(set (match_operand:DF 0 "nonimmediate_operand"
3173 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3174 (match_operand:DF 1 "general_operand"
3175 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3176 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3177 && ((optimize_function_for_size_p (cfun)
3178 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3179 && (reload_in_progress || reload_completed
3180 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3181 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3182 && optimize_function_for_size_p (cfun)
3183 && !memory_operand (operands[0], DFmode)
3184 && standard_80387_constant_p (operands[1]))
3185 || GET_CODE (operands[1]) != CONST_DOUBLE
3186 || ((optimize_function_for_size_p (cfun)
3187 || !TARGET_MEMORY_MISMATCH_STALL
3188 || reload_in_progress || reload_completed)
3189 && memory_operand (operands[0], DFmode)))"
3190 {
3191 switch (which_alternative)
3192 {
3193 case 0:
3194 case 1:
3195 return output_387_reg_move (insn, operands);
3196
3197 case 2:
3198 return standard_80387_constant_opcode (operands[1]);
3199
3200 case 3:
3201 case 4:
3202 return "#";
3203
3204 case 5:
3205 switch (get_attr_mode (insn))
3206 {
3207 case MODE_V4SF:
3208 return "%vxorps\t%0, %d0";
3209 case MODE_V2DF:
3210 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3211 return "%vxorps\t%0, %d0";
3212 else
3213 return "%vxorpd\t%0, %d0";
3214 case MODE_TI:
3215 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3216 return "%vxorps\t%0, %d0";
3217 else
3218 return "%vpxor\t%0, %d0";
3219 default:
3220 gcc_unreachable ();
3221 }
3222 case 6:
3223 case 7:
3224 case 8:
3225 switch (get_attr_mode (insn))
3226 {
3227 case MODE_V4SF:
3228 return "%vmovaps\t{%1, %0|%0, %1}";
3229 case MODE_V2DF:
3230 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3231 return "%vmovaps\t{%1, %0|%0, %1}";
3232 else
3233 return "%vmovapd\t{%1, %0|%0, %1}";
3234 case MODE_TI:
3235 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3236 return "%vmovaps\t{%1, %0|%0, %1}";
3237 else
3238 return "%vmovdqa\t{%1, %0|%0, %1}";
3239 case MODE_DI:
3240 return "%vmovq\t{%1, %0|%0, %1}";
3241 case MODE_DF:
3242 if (TARGET_AVX)
3243 {
3244 if (REG_P (operands[0]) && REG_P (operands[1]))
3245 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3246 else
3247 return "vmovsd\t{%1, %0|%0, %1}";
3248 }
3249 else
3250 return "movsd\t{%1, %0|%0, %1}";
3251 case MODE_V1DF:
3252 if (TARGET_AVX)
3253 {
3254 if (REG_P (operands[0]))
3255 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3256 else
3257 return "vmovlpd\t{%1, %0|%0, %1}";
3258 }
3259 else
3260 return "movlpd\t{%1, %0|%0, %1}";
3261 case MODE_V2SF:
3262 if (TARGET_AVX)
3263 {
3264 if (REG_P (operands[0]))
3265 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3266 else
3267 return "vmovlps\t{%1, %0|%0, %1}";
3268 }
3269 else
3270 return "movlps\t{%1, %0|%0, %1}";
3271 default:
3272 gcc_unreachable ();
3273 }
3274
3275 default:
3276 gcc_unreachable ();
3277 }
3278 }
3279 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3280 (set (attr "prefix")
3281 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3282 (const_string "orig")
3283 (const_string "maybe_vex")))
3284 (set (attr "prefix_data16")
3285 (if_then_else (eq_attr "mode" "V1DF")
3286 (const_string "1")
3287 (const_string "*")))
3288 (set (attr "mode")
3289 (cond [(eq_attr "alternative" "0,1,2")
3290 (const_string "DF")
3291 (eq_attr "alternative" "3,4")
3292 (const_string "SI")
3293
3294 /* For SSE1, we have many fewer alternatives. */
3295 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3296 (cond [(eq_attr "alternative" "5,6")
3297 (const_string "V4SF")
3298 ]
3299 (const_string "V2SF"))
3300
3301 /* xorps is one byte shorter. */
3302 (eq_attr "alternative" "5")
3303 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3304 (const_int 0))
3305 (const_string "V4SF")
3306 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3307 (const_int 0))
3308 (const_string "TI")
3309 ]
3310 (const_string "V2DF"))
3311
3312 /* For architectures resolving dependencies on
3313 whole SSE registers use APD move to break dependency
3314 chains, otherwise use short move to avoid extra work.
3315
3316 movaps encodes one byte shorter. */
3317 (eq_attr "alternative" "6")
3318 (cond
3319 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3320 (const_int 0))
3321 (const_string "V4SF")
3322 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3323 (const_int 0))
3324 (const_string "V2DF")
3325 ]
3326 (const_string "DF"))
3327 /* For architectures resolving dependencies on register
3328 parts we may avoid extra work to zero out upper part
3329 of register. */
3330 (eq_attr "alternative" "7")
3331 (if_then_else
3332 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3333 (const_int 0))
3334 (const_string "V1DF")
3335 (const_string "DF"))
3336 ]
3337 (const_string "DF")))])
3338
3339 (define_split
3340 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3341 (match_operand:DF 1 "general_operand" ""))]
3342 "reload_completed
3343 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3344 && ! (ANY_FP_REG_P (operands[0]) ||
3345 (GET_CODE (operands[0]) == SUBREG
3346 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3347 && ! (ANY_FP_REG_P (operands[1]) ||
3348 (GET_CODE (operands[1]) == SUBREG
3349 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3350 [(const_int 0)]
3351 "ix86_split_long_move (operands); DONE;")
3352
3353 (define_insn "*movsf_internal"
3354 [(set (match_operand:SF 0 "nonimmediate_operand"
3355 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3356 (match_operand:SF 1 "general_operand"
3357 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3358 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3359 && (reload_in_progress || reload_completed
3360 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3361 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3362 && standard_80387_constant_p (operands[1]))
3363 || GET_CODE (operands[1]) != CONST_DOUBLE
3364 || memory_operand (operands[0], SFmode))"
3365 {
3366 switch (which_alternative)
3367 {
3368 case 0:
3369 case 1:
3370 return output_387_reg_move (insn, operands);
3371
3372 case 2:
3373 return standard_80387_constant_opcode (operands[1]);
3374
3375 case 3:
3376 case 4:
3377 return "mov{l}\t{%1, %0|%0, %1}";
3378 case 5:
3379 if (get_attr_mode (insn) == MODE_TI)
3380 return "%vpxor\t%0, %d0";
3381 else
3382 return "%vxorps\t%0, %d0";
3383 case 6:
3384 if (get_attr_mode (insn) == MODE_V4SF)
3385 return "%vmovaps\t{%1, %0|%0, %1}";
3386 else
3387 return "%vmovss\t{%1, %d0|%d0, %1}";
3388 case 7:
3389 if (TARGET_AVX)
3390 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3391 : "vmovss\t{%1, %0|%0, %1}";
3392 else
3393 return "movss\t{%1, %0|%0, %1}";
3394 case 8:
3395 return "%vmovss\t{%1, %0|%0, %1}";
3396
3397 case 9: case 10: case 14: case 15:
3398 return "movd\t{%1, %0|%0, %1}";
3399 case 12: case 13:
3400 return "%vmovd\t{%1, %0|%0, %1}";
3401
3402 case 11:
3403 return "movq\t{%1, %0|%0, %1}";
3404
3405 default:
3406 gcc_unreachable ();
3407 }
3408 }
3409 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3410 (set (attr "prefix")
3411 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3412 (const_string "maybe_vex")
3413 (const_string "orig")))
3414 (set (attr "mode")
3415 (cond [(eq_attr "alternative" "3,4,9,10")
3416 (const_string "SI")
3417 (eq_attr "alternative" "5")
3418 (if_then_else
3419 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3420 (const_int 0))
3421 (ne (symbol_ref "TARGET_SSE2")
3422 (const_int 0)))
3423 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3424 (const_int 0)))
3425 (const_string "TI")
3426 (const_string "V4SF"))
3427 /* For architectures resolving dependencies on
3428 whole SSE registers use APS move to break dependency
3429 chains, otherwise use short move to avoid extra work.
3430
3431 Do the same for architectures resolving dependencies on
3432 the parts. While in DF mode it is better to always handle
3433 just register parts, the SF mode is different due to lack
3434 of instructions to load just part of the register. It is
3435 better to maintain the whole registers in single format
3436 to avoid problems on using packed logical operations. */
3437 (eq_attr "alternative" "6")
3438 (if_then_else
3439 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3440 (const_int 0))
3441 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3442 (const_int 0)))
3443 (const_string "V4SF")
3444 (const_string "SF"))
3445 (eq_attr "alternative" "11")
3446 (const_string "DI")]
3447 (const_string "SF")))])
3448
3449 (define_split
3450 [(set (match_operand 0 "register_operand" "")
3451 (match_operand 1 "memory_operand" ""))]
3452 "reload_completed
3453 && MEM_P (operands[1])
3454 && (GET_MODE (operands[0]) == TFmode
3455 || GET_MODE (operands[0]) == XFmode
3456 || GET_MODE (operands[0]) == DFmode
3457 || GET_MODE (operands[0]) == SFmode)
3458 && (operands[2] = find_constant_src (insn))"
3459 [(set (match_dup 0) (match_dup 2))]
3460 {
3461 rtx c = operands[2];
3462 rtx r = operands[0];
3463
3464 if (GET_CODE (r) == SUBREG)
3465 r = SUBREG_REG (r);
3466
3467 if (SSE_REG_P (r))
3468 {
3469 if (!standard_sse_constant_p (c))
3470 FAIL;
3471 }
3472 else if (FP_REG_P (r))
3473 {
3474 if (!standard_80387_constant_p (c))
3475 FAIL;
3476 }
3477 else if (MMX_REG_P (r))
3478 FAIL;
3479 })
3480
3481 (define_split
3482 [(set (match_operand 0 "register_operand" "")
3483 (float_extend (match_operand 1 "memory_operand" "")))]
3484 "reload_completed
3485 && MEM_P (operands[1])
3486 && (GET_MODE (operands[0]) == TFmode
3487 || GET_MODE (operands[0]) == XFmode
3488 || GET_MODE (operands[0]) == DFmode
3489 || GET_MODE (operands[0]) == SFmode)
3490 && (operands[2] = find_constant_src (insn))"
3491 [(set (match_dup 0) (match_dup 2))]
3492 {
3493 rtx c = operands[2];
3494 rtx r = operands[0];
3495
3496 if (GET_CODE (r) == SUBREG)
3497 r = SUBREG_REG (r);
3498
3499 if (SSE_REG_P (r))
3500 {
3501 if (!standard_sse_constant_p (c))
3502 FAIL;
3503 }
3504 else if (FP_REG_P (r))
3505 {
3506 if (!standard_80387_constant_p (c))
3507 FAIL;
3508 }
3509 else if (MMX_REG_P (r))
3510 FAIL;
3511 })
3512
3513 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3514 (define_split
3515 [(set (match_operand:X87MODEF 0 "register_operand" "")
3516 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3517 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3518 && (standard_80387_constant_p (operands[1]) == 8
3519 || standard_80387_constant_p (operands[1]) == 9)"
3520 [(set (match_dup 0)(match_dup 1))
3521 (set (match_dup 0)
3522 (neg:X87MODEF (match_dup 0)))]
3523 {
3524 REAL_VALUE_TYPE r;
3525
3526 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3527 if (real_isnegzero (&r))
3528 operands[1] = CONST0_RTX (<MODE>mode);
3529 else
3530 operands[1] = CONST1_RTX (<MODE>mode);
3531 })
3532
3533 (define_insn "swapxf"
3534 [(set (match_operand:XF 0 "register_operand" "+f")
3535 (match_operand:XF 1 "register_operand" "+f"))
3536 (set (match_dup 1)
3537 (match_dup 0))]
3538 "TARGET_80387"
3539 {
3540 if (STACK_TOP_P (operands[0]))
3541 return "fxch\t%1";
3542 else
3543 return "fxch\t%0";
3544 }
3545 [(set_attr "type" "fxch")
3546 (set_attr "mode" "XF")])
3547
3548 (define_insn "*swap<mode>"
3549 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3550 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3551 (set (match_dup 1)
3552 (match_dup 0))]
3553 "TARGET_80387 || reload_completed"
3554 {
3555 if (STACK_TOP_P (operands[0]))
3556 return "fxch\t%1";
3557 else
3558 return "fxch\t%0";
3559 }
3560 [(set_attr "type" "fxch")
3561 (set_attr "mode" "<MODE>")])
3562 \f
3563 ;; Zero extension instructions
3564
3565 (define_expand "zero_extendsidi2"
3566 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3567 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3568 ""
3569 {
3570 if (!TARGET_64BIT)
3571 {
3572 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3573 DONE;
3574 }
3575 })
3576
3577 (define_insn "*zero_extendsidi2_rex64"
3578 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3579 (zero_extend:DI
3580 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3581 "TARGET_64BIT"
3582 "@
3583 mov\t{%k1, %k0|%k0, %k1}
3584 #
3585 movd\t{%1, %0|%0, %1}
3586 movd\t{%1, %0|%0, %1}
3587 %vmovd\t{%1, %0|%0, %1}
3588 %vmovd\t{%1, %0|%0, %1}"
3589 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3590 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3591 (set_attr "prefix_0f" "0,*,*,*,*,*")
3592 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3593
3594 (define_split
3595 [(set (match_operand:DI 0 "memory_operand" "")
3596 (zero_extend:DI (match_dup 0)))]
3597 "TARGET_64BIT"
3598 [(set (match_dup 4) (const_int 0))]
3599 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3600
3601 ;; %%% Kill me once multi-word ops are sane.
3602 (define_insn "zero_extendsidi2_1"
3603 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3604 (zero_extend:DI
3605 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3606 (clobber (reg:CC FLAGS_REG))]
3607 "!TARGET_64BIT"
3608 "@
3609 #
3610 #
3611 #
3612 movd\t{%1, %0|%0, %1}
3613 movd\t{%1, %0|%0, %1}
3614 %vmovd\t{%1, %0|%0, %1}
3615 %vmovd\t{%1, %0|%0, %1}"
3616 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3617 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3618 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3619
3620 (define_split
3621 [(set (match_operand:DI 0 "register_operand" "")
3622 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3623 (clobber (reg:CC FLAGS_REG))]
3624 "!TARGET_64BIT && reload_completed
3625 && true_regnum (operands[0]) == true_regnum (operands[1])"
3626 [(set (match_dup 4) (const_int 0))]
3627 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3628
3629 (define_split
3630 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3631 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3632 (clobber (reg:CC FLAGS_REG))]
3633 "!TARGET_64BIT && reload_completed
3634 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3635 [(set (match_dup 3) (match_dup 1))
3636 (set (match_dup 4) (const_int 0))]
3637 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3638
3639 (define_insn "zero_extend<mode>di2"
3640 [(set (match_operand:DI 0 "register_operand" "=r")
3641 (zero_extend:DI
3642 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3643 "TARGET_64BIT"
3644 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3645 [(set_attr "type" "imovx")
3646 (set_attr "mode" "SI")])
3647
3648 (define_expand "zero_extendhisi2"
3649 [(set (match_operand:SI 0 "register_operand" "")
3650 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3651 ""
3652 {
3653 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3654 {
3655 operands[1] = force_reg (HImode, operands[1]);
3656 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3657 DONE;
3658 }
3659 })
3660
3661 (define_insn_and_split "zero_extendhisi2_and"
3662 [(set (match_operand:SI 0 "register_operand" "=r")
3663 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3664 (clobber (reg:CC FLAGS_REG))]
3665 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3666 "#"
3667 "&& reload_completed"
3668 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3669 (clobber (reg:CC FLAGS_REG))])]
3670 ""
3671 [(set_attr "type" "alu1")
3672 (set_attr "mode" "SI")])
3673
3674 (define_insn "*zero_extendhisi2_movzwl"
3675 [(set (match_operand:SI 0 "register_operand" "=r")
3676 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3677 "!TARGET_ZERO_EXTEND_WITH_AND
3678 || optimize_function_for_size_p (cfun)"
3679 "movz{wl|x}\t{%1, %0|%0, %1}"
3680 [(set_attr "type" "imovx")
3681 (set_attr "mode" "SI")])
3682
3683 (define_expand "zero_extendqi<mode>2"
3684 [(parallel
3685 [(set (match_operand:SWI24 0 "register_operand" "")
3686 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3687 (clobber (reg:CC FLAGS_REG))])])
3688
3689 (define_insn "*zero_extendqi<mode>2_and"
3690 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3691 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3692 (clobber (reg:CC FLAGS_REG))]
3693 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3694 "#"
3695 [(set_attr "type" "alu1")
3696 (set_attr "mode" "<MODE>")])
3697
3698 ;; When source and destination does not overlap, clear destination
3699 ;; first and then do the movb
3700 (define_split
3701 [(set (match_operand:SWI24 0 "register_operand" "")
3702 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3703 (clobber (reg:CC FLAGS_REG))]
3704 "reload_completed
3705 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3706 && ANY_QI_REG_P (operands[0])
3707 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3708 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3709 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3710 {
3711 operands[2] = gen_lowpart (QImode, operands[0]);
3712 ix86_expand_clear (operands[0]);
3713 })
3714
3715 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3716 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3717 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3718 (clobber (reg:CC FLAGS_REG))]
3719 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3720 "#"
3721 [(set_attr "type" "imovx,alu1")
3722 (set_attr "mode" "<MODE>")])
3723
3724 ;; For the movzbl case strip only the clobber
3725 (define_split
3726 [(set (match_operand:SWI24 0 "register_operand" "")
3727 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3728 (clobber (reg:CC FLAGS_REG))]
3729 "reload_completed
3730 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3731 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3732 [(set (match_dup 0)
3733 (zero_extend:SWI24 (match_dup 1)))])
3734
3735 ; zero extend to SImode to avoid partial register stalls
3736 (define_insn "*zero_extendqi<mode>2_movzbl"
3737 [(set (match_operand:SWI24 0 "register_operand" "=r")
3738 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739 "reload_completed
3740 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3741 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3742 [(set_attr "type" "imovx")
3743 (set_attr "mode" "SI")])
3744
3745 ;; Rest is handled by single and.
3746 (define_split
3747 [(set (match_operand:SWI24 0 "register_operand" "")
3748 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3749 (clobber (reg:CC FLAGS_REG))]
3750 "reload_completed
3751 && true_regnum (operands[0]) == true_regnum (operands[1])"
3752 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3753 (clobber (reg:CC FLAGS_REG))])])
3754 \f
3755 ;; Sign extension instructions
3756
3757 (define_expand "extendsidi2"
3758 [(set (match_operand:DI 0 "register_operand" "")
3759 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3760 ""
3761 {
3762 if (!TARGET_64BIT)
3763 {
3764 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3765 DONE;
3766 }
3767 })
3768
3769 (define_insn "*extendsidi2_rex64"
3770 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3771 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3772 "TARGET_64BIT"
3773 "@
3774 {cltq|cdqe}
3775 movs{lq|x}\t{%1, %0|%0, %1}"
3776 [(set_attr "type" "imovx")
3777 (set_attr "mode" "DI")
3778 (set_attr "prefix_0f" "0")
3779 (set_attr "modrm" "0,1")])
3780
3781 (define_insn "extendsidi2_1"
3782 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3783 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3784 (clobber (reg:CC FLAGS_REG))
3785 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3786 "!TARGET_64BIT"
3787 "#")
3788
3789 ;; Extend to memory case when source register does die.
3790 (define_split
3791 [(set (match_operand:DI 0 "memory_operand" "")
3792 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3793 (clobber (reg:CC FLAGS_REG))
3794 (clobber (match_operand:SI 2 "register_operand" ""))]
3795 "(reload_completed
3796 && dead_or_set_p (insn, operands[1])
3797 && !reg_mentioned_p (operands[1], operands[0]))"
3798 [(set (match_dup 3) (match_dup 1))
3799 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3800 (clobber (reg:CC FLAGS_REG))])
3801 (set (match_dup 4) (match_dup 1))]
3802 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3803
3804 ;; Extend to memory case when source register does not die.
3805 (define_split
3806 [(set (match_operand:DI 0 "memory_operand" "")
3807 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3808 (clobber (reg:CC FLAGS_REG))
3809 (clobber (match_operand:SI 2 "register_operand" ""))]
3810 "reload_completed"
3811 [(const_int 0)]
3812 {
3813 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3814
3815 emit_move_insn (operands[3], operands[1]);
3816
3817 /* Generate a cltd if possible and doing so it profitable. */
3818 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3819 && true_regnum (operands[1]) == AX_REG
3820 && true_regnum (operands[2]) == DX_REG)
3821 {
3822 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3823 }
3824 else
3825 {
3826 emit_move_insn (operands[2], operands[1]);
3827 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3828 }
3829 emit_move_insn (operands[4], operands[2]);
3830 DONE;
3831 })
3832
3833 ;; Extend to register case. Optimize case where source and destination
3834 ;; registers match and cases where we can use cltd.
3835 (define_split
3836 [(set (match_operand:DI 0 "register_operand" "")
3837 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3838 (clobber (reg:CC FLAGS_REG))
3839 (clobber (match_scratch:SI 2 ""))]
3840 "reload_completed"
3841 [(const_int 0)]
3842 {
3843 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3844
3845 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3846 emit_move_insn (operands[3], operands[1]);
3847
3848 /* Generate a cltd if possible and doing so it profitable. */
3849 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3850 && true_regnum (operands[3]) == AX_REG
3851 && true_regnum (operands[4]) == DX_REG)
3852 {
3853 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3854 DONE;
3855 }
3856
3857 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3858 emit_move_insn (operands[4], operands[1]);
3859
3860 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3861 DONE;
3862 })
3863
3864 (define_insn "extend<mode>di2"
3865 [(set (match_operand:DI 0 "register_operand" "=r")
3866 (sign_extend:DI
3867 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3868 "TARGET_64BIT"
3869 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3870 [(set_attr "type" "imovx")
3871 (set_attr "mode" "DI")])
3872
3873 (define_insn "extendhisi2"
3874 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3875 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3876 ""
3877 {
3878 switch (get_attr_prefix_0f (insn))
3879 {
3880 case 0:
3881 return "{cwtl|cwde}";
3882 default:
3883 return "movs{wl|x}\t{%1, %0|%0, %1}";
3884 }
3885 }
3886 [(set_attr "type" "imovx")
3887 (set_attr "mode" "SI")
3888 (set (attr "prefix_0f")
3889 ;; movsx is short decodable while cwtl is vector decoded.
3890 (if_then_else (and (eq_attr "cpu" "!k6")
3891 (eq_attr "alternative" "0"))
3892 (const_string "0")
3893 (const_string "1")))
3894 (set (attr "modrm")
3895 (if_then_else (eq_attr "prefix_0f" "0")
3896 (const_string "0")
3897 (const_string "1")))])
3898
3899 (define_insn "*extendhisi2_zext"
3900 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3901 (zero_extend:DI
3902 (sign_extend:SI
3903 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3904 "TARGET_64BIT"
3905 {
3906 switch (get_attr_prefix_0f (insn))
3907 {
3908 case 0:
3909 return "{cwtl|cwde}";
3910 default:
3911 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3912 }
3913 }
3914 [(set_attr "type" "imovx")
3915 (set_attr "mode" "SI")
3916 (set (attr "prefix_0f")
3917 ;; movsx is short decodable while cwtl is vector decoded.
3918 (if_then_else (and (eq_attr "cpu" "!k6")
3919 (eq_attr "alternative" "0"))
3920 (const_string "0")
3921 (const_string "1")))
3922 (set (attr "modrm")
3923 (if_then_else (eq_attr "prefix_0f" "0")
3924 (const_string "0")
3925 (const_string "1")))])
3926
3927 (define_insn "extendqisi2"
3928 [(set (match_operand:SI 0 "register_operand" "=r")
3929 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3930 ""
3931 "movs{bl|x}\t{%1, %0|%0, %1}"
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "SI")])
3934
3935 (define_insn "*extendqisi2_zext"
3936 [(set (match_operand:DI 0 "register_operand" "=r")
3937 (zero_extend:DI
3938 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3939 "TARGET_64BIT"
3940 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3941 [(set_attr "type" "imovx")
3942 (set_attr "mode" "SI")])
3943
3944 (define_insn "extendqihi2"
3945 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3946 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3947 ""
3948 {
3949 switch (get_attr_prefix_0f (insn))
3950 {
3951 case 0:
3952 return "{cbtw|cbw}";
3953 default:
3954 return "movs{bw|x}\t{%1, %0|%0, %1}";
3955 }
3956 }
3957 [(set_attr "type" "imovx")
3958 (set_attr "mode" "HI")
3959 (set (attr "prefix_0f")
3960 ;; movsx is short decodable while cwtl is vector decoded.
3961 (if_then_else (and (eq_attr "cpu" "!k6")
3962 (eq_attr "alternative" "0"))
3963 (const_string "0")
3964 (const_string "1")))
3965 (set (attr "modrm")
3966 (if_then_else (eq_attr "prefix_0f" "0")
3967 (const_string "0")
3968 (const_string "1")))])
3969 \f
3970 ;; Conversions between float and double.
3971
3972 ;; These are all no-ops in the model used for the 80387.
3973 ;; So just emit moves.
3974
3975 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3976 (define_split
3977 [(set (match_operand:DF 0 "push_operand" "")
3978 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3979 "reload_completed"
3980 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3981 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3982
3983 (define_split
3984 [(set (match_operand:XF 0 "push_operand" "")
3985 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3986 "reload_completed"
3987 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3988 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3989 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3990
3991 (define_expand "extendsfdf2"
3992 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3993 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3994 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3995 {
3996 /* ??? Needed for compress_float_constant since all fp constants
3997 are LEGITIMATE_CONSTANT_P. */
3998 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3999 {
4000 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4001 && standard_80387_constant_p (operands[1]) > 0)
4002 {
4003 operands[1] = simplify_const_unary_operation
4004 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4005 emit_move_insn_1 (operands[0], operands[1]);
4006 DONE;
4007 }
4008 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4009 }
4010 })
4011
4012 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4013 cvtss2sd:
4014 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4015 cvtps2pd xmm2,xmm1
4016 We do the conversion post reload to avoid producing of 128bit spills
4017 that might lead to ICE on 32bit target. The sequence unlikely combine
4018 anyway. */
4019 (define_split
4020 [(set (match_operand:DF 0 "register_operand" "")
4021 (float_extend:DF
4022 (match_operand:SF 1 "nonimmediate_operand" "")))]
4023 "TARGET_USE_VECTOR_FP_CONVERTS
4024 && optimize_insn_for_speed_p ()
4025 && reload_completed && SSE_REG_P (operands[0])"
4026 [(set (match_dup 2)
4027 (float_extend:V2DF
4028 (vec_select:V2SF
4029 (match_dup 3)
4030 (parallel [(const_int 0) (const_int 1)]))))]
4031 {
4032 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4033 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4034 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4035 Try to avoid move when unpacking can be done in source. */
4036 if (REG_P (operands[1]))
4037 {
4038 /* If it is unsafe to overwrite upper half of source, we need
4039 to move to destination and unpack there. */
4040 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4041 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4042 && true_regnum (operands[0]) != true_regnum (operands[1]))
4043 {
4044 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4045 emit_move_insn (tmp, operands[1]);
4046 }
4047 else
4048 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4049 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4050 operands[3]));
4051 }
4052 else
4053 emit_insn (gen_vec_setv4sf_0 (operands[3],
4054 CONST0_RTX (V4SFmode), operands[1]));
4055 })
4056
4057 (define_insn "*extendsfdf2_mixed"
4058 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4059 (float_extend:DF
4060 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4061 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4062 {
4063 switch (which_alternative)
4064 {
4065 case 0:
4066 case 1:
4067 return output_387_reg_move (insn, operands);
4068
4069 case 2:
4070 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4071
4072 default:
4073 gcc_unreachable ();
4074 }
4075 }
4076 [(set_attr "type" "fmov,fmov,ssecvt")
4077 (set_attr "prefix" "orig,orig,maybe_vex")
4078 (set_attr "mode" "SF,XF,DF")])
4079
4080 (define_insn "*extendsfdf2_sse"
4081 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4082 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4083 "TARGET_SSE2 && TARGET_SSE_MATH"
4084 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4085 [(set_attr "type" "ssecvt")
4086 (set_attr "prefix" "maybe_vex")
4087 (set_attr "mode" "DF")])
4088
4089 (define_insn "*extendsfdf2_i387"
4090 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4091 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4092 "TARGET_80387"
4093 "* return output_387_reg_move (insn, operands);"
4094 [(set_attr "type" "fmov")
4095 (set_attr "mode" "SF,XF")])
4096
4097 (define_expand "extend<mode>xf2"
4098 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4099 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4100 "TARGET_80387"
4101 {
4102 /* ??? Needed for compress_float_constant since all fp constants
4103 are LEGITIMATE_CONSTANT_P. */
4104 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4105 {
4106 if (standard_80387_constant_p (operands[1]) > 0)
4107 {
4108 operands[1] = simplify_const_unary_operation
4109 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4110 emit_move_insn_1 (operands[0], operands[1]);
4111 DONE;
4112 }
4113 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4114 }
4115 })
4116
4117 (define_insn "*extend<mode>xf2_i387"
4118 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4119 (float_extend:XF
4120 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4121 "TARGET_80387"
4122 "* return output_387_reg_move (insn, operands);"
4123 [(set_attr "type" "fmov")
4124 (set_attr "mode" "<MODE>,XF")])
4125
4126 ;; %%% This seems bad bad news.
4127 ;; This cannot output into an f-reg because there is no way to be sure
4128 ;; of truncating in that case. Otherwise this is just like a simple move
4129 ;; insn. So we pretend we can output to a reg in order to get better
4130 ;; register preferencing, but we really use a stack slot.
4131
4132 ;; Conversion from DFmode to SFmode.
4133
4134 (define_expand "truncdfsf2"
4135 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4136 (float_truncate:SF
4137 (match_operand:DF 1 "nonimmediate_operand" "")))]
4138 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4139 {
4140 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4141 ;
4142 else if (flag_unsafe_math_optimizations)
4143 ;
4144 else
4145 {
4146 enum ix86_stack_slot slot = (virtuals_instantiated
4147 ? SLOT_TEMP
4148 : SLOT_VIRTUAL);
4149 rtx temp = assign_386_stack_local (SFmode, slot);
4150 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4151 DONE;
4152 }
4153 })
4154
4155 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4156 cvtsd2ss:
4157 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4158 cvtpd2ps xmm2,xmm1
4159 We do the conversion post reload to avoid producing of 128bit spills
4160 that might lead to ICE on 32bit target. The sequence unlikely combine
4161 anyway. */
4162 (define_split
4163 [(set (match_operand:SF 0 "register_operand" "")
4164 (float_truncate:SF
4165 (match_operand:DF 1 "nonimmediate_operand" "")))]
4166 "TARGET_USE_VECTOR_FP_CONVERTS
4167 && optimize_insn_for_speed_p ()
4168 && reload_completed && SSE_REG_P (operands[0])"
4169 [(set (match_dup 2)
4170 (vec_concat:V4SF
4171 (float_truncate:V2SF
4172 (match_dup 4))
4173 (match_dup 3)))]
4174 {
4175 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4176 operands[3] = CONST0_RTX (V2SFmode);
4177 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4178 /* Use movsd for loading from memory, unpcklpd for registers.
4179 Try to avoid move when unpacking can be done in source, or SSE3
4180 movddup is available. */
4181 if (REG_P (operands[1]))
4182 {
4183 if (!TARGET_SSE3
4184 && true_regnum (operands[0]) != true_regnum (operands[1])
4185 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4186 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4187 {
4188 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4189 emit_move_insn (tmp, operands[1]);
4190 operands[1] = tmp;
4191 }
4192 else if (!TARGET_SSE3)
4193 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4194 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4195 }
4196 else
4197 emit_insn (gen_sse2_loadlpd (operands[4],
4198 CONST0_RTX (V2DFmode), operands[1]));
4199 })
4200
4201 (define_expand "truncdfsf2_with_temp"
4202 [(parallel [(set (match_operand:SF 0 "" "")
4203 (float_truncate:SF (match_operand:DF 1 "" "")))
4204 (clobber (match_operand:SF 2 "" ""))])])
4205
4206 (define_insn "*truncdfsf_fast_mixed"
4207 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4208 (float_truncate:SF
4209 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4210 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4211 {
4212 switch (which_alternative)
4213 {
4214 case 0:
4215 return output_387_reg_move (insn, operands);
4216 case 1:
4217 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4218 default:
4219 gcc_unreachable ();
4220 }
4221 }
4222 [(set_attr "type" "fmov,ssecvt")
4223 (set_attr "prefix" "orig,maybe_vex")
4224 (set_attr "mode" "SF")])
4225
4226 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4227 ;; because nothing we do here is unsafe.
4228 (define_insn "*truncdfsf_fast_sse"
4229 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4230 (float_truncate:SF
4231 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4232 "TARGET_SSE2 && TARGET_SSE_MATH"
4233 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4234 [(set_attr "type" "ssecvt")
4235 (set_attr "prefix" "maybe_vex")
4236 (set_attr "mode" "SF")])
4237
4238 (define_insn "*truncdfsf_fast_i387"
4239 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4240 (float_truncate:SF
4241 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4242 "TARGET_80387 && flag_unsafe_math_optimizations"
4243 "* return output_387_reg_move (insn, operands);"
4244 [(set_attr "type" "fmov")
4245 (set_attr "mode" "SF")])
4246
4247 (define_insn "*truncdfsf_mixed"
4248 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4249 (float_truncate:SF
4250 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4251 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4252 "TARGET_MIX_SSE_I387"
4253 {
4254 switch (which_alternative)
4255 {
4256 case 0:
4257 return output_387_reg_move (insn, operands);
4258 case 1:
4259 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4260
4261 default:
4262 return "#";
4263 }
4264 }
4265 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4266 (set_attr "unit" "*,*,i387,i387,i387")
4267 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4268 (set_attr "mode" "SF")])
4269
4270 (define_insn "*truncdfsf_i387"
4271 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4272 (float_truncate:SF
4273 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4274 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4275 "TARGET_80387"
4276 {
4277 switch (which_alternative)
4278 {
4279 case 0:
4280 return output_387_reg_move (insn, operands);
4281
4282 default:
4283 return "#";
4284 }
4285 }
4286 [(set_attr "type" "fmov,multi,multi,multi")
4287 (set_attr "unit" "*,i387,i387,i387")
4288 (set_attr "mode" "SF")])
4289
4290 (define_insn "*truncdfsf2_i387_1"
4291 [(set (match_operand:SF 0 "memory_operand" "=m")
4292 (float_truncate:SF
4293 (match_operand:DF 1 "register_operand" "f")))]
4294 "TARGET_80387
4295 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4296 && !TARGET_MIX_SSE_I387"
4297 "* return output_387_reg_move (insn, operands);"
4298 [(set_attr "type" "fmov")
4299 (set_attr "mode" "SF")])
4300
4301 (define_split
4302 [(set (match_operand:SF 0 "register_operand" "")
4303 (float_truncate:SF
4304 (match_operand:DF 1 "fp_register_operand" "")))
4305 (clobber (match_operand 2 "" ""))]
4306 "reload_completed"
4307 [(set (match_dup 2) (match_dup 1))
4308 (set (match_dup 0) (match_dup 2))]
4309 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4310
4311 ;; Conversion from XFmode to {SF,DF}mode
4312
4313 (define_expand "truncxf<mode>2"
4314 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4315 (float_truncate:MODEF
4316 (match_operand:XF 1 "register_operand" "")))
4317 (clobber (match_dup 2))])]
4318 "TARGET_80387"
4319 {
4320 if (flag_unsafe_math_optimizations)
4321 {
4322 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4323 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4324 if (reg != operands[0])
4325 emit_move_insn (operands[0], reg);
4326 DONE;
4327 }
4328 else
4329 {
4330 enum ix86_stack_slot slot = (virtuals_instantiated
4331 ? SLOT_TEMP
4332 : SLOT_VIRTUAL);
4333 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4334 }
4335 })
4336
4337 (define_insn "*truncxfsf2_mixed"
4338 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4339 (float_truncate:SF
4340 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4341 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4342 "TARGET_80387"
4343 {
4344 gcc_assert (!which_alternative);
4345 return output_387_reg_move (insn, operands);
4346 }
4347 [(set_attr "type" "fmov,multi,multi,multi")
4348 (set_attr "unit" "*,i387,i387,i387")
4349 (set_attr "mode" "SF")])
4350
4351 (define_insn "*truncxfdf2_mixed"
4352 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4353 (float_truncate:DF
4354 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4355 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4356 "TARGET_80387"
4357 {
4358 gcc_assert (!which_alternative);
4359 return output_387_reg_move (insn, operands);
4360 }
4361 [(set_attr "type" "fmov,multi,multi,multi")
4362 (set_attr "unit" "*,i387,i387,i387")
4363 (set_attr "mode" "DF")])
4364
4365 (define_insn "truncxf<mode>2_i387_noop"
4366 [(set (match_operand:MODEF 0 "register_operand" "=f")
4367 (float_truncate:MODEF
4368 (match_operand:XF 1 "register_operand" "f")))]
4369 "TARGET_80387 && flag_unsafe_math_optimizations"
4370 "* return output_387_reg_move (insn, operands);"
4371 [(set_attr "type" "fmov")
4372 (set_attr "mode" "<MODE>")])
4373
4374 (define_insn "*truncxf<mode>2_i387"
4375 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4376 (float_truncate:MODEF
4377 (match_operand:XF 1 "register_operand" "f")))]
4378 "TARGET_80387"
4379 "* return output_387_reg_move (insn, operands);"
4380 [(set_attr "type" "fmov")
4381 (set_attr "mode" "<MODE>")])
4382
4383 (define_split
4384 [(set (match_operand:MODEF 0 "register_operand" "")
4385 (float_truncate:MODEF
4386 (match_operand:XF 1 "register_operand" "")))
4387 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4388 "TARGET_80387 && reload_completed"
4389 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4390 (set (match_dup 0) (match_dup 2))])
4391
4392 (define_split
4393 [(set (match_operand:MODEF 0 "memory_operand" "")
4394 (float_truncate:MODEF
4395 (match_operand:XF 1 "register_operand" "")))
4396 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4397 "TARGET_80387"
4398 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4399 \f
4400 ;; Signed conversion to DImode.
4401
4402 (define_expand "fix_truncxfdi2"
4403 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4404 (fix:DI (match_operand:XF 1 "register_operand" "")))
4405 (clobber (reg:CC FLAGS_REG))])]
4406 "TARGET_80387"
4407 {
4408 if (TARGET_FISTTP)
4409 {
4410 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4411 DONE;
4412 }
4413 })
4414
4415 (define_expand "fix_trunc<mode>di2"
4416 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4417 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4418 (clobber (reg:CC FLAGS_REG))])]
4419 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4420 {
4421 if (TARGET_FISTTP
4422 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4423 {
4424 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4425 DONE;
4426 }
4427 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4428 {
4429 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4430 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4431 if (out != operands[0])
4432 emit_move_insn (operands[0], out);
4433 DONE;
4434 }
4435 })
4436
4437 ;; Signed conversion to SImode.
4438
4439 (define_expand "fix_truncxfsi2"
4440 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4441 (fix:SI (match_operand:XF 1 "register_operand" "")))
4442 (clobber (reg:CC FLAGS_REG))])]
4443 "TARGET_80387"
4444 {
4445 if (TARGET_FISTTP)
4446 {
4447 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4448 DONE;
4449 }
4450 })
4451
4452 (define_expand "fix_trunc<mode>si2"
4453 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4454 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4455 (clobber (reg:CC FLAGS_REG))])]
4456 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4457 {
4458 if (TARGET_FISTTP
4459 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4460 {
4461 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4462 DONE;
4463 }
4464 if (SSE_FLOAT_MODE_P (<MODE>mode))
4465 {
4466 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4467 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4468 if (out != operands[0])
4469 emit_move_insn (operands[0], out);
4470 DONE;
4471 }
4472 })
4473
4474 ;; Signed conversion to HImode.
4475
4476 (define_expand "fix_trunc<mode>hi2"
4477 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4478 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4479 (clobber (reg:CC FLAGS_REG))])]
4480 "TARGET_80387
4481 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4482 {
4483 if (TARGET_FISTTP)
4484 {
4485 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4486 DONE;
4487 }
4488 })
4489
4490 ;; Unsigned conversion to SImode.
4491
4492 (define_expand "fixuns_trunc<mode>si2"
4493 [(parallel
4494 [(set (match_operand:SI 0 "register_operand" "")
4495 (unsigned_fix:SI
4496 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4497 (use (match_dup 2))
4498 (clobber (match_scratch:<ssevecmode> 3 ""))
4499 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4500 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4501 {
4502 enum machine_mode mode = <MODE>mode;
4503 enum machine_mode vecmode = <ssevecmode>mode;
4504 REAL_VALUE_TYPE TWO31r;
4505 rtx two31;
4506
4507 if (optimize_insn_for_size_p ())
4508 FAIL;
4509
4510 real_ldexp (&TWO31r, &dconst1, 31);
4511 two31 = const_double_from_real_value (TWO31r, mode);
4512 two31 = ix86_build_const_vector (mode, true, two31);
4513 operands[2] = force_reg (vecmode, two31);
4514 })
4515
4516 (define_insn_and_split "*fixuns_trunc<mode>_1"
4517 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4518 (unsigned_fix:SI
4519 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4520 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4521 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4522 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4523 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4524 && optimize_function_for_speed_p (cfun)"
4525 "#"
4526 "&& reload_completed"
4527 [(const_int 0)]
4528 {
4529 ix86_split_convert_uns_si_sse (operands);
4530 DONE;
4531 })
4532
4533 ;; Unsigned conversion to HImode.
4534 ;; Without these patterns, we'll try the unsigned SI conversion which
4535 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4536
4537 (define_expand "fixuns_trunc<mode>hi2"
4538 [(set (match_dup 2)
4539 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4540 (set (match_operand:HI 0 "nonimmediate_operand" "")
4541 (subreg:HI (match_dup 2) 0))]
4542 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4543 "operands[2] = gen_reg_rtx (SImode);")
4544
4545 ;; When SSE is available, it is always faster to use it!
4546 (define_insn "fix_trunc<mode>di_sse"
4547 [(set (match_operand:DI 0 "register_operand" "=r,r")
4548 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4549 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4550 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4551 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4552 [(set_attr "type" "sseicvt")
4553 (set_attr "prefix" "maybe_vex")
4554 (set_attr "prefix_rex" "1")
4555 (set_attr "mode" "<MODE>")
4556 (set_attr "athlon_decode" "double,vector")
4557 (set_attr "amdfam10_decode" "double,double")])
4558
4559 (define_insn "fix_trunc<mode>si_sse"
4560 [(set (match_operand:SI 0 "register_operand" "=r,r")
4561 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4562 "SSE_FLOAT_MODE_P (<MODE>mode)
4563 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4564 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4565 [(set_attr "type" "sseicvt")
4566 (set_attr "prefix" "maybe_vex")
4567 (set_attr "mode" "<MODE>")
4568 (set_attr "athlon_decode" "double,vector")
4569 (set_attr "amdfam10_decode" "double,double")])
4570
4571 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4572 (define_peephole2
4573 [(set (match_operand:MODEF 0 "register_operand" "")
4574 (match_operand:MODEF 1 "memory_operand" ""))
4575 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4576 (fix:SSEMODEI24 (match_dup 0)))]
4577 "TARGET_SHORTEN_X87_SSE
4578 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4579 && peep2_reg_dead_p (2, operands[0])"
4580 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4581
4582 ;; Avoid vector decoded forms of the instruction.
4583 (define_peephole2
4584 [(match_scratch:DF 2 "Y2")
4585 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4586 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4587 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4588 [(set (match_dup 2) (match_dup 1))
4589 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4590
4591 (define_peephole2
4592 [(match_scratch:SF 2 "x")
4593 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4594 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4595 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4596 [(set (match_dup 2) (match_dup 1))
4597 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4598
4599 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4600 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4601 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4602 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4603 && TARGET_FISTTP
4604 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4605 && (TARGET_64BIT || <MODE>mode != DImode))
4606 && TARGET_SSE_MATH)
4607 && can_create_pseudo_p ()"
4608 "#"
4609 "&& 1"
4610 [(const_int 0)]
4611 {
4612 if (memory_operand (operands[0], VOIDmode))
4613 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4614 else
4615 {
4616 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4617 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4618 operands[1],
4619 operands[2]));
4620 }
4621 DONE;
4622 }
4623 [(set_attr "type" "fisttp")
4624 (set_attr "mode" "<MODE>")])
4625
4626 (define_insn "fix_trunc<mode>_i387_fisttp"
4627 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4628 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4629 (clobber (match_scratch:XF 2 "=&1f"))]
4630 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4631 && TARGET_FISTTP
4632 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4633 && (TARGET_64BIT || <MODE>mode != DImode))
4634 && TARGET_SSE_MATH)"
4635 "* return output_fix_trunc (insn, operands, 1);"
4636 [(set_attr "type" "fisttp")
4637 (set_attr "mode" "<MODE>")])
4638
4639 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4640 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4641 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4642 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4643 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4644 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4645 && TARGET_FISTTP
4646 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4647 && (TARGET_64BIT || <MODE>mode != DImode))
4648 && TARGET_SSE_MATH)"
4649 "#"
4650 [(set_attr "type" "fisttp")
4651 (set_attr "mode" "<MODE>")])
4652
4653 (define_split
4654 [(set (match_operand:X87MODEI 0 "register_operand" "")
4655 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4656 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4657 (clobber (match_scratch 3 ""))]
4658 "reload_completed"
4659 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4660 (clobber (match_dup 3))])
4661 (set (match_dup 0) (match_dup 2))])
4662
4663 (define_split
4664 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4665 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4666 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4667 (clobber (match_scratch 3 ""))]
4668 "reload_completed"
4669 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4670 (clobber (match_dup 3))])])
4671
4672 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4673 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4674 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4675 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4676 ;; function in i386.c.
4677 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4678 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4679 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4680 (clobber (reg:CC FLAGS_REG))]
4681 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4682 && !TARGET_FISTTP
4683 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4684 && (TARGET_64BIT || <MODE>mode != DImode))
4685 && can_create_pseudo_p ()"
4686 "#"
4687 "&& 1"
4688 [(const_int 0)]
4689 {
4690 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4691
4692 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4693 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4694 if (memory_operand (operands[0], VOIDmode))
4695 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4696 operands[2], operands[3]));
4697 else
4698 {
4699 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4700 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4701 operands[2], operands[3],
4702 operands[4]));
4703 }
4704 DONE;
4705 }
4706 [(set_attr "type" "fistp")
4707 (set_attr "i387_cw" "trunc")
4708 (set_attr "mode" "<MODE>")])
4709
4710 (define_insn "fix_truncdi_i387"
4711 [(set (match_operand:DI 0 "memory_operand" "=m")
4712 (fix:DI (match_operand 1 "register_operand" "f")))
4713 (use (match_operand:HI 2 "memory_operand" "m"))
4714 (use (match_operand:HI 3 "memory_operand" "m"))
4715 (clobber (match_scratch:XF 4 "=&1f"))]
4716 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4717 && !TARGET_FISTTP
4718 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4719 "* return output_fix_trunc (insn, operands, 0);"
4720 [(set_attr "type" "fistp")
4721 (set_attr "i387_cw" "trunc")
4722 (set_attr "mode" "DI")])
4723
4724 (define_insn "fix_truncdi_i387_with_temp"
4725 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4726 (fix:DI (match_operand 1 "register_operand" "f,f")))
4727 (use (match_operand:HI 2 "memory_operand" "m,m"))
4728 (use (match_operand:HI 3 "memory_operand" "m,m"))
4729 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4730 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4731 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4732 && !TARGET_FISTTP
4733 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4734 "#"
4735 [(set_attr "type" "fistp")
4736 (set_attr "i387_cw" "trunc")
4737 (set_attr "mode" "DI")])
4738
4739 (define_split
4740 [(set (match_operand:DI 0 "register_operand" "")
4741 (fix:DI (match_operand 1 "register_operand" "")))
4742 (use (match_operand:HI 2 "memory_operand" ""))
4743 (use (match_operand:HI 3 "memory_operand" ""))
4744 (clobber (match_operand:DI 4 "memory_operand" ""))
4745 (clobber (match_scratch 5 ""))]
4746 "reload_completed"
4747 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4748 (use (match_dup 2))
4749 (use (match_dup 3))
4750 (clobber (match_dup 5))])
4751 (set (match_dup 0) (match_dup 4))])
4752
4753 (define_split
4754 [(set (match_operand:DI 0 "memory_operand" "")
4755 (fix:DI (match_operand 1 "register_operand" "")))
4756 (use (match_operand:HI 2 "memory_operand" ""))
4757 (use (match_operand:HI 3 "memory_operand" ""))
4758 (clobber (match_operand:DI 4 "memory_operand" ""))
4759 (clobber (match_scratch 5 ""))]
4760 "reload_completed"
4761 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4762 (use (match_dup 2))
4763 (use (match_dup 3))
4764 (clobber (match_dup 5))])])
4765
4766 (define_insn "fix_trunc<mode>_i387"
4767 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4768 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4769 (use (match_operand:HI 2 "memory_operand" "m"))
4770 (use (match_operand:HI 3 "memory_operand" "m"))]
4771 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4772 && !TARGET_FISTTP
4773 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4774 "* return output_fix_trunc (insn, operands, 0);"
4775 [(set_attr "type" "fistp")
4776 (set_attr "i387_cw" "trunc")
4777 (set_attr "mode" "<MODE>")])
4778
4779 (define_insn "fix_trunc<mode>_i387_with_temp"
4780 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4781 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4782 (use (match_operand:HI 2 "memory_operand" "m,m"))
4783 (use (match_operand:HI 3 "memory_operand" "m,m"))
4784 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4785 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4786 && !TARGET_FISTTP
4787 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4788 "#"
4789 [(set_attr "type" "fistp")
4790 (set_attr "i387_cw" "trunc")
4791 (set_attr "mode" "<MODE>")])
4792
4793 (define_split
4794 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4795 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4796 (use (match_operand:HI 2 "memory_operand" ""))
4797 (use (match_operand:HI 3 "memory_operand" ""))
4798 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4799 "reload_completed"
4800 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4801 (use (match_dup 2))
4802 (use (match_dup 3))])
4803 (set (match_dup 0) (match_dup 4))])
4804
4805 (define_split
4806 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4807 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4808 (use (match_operand:HI 2 "memory_operand" ""))
4809 (use (match_operand:HI 3 "memory_operand" ""))
4810 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4811 "reload_completed"
4812 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4813 (use (match_dup 2))
4814 (use (match_dup 3))])])
4815
4816 (define_insn "x86_fnstcw_1"
4817 [(set (match_operand:HI 0 "memory_operand" "=m")
4818 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4819 "TARGET_80387"
4820 "fnstcw\t%0"
4821 [(set (attr "length")
4822 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4823 (set_attr "mode" "HI")
4824 (set_attr "unit" "i387")])
4825
4826 (define_insn "x86_fldcw_1"
4827 [(set (reg:HI FPCR_REG)
4828 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4829 "TARGET_80387"
4830 "fldcw\t%0"
4831 [(set (attr "length")
4832 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4833 (set_attr "mode" "HI")
4834 (set_attr "unit" "i387")
4835 (set_attr "athlon_decode" "vector")
4836 (set_attr "amdfam10_decode" "vector")])
4837 \f
4838 ;; Conversion between fixed point and floating point.
4839
4840 ;; Even though we only accept memory inputs, the backend _really_
4841 ;; wants to be able to do this between registers.
4842
4843 (define_expand "floathi<mode>2"
4844 [(set (match_operand:X87MODEF 0 "register_operand" "")
4845 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4846 "TARGET_80387
4847 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4848 || TARGET_MIX_SSE_I387)")
4849
4850 ;; Pre-reload splitter to add memory clobber to the pattern.
4851 (define_insn_and_split "*floathi<mode>2_1"
4852 [(set (match_operand:X87MODEF 0 "register_operand" "")
4853 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4854 "TARGET_80387
4855 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4856 || TARGET_MIX_SSE_I387)
4857 && can_create_pseudo_p ()"
4858 "#"
4859 "&& 1"
4860 [(parallel [(set (match_dup 0)
4861 (float:X87MODEF (match_dup 1)))
4862 (clobber (match_dup 2))])]
4863 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4864
4865 (define_insn "*floathi<mode>2_i387_with_temp"
4866 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4867 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4868 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4869 "TARGET_80387
4870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4871 || TARGET_MIX_SSE_I387)"
4872 "#"
4873 [(set_attr "type" "fmov,multi")
4874 (set_attr "mode" "<MODE>")
4875 (set_attr "unit" "*,i387")
4876 (set_attr "fp_int_src" "true")])
4877
4878 (define_insn "*floathi<mode>2_i387"
4879 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4880 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4881 "TARGET_80387
4882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4883 || TARGET_MIX_SSE_I387)"
4884 "fild%Z1\t%1"
4885 [(set_attr "type" "fmov")
4886 (set_attr "mode" "<MODE>")
4887 (set_attr "fp_int_src" "true")])
4888
4889 (define_split
4890 [(set (match_operand:X87MODEF 0 "register_operand" "")
4891 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4892 (clobber (match_operand:HI 2 "memory_operand" ""))]
4893 "TARGET_80387
4894 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4895 || TARGET_MIX_SSE_I387)
4896 && reload_completed"
4897 [(set (match_dup 2) (match_dup 1))
4898 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4899
4900 (define_split
4901 [(set (match_operand:X87MODEF 0 "register_operand" "")
4902 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4903 (clobber (match_operand:HI 2 "memory_operand" ""))]
4904 "TARGET_80387
4905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4906 || TARGET_MIX_SSE_I387)
4907 && reload_completed"
4908 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4909
4910 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4911 [(set (match_operand:X87MODEF 0 "register_operand" "")
4912 (float:X87MODEF
4913 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4914 "TARGET_80387
4915 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4916 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4917 {
4918 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4919 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4920 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4921 {
4922 rtx reg = gen_reg_rtx (XFmode);
4923 rtx insn;
4924
4925 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4926
4927 if (<X87MODEF:MODE>mode == SFmode)
4928 insn = gen_truncxfsf2 (operands[0], reg);
4929 else if (<X87MODEF:MODE>mode == DFmode)
4930 insn = gen_truncxfdf2 (operands[0], reg);
4931 else
4932 gcc_unreachable ();
4933
4934 emit_insn (insn);
4935 DONE;
4936 }
4937 })
4938
4939 ;; Pre-reload splitter to add memory clobber to the pattern.
4940 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4941 [(set (match_operand:X87MODEF 0 "register_operand" "")
4942 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4943 "((TARGET_80387
4944 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4945 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4946 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4947 || TARGET_MIX_SSE_I387))
4948 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4949 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4950 && ((<SSEMODEI24:MODE>mode == SImode
4951 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4952 && optimize_function_for_speed_p (cfun)
4953 && flag_trapping_math)
4954 || !(TARGET_INTER_UNIT_CONVERSIONS
4955 || optimize_function_for_size_p (cfun)))))
4956 && can_create_pseudo_p ()"
4957 "#"
4958 "&& 1"
4959 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4960 (clobber (match_dup 2))])]
4961 {
4962 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4963
4964 /* Avoid store forwarding (partial memory) stall penalty
4965 by passing DImode value through XMM registers. */
4966 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4967 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4968 && optimize_function_for_speed_p (cfun))
4969 {
4970 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4971 operands[1],
4972 operands[2]));
4973 DONE;
4974 }
4975 })
4976
4977 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4978 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4979 (float:MODEF
4980 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4981 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4982 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4983 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4984 "#"
4985 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4986 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4987 (set_attr "unit" "*,i387,*,*,*")
4988 (set_attr "athlon_decode" "*,*,double,direct,double")
4989 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4990 (set_attr "fp_int_src" "true")])
4991
4992 (define_insn "*floatsi<mode>2_vector_mixed"
4993 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4994 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4995 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4996 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4997 "@
4998 fild%Z1\t%1
4999 #"
5000 [(set_attr "type" "fmov,sseicvt")
5001 (set_attr "mode" "<MODE>,<ssevecmode>")
5002 (set_attr "unit" "i387,*")
5003 (set_attr "athlon_decode" "*,direct")
5004 (set_attr "amdfam10_decode" "*,double")
5005 (set_attr "fp_int_src" "true")])
5006
5007 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5008 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5009 (float:MODEF
5010 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5011 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5012 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5013 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5014 "#"
5015 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5016 (set_attr "mode" "<MODEF:MODE>")
5017 (set_attr "unit" "*,i387,*,*")
5018 (set_attr "athlon_decode" "*,*,double,direct")
5019 (set_attr "amdfam10_decode" "*,*,vector,double")
5020 (set_attr "fp_int_src" "true")])
5021
5022 (define_split
5023 [(set (match_operand:MODEF 0 "register_operand" "")
5024 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5025 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5026 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5027 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5028 && TARGET_INTER_UNIT_CONVERSIONS
5029 && reload_completed
5030 && (SSE_REG_P (operands[0])
5031 || (GET_CODE (operands[0]) == SUBREG
5032 && SSE_REG_P (operands[0])))"
5033 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5034
5035 (define_split
5036 [(set (match_operand:MODEF 0 "register_operand" "")
5037 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5038 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5039 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5040 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5041 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5042 && reload_completed
5043 && (SSE_REG_P (operands[0])
5044 || (GET_CODE (operands[0]) == SUBREG
5045 && SSE_REG_P (operands[0])))"
5046 [(set (match_dup 2) (match_dup 1))
5047 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5048
5049 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5050 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5051 (float:MODEF
5052 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5053 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5054 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5055 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5056 "@
5057 fild%Z1\t%1
5058 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5059 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5060 [(set_attr "type" "fmov,sseicvt,sseicvt")
5061 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5062 (set_attr "mode" "<MODEF:MODE>")
5063 (set (attr "prefix_rex")
5064 (if_then_else
5065 (and (eq_attr "prefix" "maybe_vex")
5066 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5067 (const_string "1")
5068 (const_string "*")))
5069 (set_attr "unit" "i387,*,*")
5070 (set_attr "athlon_decode" "*,double,direct")
5071 (set_attr "amdfam10_decode" "*,vector,double")
5072 (set_attr "fp_int_src" "true")])
5073
5074 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5075 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5076 (float:MODEF
5077 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5078 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5079 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5080 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5081 "@
5082 fild%Z1\t%1
5083 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5084 [(set_attr "type" "fmov,sseicvt")
5085 (set_attr "prefix" "orig,maybe_vex")
5086 (set_attr "mode" "<MODEF:MODE>")
5087 (set (attr "prefix_rex")
5088 (if_then_else
5089 (and (eq_attr "prefix" "maybe_vex")
5090 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5091 (const_string "1")
5092 (const_string "*")))
5093 (set_attr "athlon_decode" "*,direct")
5094 (set_attr "amdfam10_decode" "*,double")
5095 (set_attr "fp_int_src" "true")])
5096
5097 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5098 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5099 (float:MODEF
5100 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5101 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5102 "TARGET_SSE2 && TARGET_SSE_MATH
5103 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5104 "#"
5105 [(set_attr "type" "sseicvt")
5106 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5107 (set_attr "athlon_decode" "double,direct,double")
5108 (set_attr "amdfam10_decode" "vector,double,double")
5109 (set_attr "fp_int_src" "true")])
5110
5111 (define_insn "*floatsi<mode>2_vector_sse"
5112 [(set (match_operand:MODEF 0 "register_operand" "=x")
5113 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5114 "TARGET_SSE2 && TARGET_SSE_MATH
5115 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5116 "#"
5117 [(set_attr "type" "sseicvt")
5118 (set_attr "mode" "<MODE>")
5119 (set_attr "athlon_decode" "direct")
5120 (set_attr "amdfam10_decode" "double")
5121 (set_attr "fp_int_src" "true")])
5122
5123 (define_split
5124 [(set (match_operand:MODEF 0 "register_operand" "")
5125 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5126 (clobber (match_operand:SI 2 "memory_operand" ""))]
5127 "TARGET_SSE2 && TARGET_SSE_MATH
5128 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5129 && reload_completed
5130 && (SSE_REG_P (operands[0])
5131 || (GET_CODE (operands[0]) == SUBREG
5132 && SSE_REG_P (operands[0])))"
5133 [(const_int 0)]
5134 {
5135 rtx op1 = operands[1];
5136
5137 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5138 <MODE>mode, 0);
5139 if (GET_CODE (op1) == SUBREG)
5140 op1 = SUBREG_REG (op1);
5141
5142 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5143 {
5144 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5145 emit_insn (gen_sse2_loadld (operands[4],
5146 CONST0_RTX (V4SImode), operands[1]));
5147 }
5148 /* We can ignore possible trapping value in the
5149 high part of SSE register for non-trapping math. */
5150 else if (SSE_REG_P (op1) && !flag_trapping_math)
5151 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5152 else
5153 {
5154 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5155 emit_move_insn (operands[2], operands[1]);
5156 emit_insn (gen_sse2_loadld (operands[4],
5157 CONST0_RTX (V4SImode), operands[2]));
5158 }
5159 emit_insn
5160 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5161 DONE;
5162 })
5163
5164 (define_split
5165 [(set (match_operand:MODEF 0 "register_operand" "")
5166 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5167 (clobber (match_operand:SI 2 "memory_operand" ""))]
5168 "TARGET_SSE2 && TARGET_SSE_MATH
5169 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5170 && reload_completed
5171 && (SSE_REG_P (operands[0])
5172 || (GET_CODE (operands[0]) == SUBREG
5173 && SSE_REG_P (operands[0])))"
5174 [(const_int 0)]
5175 {
5176 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5177 <MODE>mode, 0);
5178 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5179
5180 emit_insn (gen_sse2_loadld (operands[4],
5181 CONST0_RTX (V4SImode), operands[1]));
5182 emit_insn
5183 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5184 DONE;
5185 })
5186
5187 (define_split
5188 [(set (match_operand:MODEF 0 "register_operand" "")
5189 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5190 "TARGET_SSE2 && TARGET_SSE_MATH
5191 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5192 && reload_completed
5193 && (SSE_REG_P (operands[0])
5194 || (GET_CODE (operands[0]) == SUBREG
5195 && SSE_REG_P (operands[0])))"
5196 [(const_int 0)]
5197 {
5198 rtx op1 = operands[1];
5199
5200 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5201 <MODE>mode, 0);
5202 if (GET_CODE (op1) == SUBREG)
5203 op1 = SUBREG_REG (op1);
5204
5205 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5206 {
5207 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5208 emit_insn (gen_sse2_loadld (operands[4],
5209 CONST0_RTX (V4SImode), operands[1]));
5210 }
5211 /* We can ignore possible trapping value in the
5212 high part of SSE register for non-trapping math. */
5213 else if (SSE_REG_P (op1) && !flag_trapping_math)
5214 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5215 else
5216 gcc_unreachable ();
5217 emit_insn
5218 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5219 DONE;
5220 })
5221
5222 (define_split
5223 [(set (match_operand:MODEF 0 "register_operand" "")
5224 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5225 "TARGET_SSE2 && TARGET_SSE_MATH
5226 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5227 && reload_completed
5228 && (SSE_REG_P (operands[0])
5229 || (GET_CODE (operands[0]) == SUBREG
5230 && SSE_REG_P (operands[0])))"
5231 [(const_int 0)]
5232 {
5233 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5234 <MODE>mode, 0);
5235 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5236
5237 emit_insn (gen_sse2_loadld (operands[4],
5238 CONST0_RTX (V4SImode), operands[1]));
5239 emit_insn
5240 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5241 DONE;
5242 })
5243
5244 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5245 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5246 (float:MODEF
5247 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5248 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5249 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5250 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5251 "#"
5252 [(set_attr "type" "sseicvt")
5253 (set_attr "mode" "<MODEF:MODE>")
5254 (set_attr "athlon_decode" "double,direct")
5255 (set_attr "amdfam10_decode" "vector,double")
5256 (set_attr "fp_int_src" "true")])
5257
5258 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5259 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5260 (float:MODEF
5261 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5262 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5263 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5264 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5265 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5266 [(set_attr "type" "sseicvt")
5267 (set_attr "prefix" "maybe_vex")
5268 (set_attr "mode" "<MODEF:MODE>")
5269 (set (attr "prefix_rex")
5270 (if_then_else
5271 (and (eq_attr "prefix" "maybe_vex")
5272 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5273 (const_string "1")
5274 (const_string "*")))
5275 (set_attr "athlon_decode" "double,direct")
5276 (set_attr "amdfam10_decode" "vector,double")
5277 (set_attr "fp_int_src" "true")])
5278
5279 (define_split
5280 [(set (match_operand:MODEF 0 "register_operand" "")
5281 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5282 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5283 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5284 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5285 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5286 && reload_completed
5287 && (SSE_REG_P (operands[0])
5288 || (GET_CODE (operands[0]) == SUBREG
5289 && SSE_REG_P (operands[0])))"
5290 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5291
5292 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5293 [(set (match_operand:MODEF 0 "register_operand" "=x")
5294 (float:MODEF
5295 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5296 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5297 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5298 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5299 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5300 [(set_attr "type" "sseicvt")
5301 (set_attr "prefix" "maybe_vex")
5302 (set_attr "mode" "<MODEF:MODE>")
5303 (set (attr "prefix_rex")
5304 (if_then_else
5305 (and (eq_attr "prefix" "maybe_vex")
5306 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5307 (const_string "1")
5308 (const_string "*")))
5309 (set_attr "athlon_decode" "direct")
5310 (set_attr "amdfam10_decode" "double")
5311 (set_attr "fp_int_src" "true")])
5312
5313 (define_split
5314 [(set (match_operand:MODEF 0 "register_operand" "")
5315 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5316 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5317 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5318 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5319 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5320 && reload_completed
5321 && (SSE_REG_P (operands[0])
5322 || (GET_CODE (operands[0]) == SUBREG
5323 && SSE_REG_P (operands[0])))"
5324 [(set (match_dup 2) (match_dup 1))
5325 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5326
5327 (define_split
5328 [(set (match_operand:MODEF 0 "register_operand" "")
5329 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5330 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5331 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5332 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5333 && reload_completed
5334 && (SSE_REG_P (operands[0])
5335 || (GET_CODE (operands[0]) == SUBREG
5336 && SSE_REG_P (operands[0])))"
5337 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5338
5339 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5340 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5341 (float:X87MODEF
5342 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5343 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5344 "TARGET_80387
5345 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5346 "@
5347 fild%Z1\t%1
5348 #"
5349 [(set_attr "type" "fmov,multi")
5350 (set_attr "mode" "<X87MODEF:MODE>")
5351 (set_attr "unit" "*,i387")
5352 (set_attr "fp_int_src" "true")])
5353
5354 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5355 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5356 (float:X87MODEF
5357 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5358 "TARGET_80387
5359 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5360 "fild%Z1\t%1"
5361 [(set_attr "type" "fmov")
5362 (set_attr "mode" "<X87MODEF:MODE>")
5363 (set_attr "fp_int_src" "true")])
5364
5365 (define_split
5366 [(set (match_operand:X87MODEF 0 "register_operand" "")
5367 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5368 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5369 "TARGET_80387
5370 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5371 && reload_completed
5372 && FP_REG_P (operands[0])"
5373 [(set (match_dup 2) (match_dup 1))
5374 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5375
5376 (define_split
5377 [(set (match_operand:X87MODEF 0 "register_operand" "")
5378 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5379 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5380 "TARGET_80387
5381 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5382 && reload_completed
5383 && FP_REG_P (operands[0])"
5384 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5385
5386 ;; Avoid store forwarding (partial memory) stall penalty
5387 ;; by passing DImode value through XMM registers. */
5388
5389 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5390 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5391 (float:X87MODEF
5392 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5393 (clobber (match_scratch:V4SI 3 "=X,x"))
5394 (clobber (match_scratch:V4SI 4 "=X,x"))
5395 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5396 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5397 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5398 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5399 "#"
5400 [(set_attr "type" "multi")
5401 (set_attr "mode" "<X87MODEF:MODE>")
5402 (set_attr "unit" "i387")
5403 (set_attr "fp_int_src" "true")])
5404
5405 (define_split
5406 [(set (match_operand:X87MODEF 0 "register_operand" "")
5407 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5408 (clobber (match_scratch:V4SI 3 ""))
5409 (clobber (match_scratch:V4SI 4 ""))
5410 (clobber (match_operand:DI 2 "memory_operand" ""))]
5411 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5412 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5413 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5414 && reload_completed
5415 && FP_REG_P (operands[0])"
5416 [(set (match_dup 2) (match_dup 3))
5417 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5418 {
5419 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5420 Assemble the 64-bit DImode value in an xmm register. */
5421 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5422 gen_rtx_SUBREG (SImode, operands[1], 0)));
5423 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5424 gen_rtx_SUBREG (SImode, operands[1], 4)));
5425 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5426 operands[4]));
5427
5428 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5429 })
5430
5431 (define_split
5432 [(set (match_operand:X87MODEF 0 "register_operand" "")
5433 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5434 (clobber (match_scratch:V4SI 3 ""))
5435 (clobber (match_scratch:V4SI 4 ""))
5436 (clobber (match_operand:DI 2 "memory_operand" ""))]
5437 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5438 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5439 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5440 && reload_completed
5441 && FP_REG_P (operands[0])"
5442 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5443
5444 ;; Avoid store forwarding (partial memory) stall penalty by extending
5445 ;; SImode value to DImode through XMM register instead of pushing two
5446 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5447 ;; targets benefit from this optimization. Also note that fild
5448 ;; loads from memory only.
5449
5450 (define_insn "*floatunssi<mode>2_1"
5451 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5452 (unsigned_float:X87MODEF
5453 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5454 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5455 (clobber (match_scratch:SI 3 "=X,x"))]
5456 "!TARGET_64BIT
5457 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5458 && TARGET_SSE"
5459 "#"
5460 [(set_attr "type" "multi")
5461 (set_attr "mode" "<MODE>")])
5462
5463 (define_split
5464 [(set (match_operand:X87MODEF 0 "register_operand" "")
5465 (unsigned_float:X87MODEF
5466 (match_operand:SI 1 "register_operand" "")))
5467 (clobber (match_operand:DI 2 "memory_operand" ""))
5468 (clobber (match_scratch:SI 3 ""))]
5469 "!TARGET_64BIT
5470 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5471 && TARGET_SSE
5472 && reload_completed"
5473 [(set (match_dup 2) (match_dup 1))
5474 (set (match_dup 0)
5475 (float:X87MODEF (match_dup 2)))]
5476 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5477
5478 (define_split
5479 [(set (match_operand:X87MODEF 0 "register_operand" "")
5480 (unsigned_float:X87MODEF
5481 (match_operand:SI 1 "memory_operand" "")))
5482 (clobber (match_operand:DI 2 "memory_operand" ""))
5483 (clobber (match_scratch:SI 3 ""))]
5484 "!TARGET_64BIT
5485 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5486 && TARGET_SSE
5487 && reload_completed"
5488 [(set (match_dup 2) (match_dup 3))
5489 (set (match_dup 0)
5490 (float:X87MODEF (match_dup 2)))]
5491 {
5492 emit_move_insn (operands[3], operands[1]);
5493 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5494 })
5495
5496 (define_expand "floatunssi<mode>2"
5497 [(parallel
5498 [(set (match_operand:X87MODEF 0 "register_operand" "")
5499 (unsigned_float:X87MODEF
5500 (match_operand:SI 1 "nonimmediate_operand" "")))
5501 (clobber (match_dup 2))
5502 (clobber (match_scratch:SI 3 ""))])]
5503 "!TARGET_64BIT
5504 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5505 && TARGET_SSE)
5506 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5507 {
5508 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5509 {
5510 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5511 DONE;
5512 }
5513 else
5514 {
5515 enum ix86_stack_slot slot = (virtuals_instantiated
5516 ? SLOT_TEMP
5517 : SLOT_VIRTUAL);
5518 operands[2] = assign_386_stack_local (DImode, slot);
5519 }
5520 })
5521
5522 (define_expand "floatunsdisf2"
5523 [(use (match_operand:SF 0 "register_operand" ""))
5524 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5525 "TARGET_64BIT && TARGET_SSE_MATH"
5526 "x86_emit_floatuns (operands); DONE;")
5527
5528 (define_expand "floatunsdidf2"
5529 [(use (match_operand:DF 0 "register_operand" ""))
5530 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5531 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5532 && TARGET_SSE2 && TARGET_SSE_MATH"
5533 {
5534 if (TARGET_64BIT)
5535 x86_emit_floatuns (operands);
5536 else
5537 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5538 DONE;
5539 })
5540 \f
5541 ;; Add instructions
5542
5543 (define_expand "add<mode>3"
5544 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5545 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5546 (match_operand:SDWIM 2 "<general_operand>" "")))]
5547 ""
5548 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5549
5550 (define_insn_and_split "*add<dwi>3_doubleword"
5551 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5552 (plus:<DWI>
5553 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5554 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5555 (clobber (reg:CC FLAGS_REG))]
5556 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5557 "#"
5558 "reload_completed"
5559 [(parallel [(set (reg:CC FLAGS_REG)
5560 (unspec:CC [(match_dup 1) (match_dup 2)]
5561 UNSPEC_ADD_CARRY))
5562 (set (match_dup 0)
5563 (plus:DWIH (match_dup 1) (match_dup 2)))])
5564 (parallel [(set (match_dup 3)
5565 (plus:DWIH
5566 (match_dup 4)
5567 (plus:DWIH
5568 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5569 (match_dup 5))))
5570 (clobber (reg:CC FLAGS_REG))])]
5571 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5572
5573 (define_insn "*add<mode>3_cc"
5574 [(set (reg:CC FLAGS_REG)
5575 (unspec:CC
5576 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5577 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5578 UNSPEC_ADD_CARRY))
5579 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5580 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5581 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5582 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5583 [(set_attr "type" "alu")
5584 (set_attr "mode" "<MODE>")])
5585
5586 (define_insn "addqi3_cc"
5587 [(set (reg:CC FLAGS_REG)
5588 (unspec:CC
5589 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5590 (match_operand:QI 2 "general_operand" "qn,qm")]
5591 UNSPEC_ADD_CARRY))
5592 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5593 (plus:QI (match_dup 1) (match_dup 2)))]
5594 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5595 "add{b}\t{%2, %0|%0, %2}"
5596 [(set_attr "type" "alu")
5597 (set_attr "mode" "QI")])
5598
5599 (define_insn "*lea_1"
5600 [(set (match_operand:P 0 "register_operand" "=r")
5601 (match_operand:P 1 "no_seg_address_operand" "p"))]
5602 ""
5603 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5604 [(set_attr "type" "lea")
5605 (set_attr "mode" "<MODE>")])
5606
5607 (define_insn "*lea_2"
5608 [(set (match_operand:SI 0 "register_operand" "=r")
5609 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5610 "TARGET_64BIT"
5611 "lea{l}\t{%a1, %0|%0, %a1}"
5612 [(set_attr "type" "lea")
5613 (set_attr "mode" "SI")])
5614
5615 (define_insn "*lea_2_zext"
5616 [(set (match_operand:DI 0 "register_operand" "=r")
5617 (zero_extend:DI
5618 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5619 "TARGET_64BIT"
5620 "lea{l}\t{%a1, %k0|%k0, %a1}"
5621 [(set_attr "type" "lea")
5622 (set_attr "mode" "SI")])
5623
5624 (define_insn "*add<mode>_1"
5625 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5626 (plus:SWI48
5627 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5628 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5629 (clobber (reg:CC FLAGS_REG))]
5630 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5631 {
5632 switch (get_attr_type (insn))
5633 {
5634 case TYPE_LEA:
5635 return "#";
5636
5637 case TYPE_INCDEC:
5638 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5639 if (operands[2] == const1_rtx)
5640 return "inc{<imodesuffix>}\t%0";
5641 else
5642 {
5643 gcc_assert (operands[2] == constm1_rtx);
5644 return "dec{<imodesuffix>}\t%0";
5645 }
5646
5647 default:
5648 /* For most processors, ADD is faster than LEA. This alternative
5649 was added to use ADD as much as possible. */
5650 if (which_alternative == 2)
5651 {
5652 rtx tmp;
5653 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5654 }
5655
5656 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5657 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5658 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5659
5660 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5661 }
5662 }
5663 [(set (attr "type")
5664 (cond [(eq_attr "alternative" "3")
5665 (const_string "lea")
5666 (match_operand:SWI48 2 "incdec_operand" "")
5667 (const_string "incdec")
5668 ]
5669 (const_string "alu")))
5670 (set (attr "length_immediate")
5671 (if_then_else
5672 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5673 (const_string "1")
5674 (const_string "*")))
5675 (set_attr "mode" "<MODE>")])
5676
5677 ;; It may seem that nonimmediate operand is proper one for operand 1.
5678 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5679 ;; we take care in ix86_binary_operator_ok to not allow two memory
5680 ;; operands so proper swapping will be done in reload. This allow
5681 ;; patterns constructed from addsi_1 to match.
5682
5683 (define_insn "*addsi_1_zext"
5684 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5685 (zero_extend:DI
5686 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5687 (match_operand:SI 2 "general_operand" "g,0,li"))))
5688 (clobber (reg:CC FLAGS_REG))]
5689 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5690 {
5691 switch (get_attr_type (insn))
5692 {
5693 case TYPE_LEA:
5694 return "#";
5695
5696 case TYPE_INCDEC:
5697 if (operands[2] == const1_rtx)
5698 return "inc{l}\t%k0";
5699 else
5700 {
5701 gcc_assert (operands[2] == constm1_rtx);
5702 return "dec{l}\t%k0";
5703 }
5704
5705 default:
5706 /* For most processors, ADD is faster than LEA. This alternative
5707 was added to use ADD as much as possible. */
5708 if (which_alternative == 1)
5709 {
5710 rtx tmp;
5711 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5712 }
5713
5714 if (x86_maybe_negate_const_int (&operands[2], SImode))
5715 return "sub{l}\t{%2, %k0|%k0, %2}";
5716
5717 return "add{l}\t{%2, %k0|%k0, %2}";
5718 }
5719 }
5720 [(set (attr "type")
5721 (cond [(eq_attr "alternative" "2")
5722 (const_string "lea")
5723 (match_operand:SI 2 "incdec_operand" "")
5724 (const_string "incdec")
5725 ]
5726 (const_string "alu")))
5727 (set (attr "length_immediate")
5728 (if_then_else
5729 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5730 (const_string "1")
5731 (const_string "*")))
5732 (set_attr "mode" "SI")])
5733
5734 (define_insn "*addhi_1"
5735 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5736 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5737 (match_operand:HI 2 "general_operand" "rn,rm")))
5738 (clobber (reg:CC FLAGS_REG))]
5739 "TARGET_PARTIAL_REG_STALL
5740 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5741 {
5742 switch (get_attr_type (insn))
5743 {
5744 case TYPE_INCDEC:
5745 if (operands[2] == const1_rtx)
5746 return "inc{w}\t%0";
5747 else
5748 {
5749 gcc_assert (operands[2] == constm1_rtx);
5750 return "dec{w}\t%0";
5751 }
5752
5753 default:
5754 if (x86_maybe_negate_const_int (&operands[2], HImode))
5755 return "sub{w}\t{%2, %0|%0, %2}";
5756
5757 return "add{w}\t{%2, %0|%0, %2}";
5758 }
5759 }
5760 [(set (attr "type")
5761 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5762 (const_string "incdec")
5763 (const_string "alu")))
5764 (set (attr "length_immediate")
5765 (if_then_else
5766 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5767 (const_string "1")
5768 (const_string "*")))
5769 (set_attr "mode" "HI")])
5770
5771 (define_insn "*addhi_1_lea"
5772 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5773 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5774 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5775 (clobber (reg:CC FLAGS_REG))]
5776 "!TARGET_PARTIAL_REG_STALL
5777 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5778 {
5779 switch (get_attr_type (insn))
5780 {
5781 case TYPE_LEA:
5782 return "#";
5783
5784 case TYPE_INCDEC:
5785 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5786 if (operands[2] == const1_rtx)
5787 return "inc{w}\t%0";
5788 else
5789 {
5790 gcc_assert (operands[2] == constm1_rtx);
5791 return "dec{w}\t%0";
5792 }
5793
5794 default:
5795 /* For most processors, ADD is faster than LEA. This alternative
5796 was added to use ADD as much as possible. */
5797 if (which_alternative == 2)
5798 {
5799 rtx tmp;
5800 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5801 }
5802
5803 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5804 if (x86_maybe_negate_const_int (&operands[2], HImode))
5805 return "sub{w}\t{%2, %0|%0, %2}";
5806
5807 return "add{w}\t{%2, %0|%0, %2}";
5808 }
5809 }
5810 [(set (attr "type")
5811 (cond [(eq_attr "alternative" "3")
5812 (const_string "lea")
5813 (match_operand:HI 2 "incdec_operand" "")
5814 (const_string "incdec")
5815 ]
5816 (const_string "alu")))
5817 (set (attr "length_immediate")
5818 (if_then_else
5819 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5820 (const_string "1")
5821 (const_string "*")))
5822 (set_attr "mode" "HI,HI,HI,SI")])
5823
5824 ;; %%% Potential partial reg stall on alternative 2. What to do?
5825 (define_insn "*addqi_1"
5826 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5827 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5828 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5829 (clobber (reg:CC FLAGS_REG))]
5830 "TARGET_PARTIAL_REG_STALL
5831 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5832 {
5833 int widen = (which_alternative == 2);
5834 switch (get_attr_type (insn))
5835 {
5836 case TYPE_INCDEC:
5837 if (operands[2] == const1_rtx)
5838 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5839 else
5840 {
5841 gcc_assert (operands[2] == constm1_rtx);
5842 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5843 }
5844
5845 default:
5846 if (x86_maybe_negate_const_int (&operands[2], QImode))
5847 {
5848 if (widen)
5849 return "sub{l}\t{%2, %k0|%k0, %2}";
5850 else
5851 return "sub{b}\t{%2, %0|%0, %2}";
5852 }
5853 if (widen)
5854 return "add{l}\t{%k2, %k0|%k0, %k2}";
5855 else
5856 return "add{b}\t{%2, %0|%0, %2}";
5857 }
5858 }
5859 [(set (attr "type")
5860 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5861 (const_string "incdec")
5862 (const_string "alu")))
5863 (set (attr "length_immediate")
5864 (if_then_else
5865 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5866 (const_string "1")
5867 (const_string "*")))
5868 (set_attr "mode" "QI,QI,SI")])
5869
5870 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5871 (define_insn "*addqi_1_lea"
5872 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5873 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5874 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5875 (clobber (reg:CC FLAGS_REG))]
5876 "!TARGET_PARTIAL_REG_STALL
5877 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5878 {
5879 int widen = (which_alternative == 3 || which_alternative == 4);
5880
5881 switch (get_attr_type (insn))
5882 {
5883 case TYPE_LEA:
5884 return "#";
5885
5886 case TYPE_INCDEC:
5887 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5888 if (operands[2] == const1_rtx)
5889 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5890 else
5891 {
5892 gcc_assert (operands[2] == constm1_rtx);
5893 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5894 }
5895
5896 default:
5897 /* For most processors, ADD is faster than LEA. These alternatives
5898 were added to use ADD as much as possible. */
5899 if (which_alternative == 2 || which_alternative == 4)
5900 {
5901 rtx tmp;
5902 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5903 }
5904
5905 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5906 if (x86_maybe_negate_const_int (&operands[2], QImode))
5907 {
5908 if (widen)
5909 return "sub{l}\t{%2, %k0|%k0, %2}";
5910 else
5911 return "sub{b}\t{%2, %0|%0, %2}";
5912 }
5913 if (widen)
5914 return "add{l}\t{%k2, %k0|%k0, %k2}";
5915 else
5916 return "add{b}\t{%2, %0|%0, %2}";
5917 }
5918 }
5919 [(set (attr "type")
5920 (cond [(eq_attr "alternative" "5")
5921 (const_string "lea")
5922 (match_operand:QI 2 "incdec_operand" "")
5923 (const_string "incdec")
5924 ]
5925 (const_string "alu")))
5926 (set (attr "length_immediate")
5927 (if_then_else
5928 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5929 (const_string "1")
5930 (const_string "*")))
5931 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5932
5933 (define_insn "*addqi_1_slp"
5934 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5935 (plus:QI (match_dup 0)
5936 (match_operand:QI 1 "general_operand" "qn,qnm")))
5937 (clobber (reg:CC FLAGS_REG))]
5938 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5939 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5940 {
5941 switch (get_attr_type (insn))
5942 {
5943 case TYPE_INCDEC:
5944 if (operands[1] == const1_rtx)
5945 return "inc{b}\t%0";
5946 else
5947 {
5948 gcc_assert (operands[1] == constm1_rtx);
5949 return "dec{b}\t%0";
5950 }
5951
5952 default:
5953 if (x86_maybe_negate_const_int (&operands[1], QImode))
5954 return "sub{b}\t{%1, %0|%0, %1}";
5955
5956 return "add{b}\t{%1, %0|%0, %1}";
5957 }
5958 }
5959 [(set (attr "type")
5960 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5961 (const_string "incdec")
5962 (const_string "alu1")))
5963 (set (attr "memory")
5964 (if_then_else (match_operand 1 "memory_operand" "")
5965 (const_string "load")
5966 (const_string "none")))
5967 (set_attr "mode" "QI")])
5968
5969 ;; Convert lea to the lea pattern to avoid flags dependency.
5970 (define_split
5971 [(set (match_operand 0 "register_operand" "")
5972 (plus (match_operand 1 "register_operand" "")
5973 (match_operand 2 "nonmemory_operand" "")))
5974 (clobber (reg:CC FLAGS_REG))]
5975 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5976 [(const_int 0)]
5977 {
5978 rtx pat;
5979 enum machine_mode mode = GET_MODE (operands[0]);
5980
5981 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5982 may confuse gen_lowpart. */
5983 if (mode != Pmode)
5984 {
5985 operands[1] = gen_lowpart (Pmode, operands[1]);
5986 operands[2] = gen_lowpart (Pmode, operands[2]);
5987 }
5988
5989 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5990
5991 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5992 operands[0] = gen_lowpart (SImode, operands[0]);
5993
5994 if (TARGET_64BIT && mode != Pmode)
5995 pat = gen_rtx_SUBREG (SImode, pat, 0);
5996
5997 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5998 DONE;
5999 })
6000
6001 ;; Convert lea to the lea pattern to avoid flags dependency.
6002 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6003 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6004 (define_split
6005 [(set (match_operand:DI 0 "register_operand" "")
6006 (plus:DI (match_operand:DI 1 "register_operand" "")
6007 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6008 (clobber (reg:CC FLAGS_REG))]
6009 "TARGET_64BIT && reload_completed
6010 && true_regnum (operands[0]) != true_regnum (operands[1])"
6011 [(set (match_dup 0)
6012 (plus:DI (match_dup 1) (match_dup 2)))])
6013
6014 ;; Convert lea to the lea pattern to avoid flags dependency.
6015 (define_split
6016 [(set (match_operand:DI 0 "register_operand" "")
6017 (zero_extend:DI
6018 (plus:SI (match_operand:SI 1 "register_operand" "")
6019 (match_operand:SI 2 "nonmemory_operand" ""))))
6020 (clobber (reg:CC FLAGS_REG))]
6021 "TARGET_64BIT && reload_completed
6022 && ix86_lea_for_add_ok (insn, operands)"
6023 [(set (match_dup 0)
6024 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6025 {
6026 operands[1] = gen_lowpart (DImode, operands[1]);
6027 operands[2] = gen_lowpart (DImode, operands[2]);
6028 })
6029
6030 (define_insn "*add<mode>_2"
6031 [(set (reg FLAGS_REG)
6032 (compare
6033 (plus:SWI
6034 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6035 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6036 (const_int 0)))
6037 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6038 (plus:SWI (match_dup 1) (match_dup 2)))]
6039 "ix86_match_ccmode (insn, CCGOCmode)
6040 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6041 {
6042 switch (get_attr_type (insn))
6043 {
6044 case TYPE_INCDEC:
6045 if (operands[2] == const1_rtx)
6046 return "inc{<imodesuffix>}\t%0";
6047 else
6048 {
6049 gcc_assert (operands[2] == constm1_rtx);
6050 return "dec{<imodesuffix>}\t%0";
6051 }
6052
6053 default:
6054 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6055 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6056
6057 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6058 }
6059 }
6060 [(set (attr "type")
6061 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6062 (const_string "incdec")
6063 (const_string "alu")))
6064 (set (attr "length_immediate")
6065 (if_then_else
6066 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6067 (const_string "1")
6068 (const_string "*")))
6069 (set_attr "mode" "<MODE>")])
6070
6071 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6072 (define_insn "*addsi_2_zext"
6073 [(set (reg FLAGS_REG)
6074 (compare
6075 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6076 (match_operand:SI 2 "general_operand" "g"))
6077 (const_int 0)))
6078 (set (match_operand:DI 0 "register_operand" "=r")
6079 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6080 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6081 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6082 {
6083 switch (get_attr_type (insn))
6084 {
6085 case TYPE_INCDEC:
6086 if (operands[2] == const1_rtx)
6087 return "inc{l}\t%k0";
6088 else
6089 {
6090 gcc_assert (operands[2] == constm1_rtx);
6091 return "dec{l}\t%k0";
6092 }
6093
6094 default:
6095 if (x86_maybe_negate_const_int (&operands[2], SImode))
6096 return "sub{l}\t{%2, %k0|%k0, %2}";
6097
6098 return "add{l}\t{%2, %k0|%k0, %2}";
6099 }
6100 }
6101 [(set (attr "type")
6102 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6103 (const_string "incdec")
6104 (const_string "alu")))
6105 (set (attr "length_immediate")
6106 (if_then_else
6107 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6108 (const_string "1")
6109 (const_string "*")))
6110 (set_attr "mode" "SI")])
6111
6112 (define_insn "*add<mode>_3"
6113 [(set (reg FLAGS_REG)
6114 (compare
6115 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6116 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6117 (clobber (match_scratch:SWI 0 "=<r>"))]
6118 "ix86_match_ccmode (insn, CCZmode)
6119 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6120 {
6121 switch (get_attr_type (insn))
6122 {
6123 case TYPE_INCDEC:
6124 if (operands[2] == const1_rtx)
6125 return "inc{<imodesuffix>}\t%0";
6126 else
6127 {
6128 gcc_assert (operands[2] == constm1_rtx);
6129 return "dec{<imodesuffix>}\t%0";
6130 }
6131
6132 default:
6133 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6134 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6135
6136 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6137 }
6138 }
6139 [(set (attr "type")
6140 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6141 (const_string "incdec")
6142 (const_string "alu")))
6143 (set (attr "length_immediate")
6144 (if_then_else
6145 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6146 (const_string "1")
6147 (const_string "*")))
6148 (set_attr "mode" "<MODE>")])
6149
6150 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6151 (define_insn "*addsi_3_zext"
6152 [(set (reg FLAGS_REG)
6153 (compare
6154 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6155 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6156 (set (match_operand:DI 0 "register_operand" "=r")
6157 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6158 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6159 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6160 {
6161 switch (get_attr_type (insn))
6162 {
6163 case TYPE_INCDEC:
6164 if (operands[2] == const1_rtx)
6165 return "inc{l}\t%k0";
6166 else
6167 {
6168 gcc_assert (operands[2] == constm1_rtx);
6169 return "dec{l}\t%k0";
6170 }
6171
6172 default:
6173 if (x86_maybe_negate_const_int (&operands[2], SImode))
6174 return "sub{l}\t{%2, %k0|%k0, %2}";
6175
6176 return "add{l}\t{%2, %k0|%k0, %2}";
6177 }
6178 }
6179 [(set (attr "type")
6180 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6181 (const_string "incdec")
6182 (const_string "alu")))
6183 (set (attr "length_immediate")
6184 (if_then_else
6185 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6186 (const_string "1")
6187 (const_string "*")))
6188 (set_attr "mode" "SI")])
6189
6190 ; For comparisons against 1, -1 and 128, we may generate better code
6191 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6192 ; is matched then. We can't accept general immediate, because for
6193 ; case of overflows, the result is messed up.
6194 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6195 ; only for comparisons not depending on it.
6196
6197 (define_insn "*adddi_4"
6198 [(set (reg FLAGS_REG)
6199 (compare
6200 (match_operand:DI 1 "nonimmediate_operand" "0")
6201 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6202 (clobber (match_scratch:DI 0 "=rm"))]
6203 "TARGET_64BIT
6204 && ix86_match_ccmode (insn, CCGCmode)"
6205 {
6206 switch (get_attr_type (insn))
6207 {
6208 case TYPE_INCDEC:
6209 if (operands[2] == constm1_rtx)
6210 return "inc{q}\t%0";
6211 else
6212 {
6213 gcc_assert (operands[2] == const1_rtx);
6214 return "dec{q}\t%0";
6215 }
6216
6217 default:
6218 if (x86_maybe_negate_const_int (&operands[2], DImode))
6219 return "add{q}\t{%2, %0|%0, %2}";
6220
6221 return "sub{q}\t{%2, %0|%0, %2}";
6222 }
6223 }
6224 [(set (attr "type")
6225 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6226 (const_string "incdec")
6227 (const_string "alu")))
6228 (set (attr "length_immediate")
6229 (if_then_else
6230 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6231 (const_string "1")
6232 (const_string "*")))
6233 (set_attr "mode" "DI")])
6234
6235 ; For comparisons against 1, -1 and 128, we may generate better code
6236 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6237 ; is matched then. We can't accept general immediate, because for
6238 ; case of overflows, the result is messed up.
6239 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6240 ; only for comparisons not depending on it.
6241
6242 (define_insn "*add<mode>_4"
6243 [(set (reg FLAGS_REG)
6244 (compare
6245 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6246 (match_operand:SWI124 2 "const_int_operand" "n")))
6247 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6248 "ix86_match_ccmode (insn, CCGCmode)"
6249 {
6250 switch (get_attr_type (insn))
6251 {
6252 case TYPE_INCDEC:
6253 if (operands[2] == constm1_rtx)
6254 return "inc{<imodesuffix>}\t%0";
6255 else
6256 {
6257 gcc_assert (operands[2] == const1_rtx);
6258 return "dec{<imodesuffix>}\t%0";
6259 }
6260
6261 default:
6262 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6263 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6264
6265 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6266 }
6267 }
6268 [(set (attr "type")
6269 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6270 (const_string "incdec")
6271 (const_string "alu")))
6272 (set (attr "length_immediate")
6273 (if_then_else
6274 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6275 (const_string "1")
6276 (const_string "*")))
6277 (set_attr "mode" "<MODE>")])
6278
6279 (define_insn "*add<mode>_5"
6280 [(set (reg FLAGS_REG)
6281 (compare
6282 (plus:SWI
6283 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6284 (match_operand:SWI 2 "<general_operand>" "<g>"))
6285 (const_int 0)))
6286 (clobber (match_scratch:SWI 0 "=<r>"))]
6287 "ix86_match_ccmode (insn, CCGOCmode)
6288 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6289 {
6290 switch (get_attr_type (insn))
6291 {
6292 case TYPE_INCDEC:
6293 if (operands[2] == const1_rtx)
6294 return "inc{<imodesuffix>}\t%0";
6295 else
6296 {
6297 gcc_assert (operands[2] == constm1_rtx);
6298 return "dec{<imodesuffix>}\t%0";
6299 }
6300
6301 default:
6302 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6303 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6304
6305 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6306 }
6307 }
6308 [(set (attr "type")
6309 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu")))
6312 (set (attr "length_immediate")
6313 (if_then_else
6314 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6315 (const_string "1")
6316 (const_string "*")))
6317 (set_attr "mode" "<MODE>")])
6318
6319 (define_insn "*addqi_ext_1_rex64"
6320 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6321 (const_int 8)
6322 (const_int 8))
6323 (plus:SI
6324 (zero_extract:SI
6325 (match_operand 1 "ext_register_operand" "0")
6326 (const_int 8)
6327 (const_int 8))
6328 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6329 (clobber (reg:CC FLAGS_REG))]
6330 "TARGET_64BIT"
6331 {
6332 switch (get_attr_type (insn))
6333 {
6334 case TYPE_INCDEC:
6335 if (operands[2] == const1_rtx)
6336 return "inc{b}\t%h0";
6337 else
6338 {
6339 gcc_assert (operands[2] == constm1_rtx);
6340 return "dec{b}\t%h0";
6341 }
6342
6343 default:
6344 return "add{b}\t{%2, %h0|%h0, %2}";
6345 }
6346 }
6347 [(set (attr "type")
6348 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6349 (const_string "incdec")
6350 (const_string "alu")))
6351 (set_attr "modrm" "1")
6352 (set_attr "mode" "QI")])
6353
6354 (define_insn "addqi_ext_1"
6355 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6356 (const_int 8)
6357 (const_int 8))
6358 (plus:SI
6359 (zero_extract:SI
6360 (match_operand 1 "ext_register_operand" "0")
6361 (const_int 8)
6362 (const_int 8))
6363 (match_operand:QI 2 "general_operand" "Qmn")))
6364 (clobber (reg:CC FLAGS_REG))]
6365 "!TARGET_64BIT"
6366 {
6367 switch (get_attr_type (insn))
6368 {
6369 case TYPE_INCDEC:
6370 if (operands[2] == const1_rtx)
6371 return "inc{b}\t%h0";
6372 else
6373 {
6374 gcc_assert (operands[2] == constm1_rtx);
6375 return "dec{b}\t%h0";
6376 }
6377
6378 default:
6379 return "add{b}\t{%2, %h0|%h0, %2}";
6380 }
6381 }
6382 [(set (attr "type")
6383 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6384 (const_string "incdec")
6385 (const_string "alu")))
6386 (set_attr "modrm" "1")
6387 (set_attr "mode" "QI")])
6388
6389 (define_insn "*addqi_ext_2"
6390 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6391 (const_int 8)
6392 (const_int 8))
6393 (plus:SI
6394 (zero_extract:SI
6395 (match_operand 1 "ext_register_operand" "%0")
6396 (const_int 8)
6397 (const_int 8))
6398 (zero_extract:SI
6399 (match_operand 2 "ext_register_operand" "Q")
6400 (const_int 8)
6401 (const_int 8))))
6402 (clobber (reg:CC FLAGS_REG))]
6403 ""
6404 "add{b}\t{%h2, %h0|%h0, %h2}"
6405 [(set_attr "type" "alu")
6406 (set_attr "mode" "QI")])
6407
6408 ;; The lea patterns for non-Pmodes needs to be matched by
6409 ;; several insns converted to real lea by splitters.
6410
6411 (define_insn_and_split "*lea_general_1"
6412 [(set (match_operand 0 "register_operand" "=r")
6413 (plus (plus (match_operand 1 "index_register_operand" "l")
6414 (match_operand 2 "register_operand" "r"))
6415 (match_operand 3 "immediate_operand" "i")))]
6416 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6417 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6418 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6419 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6420 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6421 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6422 || GET_MODE (operands[3]) == VOIDmode)"
6423 "#"
6424 "&& reload_completed"
6425 [(const_int 0)]
6426 {
6427 rtx pat;
6428 operands[0] = gen_lowpart (SImode, operands[0]);
6429 operands[1] = gen_lowpart (Pmode, operands[1]);
6430 operands[2] = gen_lowpart (Pmode, operands[2]);
6431 operands[3] = gen_lowpart (Pmode, operands[3]);
6432 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6433 operands[3]);
6434 if (Pmode != SImode)
6435 pat = gen_rtx_SUBREG (SImode, pat, 0);
6436 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6437 DONE;
6438 }
6439 [(set_attr "type" "lea")
6440 (set_attr "mode" "SI")])
6441
6442 (define_insn_and_split "*lea_general_1_zext"
6443 [(set (match_operand:DI 0 "register_operand" "=r")
6444 (zero_extend:DI
6445 (plus:SI (plus:SI
6446 (match_operand:SI 1 "index_register_operand" "l")
6447 (match_operand:SI 2 "register_operand" "r"))
6448 (match_operand:SI 3 "immediate_operand" "i"))))]
6449 "TARGET_64BIT"
6450 "#"
6451 "&& reload_completed"
6452 [(set (match_dup 0)
6453 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6454 (match_dup 2))
6455 (match_dup 3)) 0)))]
6456 {
6457 operands[1] = gen_lowpart (Pmode, operands[1]);
6458 operands[2] = gen_lowpart (Pmode, operands[2]);
6459 operands[3] = gen_lowpart (Pmode, operands[3]);
6460 }
6461 [(set_attr "type" "lea")
6462 (set_attr "mode" "SI")])
6463
6464 (define_insn_and_split "*lea_general_2"
6465 [(set (match_operand 0 "register_operand" "=r")
6466 (plus (mult (match_operand 1 "index_register_operand" "l")
6467 (match_operand 2 "const248_operand" "i"))
6468 (match_operand 3 "nonmemory_operand" "ri")))]
6469 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6470 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6471 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6472 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6473 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6474 || GET_MODE (operands[3]) == VOIDmode)"
6475 "#"
6476 "&& reload_completed"
6477 [(const_int 0)]
6478 {
6479 rtx pat;
6480 operands[0] = gen_lowpart (SImode, operands[0]);
6481 operands[1] = gen_lowpart (Pmode, operands[1]);
6482 operands[3] = gen_lowpart (Pmode, operands[3]);
6483 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6484 operands[3]);
6485 if (Pmode != SImode)
6486 pat = gen_rtx_SUBREG (SImode, pat, 0);
6487 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6488 DONE;
6489 }
6490 [(set_attr "type" "lea")
6491 (set_attr "mode" "SI")])
6492
6493 (define_insn_and_split "*lea_general_2_zext"
6494 [(set (match_operand:DI 0 "register_operand" "=r")
6495 (zero_extend:DI
6496 (plus:SI (mult:SI
6497 (match_operand:SI 1 "index_register_operand" "l")
6498 (match_operand:SI 2 "const248_operand" "n"))
6499 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6500 "TARGET_64BIT"
6501 "#"
6502 "&& reload_completed"
6503 [(set (match_dup 0)
6504 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6505 (match_dup 2))
6506 (match_dup 3)) 0)))]
6507 {
6508 operands[1] = gen_lowpart (Pmode, operands[1]);
6509 operands[3] = gen_lowpart (Pmode, operands[3]);
6510 }
6511 [(set_attr "type" "lea")
6512 (set_attr "mode" "SI")])
6513
6514 (define_insn_and_split "*lea_general_3"
6515 [(set (match_operand 0 "register_operand" "=r")
6516 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6517 (match_operand 2 "const248_operand" "i"))
6518 (match_operand 3 "register_operand" "r"))
6519 (match_operand 4 "immediate_operand" "i")))]
6520 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6521 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6522 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6523 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6524 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6525 "#"
6526 "&& reload_completed"
6527 [(const_int 0)]
6528 {
6529 rtx pat;
6530 operands[0] = gen_lowpart (SImode, operands[0]);
6531 operands[1] = gen_lowpart (Pmode, operands[1]);
6532 operands[3] = gen_lowpart (Pmode, operands[3]);
6533 operands[4] = gen_lowpart (Pmode, operands[4]);
6534 pat = gen_rtx_PLUS (Pmode,
6535 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6536 operands[2]),
6537 operands[3]),
6538 operands[4]);
6539 if (Pmode != SImode)
6540 pat = gen_rtx_SUBREG (SImode, pat, 0);
6541 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6542 DONE;
6543 }
6544 [(set_attr "type" "lea")
6545 (set_attr "mode" "SI")])
6546
6547 (define_insn_and_split "*lea_general_3_zext"
6548 [(set (match_operand:DI 0 "register_operand" "=r")
6549 (zero_extend:DI
6550 (plus:SI (plus:SI
6551 (mult:SI
6552 (match_operand:SI 1 "index_register_operand" "l")
6553 (match_operand:SI 2 "const248_operand" "n"))
6554 (match_operand:SI 3 "register_operand" "r"))
6555 (match_operand:SI 4 "immediate_operand" "i"))))]
6556 "TARGET_64BIT"
6557 "#"
6558 "&& reload_completed"
6559 [(set (match_dup 0)
6560 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6561 (match_dup 2))
6562 (match_dup 3))
6563 (match_dup 4)) 0)))]
6564 {
6565 operands[1] = gen_lowpart (Pmode, operands[1]);
6566 operands[3] = gen_lowpart (Pmode, operands[3]);
6567 operands[4] = gen_lowpart (Pmode, operands[4]);
6568 }
6569 [(set_attr "type" "lea")
6570 (set_attr "mode" "SI")])
6571 \f
6572 ;; Subtract instructions
6573
6574 (define_expand "sub<mode>3"
6575 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6576 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6577 (match_operand:SDWIM 2 "<general_operand>" "")))]
6578 ""
6579 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6580
6581 (define_insn_and_split "*sub<dwi>3_doubleword"
6582 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6583 (minus:<DWI>
6584 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6585 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6586 (clobber (reg:CC FLAGS_REG))]
6587 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6588 "#"
6589 "reload_completed"
6590 [(parallel [(set (reg:CC FLAGS_REG)
6591 (compare:CC (match_dup 1) (match_dup 2)))
6592 (set (match_dup 0)
6593 (minus:DWIH (match_dup 1) (match_dup 2)))])
6594 (parallel [(set (match_dup 3)
6595 (minus:DWIH
6596 (match_dup 4)
6597 (plus:DWIH
6598 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6599 (match_dup 5))))
6600 (clobber (reg:CC FLAGS_REG))])]
6601 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6602
6603 (define_insn "*sub<mode>_1"
6604 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6605 (minus:SWI
6606 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6607 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6608 (clobber (reg:CC FLAGS_REG))]
6609 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6610 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6611 [(set_attr "type" "alu")
6612 (set_attr "mode" "<MODE>")])
6613
6614 (define_insn "*subsi_1_zext"
6615 [(set (match_operand:DI 0 "register_operand" "=r")
6616 (zero_extend:DI
6617 (minus:SI (match_operand:SI 1 "register_operand" "0")
6618 (match_operand:SI 2 "general_operand" "g"))))
6619 (clobber (reg:CC FLAGS_REG))]
6620 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6621 "sub{l}\t{%2, %k0|%k0, %2}"
6622 [(set_attr "type" "alu")
6623 (set_attr "mode" "SI")])
6624
6625 (define_insn "*subqi_1_slp"
6626 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6627 (minus:QI (match_dup 0)
6628 (match_operand:QI 1 "general_operand" "qn,qm")))
6629 (clobber (reg:CC FLAGS_REG))]
6630 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6632 "sub{b}\t{%1, %0|%0, %1}"
6633 [(set_attr "type" "alu1")
6634 (set_attr "mode" "QI")])
6635
6636 (define_insn "*sub<mode>_2"
6637 [(set (reg FLAGS_REG)
6638 (compare
6639 (minus:SWI
6640 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6641 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6642 (const_int 0)))
6643 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6644 (minus:SWI (match_dup 1) (match_dup 2)))]
6645 "ix86_match_ccmode (insn, CCGOCmode)
6646 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6647 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "mode" "<MODE>")])
6650
6651 (define_insn "*subsi_2_zext"
6652 [(set (reg FLAGS_REG)
6653 (compare
6654 (minus:SI (match_operand:SI 1 "register_operand" "0")
6655 (match_operand:SI 2 "general_operand" "g"))
6656 (const_int 0)))
6657 (set (match_operand:DI 0 "register_operand" "=r")
6658 (zero_extend:DI
6659 (minus:SI (match_dup 1)
6660 (match_dup 2))))]
6661 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6662 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6663 "sub{l}\t{%2, %k0|%k0, %2}"
6664 [(set_attr "type" "alu")
6665 (set_attr "mode" "SI")])
6666
6667 (define_insn "*sub<mode>_3"
6668 [(set (reg FLAGS_REG)
6669 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6670 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6671 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6672 (minus:SWI (match_dup 1) (match_dup 2)))]
6673 "ix86_match_ccmode (insn, CCmode)
6674 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6675 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "mode" "<MODE>")])
6678
6679 (define_insn "*subsi_3_zext"
6680 [(set (reg FLAGS_REG)
6681 (compare (match_operand:SI 1 "register_operand" "0")
6682 (match_operand:SI 2 "general_operand" "g")))
6683 (set (match_operand:DI 0 "register_operand" "=r")
6684 (zero_extend:DI
6685 (minus:SI (match_dup 1)
6686 (match_dup 2))))]
6687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6688 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6689 "sub{l}\t{%2, %1|%1, %2}"
6690 [(set_attr "type" "alu")
6691 (set_attr "mode" "SI")])
6692 \f
6693 ;; Add with carry and subtract with borrow
6694
6695 (define_expand "<plusminus_insn><mode>3_carry"
6696 [(parallel
6697 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6698 (plusminus:SWI
6699 (match_operand:SWI 1 "nonimmediate_operand" "")
6700 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6701 [(match_operand 3 "flags_reg_operand" "")
6702 (const_int 0)])
6703 (match_operand:SWI 2 "<general_operand>" ""))))
6704 (clobber (reg:CC FLAGS_REG))])]
6705 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6706
6707 (define_insn "*<plusminus_insn><mode>3_carry"
6708 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6709 (plusminus:SWI
6710 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6711 (plus:SWI
6712 (match_operator 3 "ix86_carry_flag_operator"
6713 [(reg FLAGS_REG) (const_int 0)])
6714 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6715 (clobber (reg:CC FLAGS_REG))]
6716 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6717 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6718 [(set_attr "type" "alu")
6719 (set_attr "use_carry" "1")
6720 (set_attr "pent_pair" "pu")
6721 (set_attr "mode" "<MODE>")])
6722
6723 (define_insn "*addsi3_carry_zext"
6724 [(set (match_operand:DI 0 "register_operand" "=r")
6725 (zero_extend:DI
6726 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6727 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6728 [(reg FLAGS_REG) (const_int 0)])
6729 (match_operand:SI 2 "general_operand" "g")))))
6730 (clobber (reg:CC FLAGS_REG))]
6731 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6732 "adc{l}\t{%2, %k0|%k0, %2}"
6733 [(set_attr "type" "alu")
6734 (set_attr "use_carry" "1")
6735 (set_attr "pent_pair" "pu")
6736 (set_attr "mode" "SI")])
6737
6738 (define_insn "*subsi3_carry_zext"
6739 [(set (match_operand:DI 0 "register_operand" "=r")
6740 (zero_extend:DI
6741 (minus:SI (match_operand:SI 1 "register_operand" "0")
6742 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6743 [(reg FLAGS_REG) (const_int 0)])
6744 (match_operand:SI 2 "general_operand" "g")))))
6745 (clobber (reg:CC FLAGS_REG))]
6746 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747 "sbb{l}\t{%2, %k0|%k0, %2}"
6748 [(set_attr "type" "alu")
6749 (set_attr "pent_pair" "pu")
6750 (set_attr "mode" "SI")])
6751 \f
6752 ;; Overflow setting add and subtract instructions
6753
6754 (define_insn "*add<mode>3_cconly_overflow"
6755 [(set (reg:CCC FLAGS_REG)
6756 (compare:CCC
6757 (plus:SWI
6758 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6759 (match_operand:SWI 2 "<general_operand>" "<g>"))
6760 (match_dup 1)))
6761 (clobber (match_scratch:SWI 0 "=<r>"))]
6762 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6763 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "<MODE>")])
6766
6767 (define_insn "*sub<mode>3_cconly_overflow"
6768 [(set (reg:CCC FLAGS_REG)
6769 (compare:CCC
6770 (minus:SWI
6771 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6772 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6773 (match_dup 0)))]
6774 ""
6775 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6776 [(set_attr "type" "icmp")
6777 (set_attr "mode" "<MODE>")])
6778
6779 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6780 [(set (reg:CCC FLAGS_REG)
6781 (compare:CCC
6782 (plusminus:SWI
6783 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6784 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6785 (match_dup 1)))
6786 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6787 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6788 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6789 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6790 [(set_attr "type" "alu")
6791 (set_attr "mode" "<MODE>")])
6792
6793 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6794 [(set (reg:CCC FLAGS_REG)
6795 (compare:CCC
6796 (plusminus:SI
6797 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6798 (match_operand:SI 2 "general_operand" "g"))
6799 (match_dup 1)))
6800 (set (match_operand:DI 0 "register_operand" "=r")
6801 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6802 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6803 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6804 [(set_attr "type" "alu")
6805 (set_attr "mode" "SI")])
6806
6807 ;; The patterns that match these are at the end of this file.
6808
6809 (define_expand "<plusminus_insn>xf3"
6810 [(set (match_operand:XF 0 "register_operand" "")
6811 (plusminus:XF
6812 (match_operand:XF 1 "register_operand" "")
6813 (match_operand:XF 2 "register_operand" "")))]
6814 "TARGET_80387")
6815
6816 (define_expand "<plusminus_insn><mode>3"
6817 [(set (match_operand:MODEF 0 "register_operand" "")
6818 (plusminus:MODEF
6819 (match_operand:MODEF 1 "register_operand" "")
6820 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6821 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6822 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6823 \f
6824 ;; Multiply instructions
6825
6826 (define_expand "mul<mode>3"
6827 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6828 (mult:SWIM248
6829 (match_operand:SWIM248 1 "register_operand" "")
6830 (match_operand:SWIM248 2 "<general_operand>" "")))
6831 (clobber (reg:CC FLAGS_REG))])])
6832
6833 (define_expand "mulqi3"
6834 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6835 (mult:QI
6836 (match_operand:QI 1 "register_operand" "")
6837 (match_operand:QI 2 "nonimmediate_operand" "")))
6838 (clobber (reg:CC FLAGS_REG))])]
6839 "TARGET_QIMODE_MATH")
6840
6841 ;; On AMDFAM10
6842 ;; IMUL reg32/64, reg32/64, imm8 Direct
6843 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6844 ;; IMUL reg32/64, reg32/64, imm32 Direct
6845 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6846 ;; IMUL reg32/64, reg32/64 Direct
6847 ;; IMUL reg32/64, mem32/64 Direct
6848
6849 (define_insn "*mul<mode>3_1"
6850 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6851 (mult:SWI48
6852 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6853 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6854 (clobber (reg:CC FLAGS_REG))]
6855 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 "@
6857 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6858 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6859 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6860 [(set_attr "type" "imul")
6861 (set_attr "prefix_0f" "0,0,1")
6862 (set (attr "athlon_decode")
6863 (cond [(eq_attr "cpu" "athlon")
6864 (const_string "vector")
6865 (eq_attr "alternative" "1")
6866 (const_string "vector")
6867 (and (eq_attr "alternative" "2")
6868 (match_operand 1 "memory_operand" ""))
6869 (const_string "vector")]
6870 (const_string "direct")))
6871 (set (attr "amdfam10_decode")
6872 (cond [(and (eq_attr "alternative" "0,1")
6873 (match_operand 1 "memory_operand" ""))
6874 (const_string "vector")]
6875 (const_string "direct")))
6876 (set_attr "mode" "<MODE>")])
6877
6878 (define_insn "*mulsi3_1_zext"
6879 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6880 (zero_extend:DI
6881 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6882 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6883 (clobber (reg:CC FLAGS_REG))]
6884 "TARGET_64BIT
6885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6886 "@
6887 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6888 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6889 imul{l}\t{%2, %k0|%k0, %2}"
6890 [(set_attr "type" "imul")
6891 (set_attr "prefix_0f" "0,0,1")
6892 (set (attr "athlon_decode")
6893 (cond [(eq_attr "cpu" "athlon")
6894 (const_string "vector")
6895 (eq_attr "alternative" "1")
6896 (const_string "vector")
6897 (and (eq_attr "alternative" "2")
6898 (match_operand 1 "memory_operand" ""))
6899 (const_string "vector")]
6900 (const_string "direct")))
6901 (set (attr "amdfam10_decode")
6902 (cond [(and (eq_attr "alternative" "0,1")
6903 (match_operand 1 "memory_operand" ""))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set_attr "mode" "SI")])
6907
6908 ;; On AMDFAM10
6909 ;; IMUL reg16, reg16, imm8 VectorPath
6910 ;; IMUL reg16, mem16, imm8 VectorPath
6911 ;; IMUL reg16, reg16, imm16 VectorPath
6912 ;; IMUL reg16, mem16, imm16 VectorPath
6913 ;; IMUL reg16, reg16 Direct
6914 ;; IMUL reg16, mem16 Direct
6915
6916 (define_insn "*mulhi3_1"
6917 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6918 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6919 (match_operand:HI 2 "general_operand" "K,n,mr")))
6920 (clobber (reg:CC FLAGS_REG))]
6921 "TARGET_HIMODE_MATH
6922 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6923 "@
6924 imul{w}\t{%2, %1, %0|%0, %1, %2}
6925 imul{w}\t{%2, %1, %0|%0, %1, %2}
6926 imul{w}\t{%2, %0|%0, %2}"
6927 [(set_attr "type" "imul")
6928 (set_attr "prefix_0f" "0,0,1")
6929 (set (attr "athlon_decode")
6930 (cond [(eq_attr "cpu" "athlon")
6931 (const_string "vector")
6932 (eq_attr "alternative" "1,2")
6933 (const_string "vector")]
6934 (const_string "direct")))
6935 (set (attr "amdfam10_decode")
6936 (cond [(eq_attr "alternative" "0,1")
6937 (const_string "vector")]
6938 (const_string "direct")))
6939 (set_attr "mode" "HI")])
6940
6941 ;;On AMDFAM10
6942 ;; MUL reg8 Direct
6943 ;; MUL mem8 Direct
6944
6945 (define_insn "*mulqi3_1"
6946 [(set (match_operand:QI 0 "register_operand" "=a")
6947 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6948 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "TARGET_QIMODE_MATH
6951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952 "mul{b}\t%2"
6953 [(set_attr "type" "imul")
6954 (set_attr "length_immediate" "0")
6955 (set (attr "athlon_decode")
6956 (if_then_else (eq_attr "cpu" "athlon")
6957 (const_string "vector")
6958 (const_string "direct")))
6959 (set_attr "amdfam10_decode" "direct")
6960 (set_attr "mode" "QI")])
6961
6962 (define_expand "<u>mul<mode><dwi>3"
6963 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6964 (mult:<DWI>
6965 (any_extend:<DWI>
6966 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6967 (any_extend:<DWI>
6968 (match_operand:DWIH 2 "register_operand" ""))))
6969 (clobber (reg:CC FLAGS_REG))])])
6970
6971 (define_expand "<u>mulqihi3"
6972 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6973 (mult:HI
6974 (any_extend:HI
6975 (match_operand:QI 1 "nonimmediate_operand" ""))
6976 (any_extend:HI
6977 (match_operand:QI 2 "register_operand" ""))))
6978 (clobber (reg:CC FLAGS_REG))])]
6979 "TARGET_QIMODE_MATH")
6980
6981 (define_insn "*<u>mul<mode><dwi>3_1"
6982 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6983 (mult:<DWI>
6984 (any_extend:<DWI>
6985 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6986 (any_extend:<DWI>
6987 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6988 (clobber (reg:CC FLAGS_REG))]
6989 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6990 "<sgnprefix>mul{<imodesuffix>}\t%2"
6991 [(set_attr "type" "imul")
6992 (set_attr "length_immediate" "0")
6993 (set (attr "athlon_decode")
6994 (if_then_else (eq_attr "cpu" "athlon")
6995 (const_string "vector")
6996 (const_string "double")))
6997 (set_attr "amdfam10_decode" "double")
6998 (set_attr "mode" "<MODE>")])
6999
7000 (define_insn "*<u>mulqihi3_1"
7001 [(set (match_operand:HI 0 "register_operand" "=a")
7002 (mult:HI
7003 (any_extend:HI
7004 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7005 (any_extend:HI
7006 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7007 (clobber (reg:CC FLAGS_REG))]
7008 "TARGET_QIMODE_MATH
7009 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7010 "<sgnprefix>mul{b}\t%2"
7011 [(set_attr "type" "imul")
7012 (set_attr "length_immediate" "0")
7013 (set (attr "athlon_decode")
7014 (if_then_else (eq_attr "cpu" "athlon")
7015 (const_string "vector")
7016 (const_string "direct")))
7017 (set_attr "amdfam10_decode" "direct")
7018 (set_attr "mode" "QI")])
7019
7020 (define_expand "<s>mul<mode>3_highpart"
7021 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7022 (truncate:SWI48
7023 (lshiftrt:<DWI>
7024 (mult:<DWI>
7025 (any_extend:<DWI>
7026 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7027 (any_extend:<DWI>
7028 (match_operand:SWI48 2 "register_operand" "")))
7029 (match_dup 4))))
7030 (clobber (match_scratch:SWI48 3 ""))
7031 (clobber (reg:CC FLAGS_REG))])]
7032 ""
7033 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7034
7035 (define_insn "*<s>muldi3_highpart_1"
7036 [(set (match_operand:DI 0 "register_operand" "=d")
7037 (truncate:DI
7038 (lshiftrt:TI
7039 (mult:TI
7040 (any_extend:TI
7041 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7042 (any_extend:TI
7043 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7044 (const_int 64))))
7045 (clobber (match_scratch:DI 3 "=1"))
7046 (clobber (reg:CC FLAGS_REG))]
7047 "TARGET_64BIT
7048 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7049 "<sgnprefix>mul{q}\t%2"
7050 [(set_attr "type" "imul")
7051 (set_attr "length_immediate" "0")
7052 (set (attr "athlon_decode")
7053 (if_then_else (eq_attr "cpu" "athlon")
7054 (const_string "vector")
7055 (const_string "double")))
7056 (set_attr "amdfam10_decode" "double")
7057 (set_attr "mode" "DI")])
7058
7059 (define_insn "*<s>mulsi3_highpart_1"
7060 [(set (match_operand:SI 0 "register_operand" "=d")
7061 (truncate:SI
7062 (lshiftrt:DI
7063 (mult:DI
7064 (any_extend:DI
7065 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7066 (any_extend:DI
7067 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7068 (const_int 32))))
7069 (clobber (match_scratch:SI 3 "=1"))
7070 (clobber (reg:CC FLAGS_REG))]
7071 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7072 "<sgnprefix>mul{l}\t%2"
7073 [(set_attr "type" "imul")
7074 (set_attr "length_immediate" "0")
7075 (set (attr "athlon_decode")
7076 (if_then_else (eq_attr "cpu" "athlon")
7077 (const_string "vector")
7078 (const_string "double")))
7079 (set_attr "amdfam10_decode" "double")
7080 (set_attr "mode" "SI")])
7081
7082 (define_insn "*<s>mulsi3_highpart_zext"
7083 [(set (match_operand:DI 0 "register_operand" "=d")
7084 (zero_extend:DI (truncate:SI
7085 (lshiftrt:DI
7086 (mult:DI (any_extend:DI
7087 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7088 (any_extend:DI
7089 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7090 (const_int 32)))))
7091 (clobber (match_scratch:SI 3 "=1"))
7092 (clobber (reg:CC FLAGS_REG))]
7093 "TARGET_64BIT
7094 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7095 "<sgnprefix>mul{l}\t%2"
7096 [(set_attr "type" "imul")
7097 (set_attr "length_immediate" "0")
7098 (set (attr "athlon_decode")
7099 (if_then_else (eq_attr "cpu" "athlon")
7100 (const_string "vector")
7101 (const_string "double")))
7102 (set_attr "amdfam10_decode" "double")
7103 (set_attr "mode" "SI")])
7104
7105 ;; The patterns that match these are at the end of this file.
7106
7107 (define_expand "mulxf3"
7108 [(set (match_operand:XF 0 "register_operand" "")
7109 (mult:XF (match_operand:XF 1 "register_operand" "")
7110 (match_operand:XF 2 "register_operand" "")))]
7111 "TARGET_80387")
7112
7113 (define_expand "mul<mode>3"
7114 [(set (match_operand:MODEF 0 "register_operand" "")
7115 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7116 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7117 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7118 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7119 \f
7120 ;; Divide instructions
7121
7122 ;; The patterns that match these are at the end of this file.
7123
7124 (define_expand "divxf3"
7125 [(set (match_operand:XF 0 "register_operand" "")
7126 (div:XF (match_operand:XF 1 "register_operand" "")
7127 (match_operand:XF 2 "register_operand" "")))]
7128 "TARGET_80387")
7129
7130 (define_expand "divdf3"
7131 [(set (match_operand:DF 0 "register_operand" "")
7132 (div:DF (match_operand:DF 1 "register_operand" "")
7133 (match_operand:DF 2 "nonimmediate_operand" "")))]
7134 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7135 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7136
7137 (define_expand "divsf3"
7138 [(set (match_operand:SF 0 "register_operand" "")
7139 (div:SF (match_operand:SF 1 "register_operand" "")
7140 (match_operand:SF 2 "nonimmediate_operand" "")))]
7141 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7142 || TARGET_SSE_MATH"
7143 {
7144 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7145 && flag_finite_math_only && !flag_trapping_math
7146 && flag_unsafe_math_optimizations)
7147 {
7148 ix86_emit_swdivsf (operands[0], operands[1],
7149 operands[2], SFmode);
7150 DONE;
7151 }
7152 })
7153 \f
7154 ;; Divmod instructions.
7155
7156 (define_expand "divmod<mode>4"
7157 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7158 (div:SWIM248
7159 (match_operand:SWIM248 1 "register_operand" "")
7160 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7161 (set (match_operand:SWIM248 3 "register_operand" "")
7162 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7163 (clobber (reg:CC FLAGS_REG))])])
7164
7165 ;; Split with 8bit unsigned divide:
7166 ;; if (dividend an divisor are in [0-255])
7167 ;; use 8bit unsigned integer divide
7168 ;; else
7169 ;; use original integer divide
7170 (define_split
7171 [(set (match_operand:SWI48 0 "register_operand" "")
7172 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7173 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7174 (set (match_operand:SWI48 1 "register_operand" "")
7175 (mod:SWI48 (match_dup 2) (match_dup 3)))
7176 (clobber (reg:CC FLAGS_REG))]
7177 "TARGET_USE_8BIT_IDIV
7178 && TARGET_QIMODE_MATH
7179 && can_create_pseudo_p ()
7180 && !optimize_insn_for_size_p ()"
7181 [(const_int 0)]
7182 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7183
7184 (define_insn_and_split "divmod<mode>4_1"
7185 [(set (match_operand:SWI48 0 "register_operand" "=a")
7186 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7187 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7188 (set (match_operand:SWI48 1 "register_operand" "=&d")
7189 (mod:SWI48 (match_dup 2) (match_dup 3)))
7190 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7191 (clobber (reg:CC FLAGS_REG))]
7192 ""
7193 "#"
7194 "reload_completed"
7195 [(parallel [(set (match_dup 1)
7196 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7197 (clobber (reg:CC FLAGS_REG))])
7198 (parallel [(set (match_dup 0)
7199 (div:SWI48 (match_dup 2) (match_dup 3)))
7200 (set (match_dup 1)
7201 (mod:SWI48 (match_dup 2) (match_dup 3)))
7202 (use (match_dup 1))
7203 (clobber (reg:CC FLAGS_REG))])]
7204 {
7205 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7206
7207 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7208 operands[4] = operands[2];
7209 else
7210 {
7211 /* Avoid use of cltd in favor of a mov+shift. */
7212 emit_move_insn (operands[1], operands[2]);
7213 operands[4] = operands[1];
7214 }
7215 }
7216 [(set_attr "type" "multi")
7217 (set_attr "mode" "<MODE>")])
7218
7219 (define_insn_and_split "*divmod<mode>4"
7220 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7221 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7222 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7223 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7224 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7225 (clobber (reg:CC FLAGS_REG))]
7226 ""
7227 "#"
7228 "reload_completed"
7229 [(parallel [(set (match_dup 1)
7230 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7231 (clobber (reg:CC FLAGS_REG))])
7232 (parallel [(set (match_dup 0)
7233 (div:SWIM248 (match_dup 2) (match_dup 3)))
7234 (set (match_dup 1)
7235 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7236 (use (match_dup 1))
7237 (clobber (reg:CC FLAGS_REG))])]
7238 {
7239 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7240
7241 if (<MODE>mode != HImode
7242 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7243 operands[4] = operands[2];
7244 else
7245 {
7246 /* Avoid use of cltd in favor of a mov+shift. */
7247 emit_move_insn (operands[1], operands[2]);
7248 operands[4] = operands[1];
7249 }
7250 }
7251 [(set_attr "type" "multi")
7252 (set_attr "mode" "<MODE>")])
7253
7254 (define_insn "*divmod<mode>4_noext"
7255 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7256 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7257 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7258 (set (match_operand:SWIM248 1 "register_operand" "=d")
7259 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7260 (use (match_operand:SWIM248 4 "register_operand" "1"))
7261 (clobber (reg:CC FLAGS_REG))]
7262 ""
7263 "idiv{<imodesuffix>}\t%3"
7264 [(set_attr "type" "idiv")
7265 (set_attr "mode" "<MODE>")])
7266
7267 (define_expand "divmodqi4"
7268 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7269 (div:QI
7270 (match_operand:QI 1 "register_operand" "")
7271 (match_operand:QI 2 "nonimmediate_operand" "")))
7272 (set (match_operand:QI 3 "register_operand" "")
7273 (mod:QI (match_dup 1) (match_dup 2)))
7274 (clobber (reg:CC FLAGS_REG))])]
7275 "TARGET_QIMODE_MATH"
7276 {
7277 rtx div, mod, insn;
7278 rtx tmp0, tmp1;
7279
7280 tmp0 = gen_reg_rtx (HImode);
7281 tmp1 = gen_reg_rtx (HImode);
7282
7283 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7284 in AX. */
7285 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7286 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7287
7288 /* Extract remainder from AH. */
7289 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7290 insn = emit_move_insn (operands[3], tmp1);
7291
7292 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7293 set_unique_reg_note (insn, REG_EQUAL, mod);
7294
7295 /* Extract quotient from AL. */
7296 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7297
7298 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7299 set_unique_reg_note (insn, REG_EQUAL, div);
7300
7301 DONE;
7302 })
7303
7304 ;; Divide AX by r/m8, with result stored in
7305 ;; AL <- Quotient
7306 ;; AH <- Remainder
7307 ;; Change div/mod to HImode and extend the second argument to HImode
7308 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7309 ;; combine may fail.
7310 (define_insn "divmodhiqi3"
7311 [(set (match_operand:HI 0 "register_operand" "=a")
7312 (ior:HI
7313 (ashift:HI
7314 (zero_extend:HI
7315 (truncate:QI
7316 (mod:HI (match_operand:HI 1 "register_operand" "0")
7317 (sign_extend:HI
7318 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7319 (const_int 8))
7320 (zero_extend:HI
7321 (truncate:QI
7322 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7323 (clobber (reg:CC FLAGS_REG))]
7324 "TARGET_QIMODE_MATH"
7325 "idiv{b}\t%2"
7326 [(set_attr "type" "idiv")
7327 (set_attr "mode" "QI")])
7328
7329 (define_expand "udivmod<mode>4"
7330 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7331 (udiv:SWIM248
7332 (match_operand:SWIM248 1 "register_operand" "")
7333 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7334 (set (match_operand:SWIM248 3 "register_operand" "")
7335 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7336 (clobber (reg:CC FLAGS_REG))])])
7337
7338 ;; Split with 8bit unsigned divide:
7339 ;; if (dividend an divisor are in [0-255])
7340 ;; use 8bit unsigned integer divide
7341 ;; else
7342 ;; use original integer divide
7343 (define_split
7344 [(set (match_operand:SWI48 0 "register_operand" "")
7345 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7346 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7347 (set (match_operand:SWI48 1 "register_operand" "")
7348 (umod:SWI48 (match_dup 2) (match_dup 3)))
7349 (clobber (reg:CC FLAGS_REG))]
7350 "TARGET_USE_8BIT_IDIV
7351 && TARGET_QIMODE_MATH
7352 && can_create_pseudo_p ()
7353 && !optimize_insn_for_size_p ()"
7354 [(const_int 0)]
7355 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7356
7357 (define_insn_and_split "udivmod<mode>4_1"
7358 [(set (match_operand:SWI48 0 "register_operand" "=a")
7359 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7360 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7361 (set (match_operand:SWI48 1 "register_operand" "=&d")
7362 (umod:SWI48 (match_dup 2) (match_dup 3)))
7363 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7364 (clobber (reg:CC FLAGS_REG))]
7365 ""
7366 "#"
7367 "reload_completed"
7368 [(set (match_dup 1) (const_int 0))
7369 (parallel [(set (match_dup 0)
7370 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7371 (set (match_dup 1)
7372 (umod:SWI48 (match_dup 2) (match_dup 3)))
7373 (use (match_dup 1))
7374 (clobber (reg:CC FLAGS_REG))])]
7375 ""
7376 [(set_attr "type" "multi")
7377 (set_attr "mode" "<MODE>")])
7378
7379 (define_insn_and_split "*udivmod<mode>4"
7380 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7381 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7382 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7383 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7384 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7385 (clobber (reg:CC FLAGS_REG))]
7386 ""
7387 "#"
7388 "reload_completed"
7389 [(set (match_dup 1) (const_int 0))
7390 (parallel [(set (match_dup 0)
7391 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7392 (set (match_dup 1)
7393 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7394 (use (match_dup 1))
7395 (clobber (reg:CC FLAGS_REG))])]
7396 ""
7397 [(set_attr "type" "multi")
7398 (set_attr "mode" "<MODE>")])
7399
7400 (define_insn "*udivmod<mode>4_noext"
7401 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7402 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7403 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7404 (set (match_operand:SWIM248 1 "register_operand" "=d")
7405 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7406 (use (match_operand:SWIM248 4 "register_operand" "1"))
7407 (clobber (reg:CC FLAGS_REG))]
7408 ""
7409 "div{<imodesuffix>}\t%3"
7410 [(set_attr "type" "idiv")
7411 (set_attr "mode" "<MODE>")])
7412
7413 (define_expand "udivmodqi4"
7414 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7415 (udiv:QI
7416 (match_operand:QI 1 "register_operand" "")
7417 (match_operand:QI 2 "nonimmediate_operand" "")))
7418 (set (match_operand:QI 3 "register_operand" "")
7419 (umod:QI (match_dup 1) (match_dup 2)))
7420 (clobber (reg:CC FLAGS_REG))])]
7421 "TARGET_QIMODE_MATH"
7422 {
7423 rtx div, mod, insn;
7424 rtx tmp0, tmp1;
7425
7426 tmp0 = gen_reg_rtx (HImode);
7427 tmp1 = gen_reg_rtx (HImode);
7428
7429 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7430 in AX. */
7431 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7432 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7433
7434 /* Extract remainder from AH. */
7435 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7436 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7437 insn = emit_move_insn (operands[3], tmp1);
7438
7439 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7440 set_unique_reg_note (insn, REG_EQUAL, mod);
7441
7442 /* Extract quotient from AL. */
7443 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7444
7445 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7446 set_unique_reg_note (insn, REG_EQUAL, div);
7447
7448 DONE;
7449 })
7450
7451 (define_insn "udivmodhiqi3"
7452 [(set (match_operand:HI 0 "register_operand" "=a")
7453 (ior:HI
7454 (ashift:HI
7455 (zero_extend:HI
7456 (truncate:QI
7457 (mod:HI (match_operand:HI 1 "register_operand" "0")
7458 (zero_extend:HI
7459 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7460 (const_int 8))
7461 (zero_extend:HI
7462 (truncate:QI
7463 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7464 (clobber (reg:CC FLAGS_REG))]
7465 "TARGET_QIMODE_MATH"
7466 "div{b}\t%2"
7467 [(set_attr "type" "idiv")
7468 (set_attr "mode" "QI")])
7469
7470 ;; We cannot use div/idiv for double division, because it causes
7471 ;; "division by zero" on the overflow and that's not what we expect
7472 ;; from truncate. Because true (non truncating) double division is
7473 ;; never generated, we can't create this insn anyway.
7474 ;
7475 ;(define_insn ""
7476 ; [(set (match_operand:SI 0 "register_operand" "=a")
7477 ; (truncate:SI
7478 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7479 ; (zero_extend:DI
7480 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7481 ; (set (match_operand:SI 3 "register_operand" "=d")
7482 ; (truncate:SI
7483 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7484 ; (clobber (reg:CC FLAGS_REG))]
7485 ; ""
7486 ; "div{l}\t{%2, %0|%0, %2}"
7487 ; [(set_attr "type" "idiv")])
7488 \f
7489 ;;- Logical AND instructions
7490
7491 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7492 ;; Note that this excludes ah.
7493
7494 (define_expand "testsi_ccno_1"
7495 [(set (reg:CCNO FLAGS_REG)
7496 (compare:CCNO
7497 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7498 (match_operand:SI 1 "nonmemory_operand" ""))
7499 (const_int 0)))])
7500
7501 (define_expand "testqi_ccz_1"
7502 [(set (reg:CCZ FLAGS_REG)
7503 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7504 (match_operand:QI 1 "nonmemory_operand" ""))
7505 (const_int 0)))])
7506
7507 (define_expand "testdi_ccno_1"
7508 [(set (reg:CCNO FLAGS_REG)
7509 (compare:CCNO
7510 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7511 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7512 (const_int 0)))]
7513 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7514
7515 (define_insn "*testdi_1"
7516 [(set (reg FLAGS_REG)
7517 (compare
7518 (and:DI
7519 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7520 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7521 (const_int 0)))]
7522 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7523 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7524 "@
7525 test{l}\t{%k1, %k0|%k0, %k1}
7526 test{l}\t{%k1, %k0|%k0, %k1}
7527 test{q}\t{%1, %0|%0, %1}
7528 test{q}\t{%1, %0|%0, %1}
7529 test{q}\t{%1, %0|%0, %1}"
7530 [(set_attr "type" "test")
7531 (set_attr "modrm" "0,1,0,1,1")
7532 (set_attr "mode" "SI,SI,DI,DI,DI")])
7533
7534 (define_insn "*testqi_1_maybe_si"
7535 [(set (reg FLAGS_REG)
7536 (compare
7537 (and:QI
7538 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7539 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7540 (const_int 0)))]
7541 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7542 && ix86_match_ccmode (insn,
7543 CONST_INT_P (operands[1])
7544 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7545 {
7546 if (which_alternative == 3)
7547 {
7548 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7549 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7550 return "test{l}\t{%1, %k0|%k0, %1}";
7551 }
7552 return "test{b}\t{%1, %0|%0, %1}";
7553 }
7554 [(set_attr "type" "test")
7555 (set_attr "modrm" "0,1,1,1")
7556 (set_attr "mode" "QI,QI,QI,SI")
7557 (set_attr "pent_pair" "uv,np,uv,np")])
7558
7559 (define_insn "*test<mode>_1"
7560 [(set (reg FLAGS_REG)
7561 (compare
7562 (and:SWI124
7563 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7564 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7565 (const_int 0)))]
7566 "ix86_match_ccmode (insn, CCNOmode)
7567 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7568 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7569 [(set_attr "type" "test")
7570 (set_attr "modrm" "0,1,1")
7571 (set_attr "mode" "<MODE>")
7572 (set_attr "pent_pair" "uv,np,uv")])
7573
7574 (define_expand "testqi_ext_ccno_0"
7575 [(set (reg:CCNO FLAGS_REG)
7576 (compare:CCNO
7577 (and:SI
7578 (zero_extract:SI
7579 (match_operand 0 "ext_register_operand" "")
7580 (const_int 8)
7581 (const_int 8))
7582 (match_operand 1 "const_int_operand" ""))
7583 (const_int 0)))])
7584
7585 (define_insn "*testqi_ext_0"
7586 [(set (reg FLAGS_REG)
7587 (compare
7588 (and:SI
7589 (zero_extract:SI
7590 (match_operand 0 "ext_register_operand" "Q")
7591 (const_int 8)
7592 (const_int 8))
7593 (match_operand 1 "const_int_operand" "n"))
7594 (const_int 0)))]
7595 "ix86_match_ccmode (insn, CCNOmode)"
7596 "test{b}\t{%1, %h0|%h0, %1}"
7597 [(set_attr "type" "test")
7598 (set_attr "mode" "QI")
7599 (set_attr "length_immediate" "1")
7600 (set_attr "modrm" "1")
7601 (set_attr "pent_pair" "np")])
7602
7603 (define_insn "*testqi_ext_1_rex64"
7604 [(set (reg FLAGS_REG)
7605 (compare
7606 (and:SI
7607 (zero_extract:SI
7608 (match_operand 0 "ext_register_operand" "Q")
7609 (const_int 8)
7610 (const_int 8))
7611 (zero_extend:SI
7612 (match_operand:QI 1 "register_operand" "Q")))
7613 (const_int 0)))]
7614 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7615 "test{b}\t{%1, %h0|%h0, %1}"
7616 [(set_attr "type" "test")
7617 (set_attr "mode" "QI")])
7618
7619 (define_insn "*testqi_ext_1"
7620 [(set (reg FLAGS_REG)
7621 (compare
7622 (and:SI
7623 (zero_extract:SI
7624 (match_operand 0 "ext_register_operand" "Q")
7625 (const_int 8)
7626 (const_int 8))
7627 (zero_extend:SI
7628 (match_operand:QI 1 "general_operand" "Qm")))
7629 (const_int 0)))]
7630 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7631 "test{b}\t{%1, %h0|%h0, %1}"
7632 [(set_attr "type" "test")
7633 (set_attr "mode" "QI")])
7634
7635 (define_insn "*testqi_ext_2"
7636 [(set (reg FLAGS_REG)
7637 (compare
7638 (and:SI
7639 (zero_extract:SI
7640 (match_operand 0 "ext_register_operand" "Q")
7641 (const_int 8)
7642 (const_int 8))
7643 (zero_extract:SI
7644 (match_operand 1 "ext_register_operand" "Q")
7645 (const_int 8)
7646 (const_int 8)))
7647 (const_int 0)))]
7648 "ix86_match_ccmode (insn, CCNOmode)"
7649 "test{b}\t{%h1, %h0|%h0, %h1}"
7650 [(set_attr "type" "test")
7651 (set_attr "mode" "QI")])
7652
7653 (define_insn "*testqi_ext_3_rex64"
7654 [(set (reg FLAGS_REG)
7655 (compare (zero_extract:DI
7656 (match_operand 0 "nonimmediate_operand" "rm")
7657 (match_operand:DI 1 "const_int_operand" "")
7658 (match_operand:DI 2 "const_int_operand" ""))
7659 (const_int 0)))]
7660 "TARGET_64BIT
7661 && ix86_match_ccmode (insn, CCNOmode)
7662 && INTVAL (operands[1]) > 0
7663 && INTVAL (operands[2]) >= 0
7664 /* Ensure that resulting mask is zero or sign extended operand. */
7665 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7666 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7667 && INTVAL (operands[1]) > 32))
7668 && (GET_MODE (operands[0]) == SImode
7669 || GET_MODE (operands[0]) == DImode
7670 || GET_MODE (operands[0]) == HImode
7671 || GET_MODE (operands[0]) == QImode)"
7672 "#")
7673
7674 ;; Combine likes to form bit extractions for some tests. Humor it.
7675 (define_insn "*testqi_ext_3"
7676 [(set (reg FLAGS_REG)
7677 (compare (zero_extract:SI
7678 (match_operand 0 "nonimmediate_operand" "rm")
7679 (match_operand:SI 1 "const_int_operand" "")
7680 (match_operand:SI 2 "const_int_operand" ""))
7681 (const_int 0)))]
7682 "ix86_match_ccmode (insn, CCNOmode)
7683 && INTVAL (operands[1]) > 0
7684 && INTVAL (operands[2]) >= 0
7685 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7686 && (GET_MODE (operands[0]) == SImode
7687 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7688 || GET_MODE (operands[0]) == HImode
7689 || GET_MODE (operands[0]) == QImode)"
7690 "#")
7691
7692 (define_split
7693 [(set (match_operand 0 "flags_reg_operand" "")
7694 (match_operator 1 "compare_operator"
7695 [(zero_extract
7696 (match_operand 2 "nonimmediate_operand" "")
7697 (match_operand 3 "const_int_operand" "")
7698 (match_operand 4 "const_int_operand" ""))
7699 (const_int 0)]))]
7700 "ix86_match_ccmode (insn, CCNOmode)"
7701 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7702 {
7703 rtx val = operands[2];
7704 HOST_WIDE_INT len = INTVAL (operands[3]);
7705 HOST_WIDE_INT pos = INTVAL (operands[4]);
7706 HOST_WIDE_INT mask;
7707 enum machine_mode mode, submode;
7708
7709 mode = GET_MODE (val);
7710 if (MEM_P (val))
7711 {
7712 /* ??? Combine likes to put non-volatile mem extractions in QImode
7713 no matter the size of the test. So find a mode that works. */
7714 if (! MEM_VOLATILE_P (val))
7715 {
7716 mode = smallest_mode_for_size (pos + len, MODE_INT);
7717 val = adjust_address (val, mode, 0);
7718 }
7719 }
7720 else if (GET_CODE (val) == SUBREG
7721 && (submode = GET_MODE (SUBREG_REG (val)),
7722 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7723 && pos + len <= GET_MODE_BITSIZE (submode)
7724 && GET_MODE_CLASS (submode) == MODE_INT)
7725 {
7726 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7727 mode = submode;
7728 val = SUBREG_REG (val);
7729 }
7730 else if (mode == HImode && pos + len <= 8)
7731 {
7732 /* Small HImode tests can be converted to QImode. */
7733 mode = QImode;
7734 val = gen_lowpart (QImode, val);
7735 }
7736
7737 if (len == HOST_BITS_PER_WIDE_INT)
7738 mask = -1;
7739 else
7740 mask = ((HOST_WIDE_INT)1 << len) - 1;
7741 mask <<= pos;
7742
7743 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7744 })
7745
7746 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7747 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7748 ;; this is relatively important trick.
7749 ;; Do the conversion only post-reload to avoid limiting of the register class
7750 ;; to QI regs.
7751 (define_split
7752 [(set (match_operand 0 "flags_reg_operand" "")
7753 (match_operator 1 "compare_operator"
7754 [(and (match_operand 2 "register_operand" "")
7755 (match_operand 3 "const_int_operand" ""))
7756 (const_int 0)]))]
7757 "reload_completed
7758 && QI_REG_P (operands[2])
7759 && GET_MODE (operands[2]) != QImode
7760 && ((ix86_match_ccmode (insn, CCZmode)
7761 && !(INTVAL (operands[3]) & ~(255 << 8)))
7762 || (ix86_match_ccmode (insn, CCNOmode)
7763 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7764 [(set (match_dup 0)
7765 (match_op_dup 1
7766 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7767 (match_dup 3))
7768 (const_int 0)]))]
7769 "operands[2] = gen_lowpart (SImode, operands[2]);
7770 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7771
7772 (define_split
7773 [(set (match_operand 0 "flags_reg_operand" "")
7774 (match_operator 1 "compare_operator"
7775 [(and (match_operand 2 "nonimmediate_operand" "")
7776 (match_operand 3 "const_int_operand" ""))
7777 (const_int 0)]))]
7778 "reload_completed
7779 && GET_MODE (operands[2]) != QImode
7780 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7781 && ((ix86_match_ccmode (insn, CCZmode)
7782 && !(INTVAL (operands[3]) & ~255))
7783 || (ix86_match_ccmode (insn, CCNOmode)
7784 && !(INTVAL (operands[3]) & ~127)))"
7785 [(set (match_dup 0)
7786 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7787 (const_int 0)]))]
7788 "operands[2] = gen_lowpart (QImode, operands[2]);
7789 operands[3] = gen_lowpart (QImode, operands[3]);")
7790
7791 ;; %%% This used to optimize known byte-wide and operations to memory,
7792 ;; and sometimes to QImode registers. If this is considered useful,
7793 ;; it should be done with splitters.
7794
7795 (define_expand "and<mode>3"
7796 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7797 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7798 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7799 ""
7800 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7801
7802 (define_insn "*anddi_1"
7803 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7804 (and:DI
7805 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7806 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7807 (clobber (reg:CC FLAGS_REG))]
7808 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7809 {
7810 switch (get_attr_type (insn))
7811 {
7812 case TYPE_IMOVX:
7813 {
7814 enum machine_mode mode;
7815
7816 gcc_assert (CONST_INT_P (operands[2]));
7817 if (INTVAL (operands[2]) == 0xff)
7818 mode = QImode;
7819 else
7820 {
7821 gcc_assert (INTVAL (operands[2]) == 0xffff);
7822 mode = HImode;
7823 }
7824
7825 operands[1] = gen_lowpart (mode, operands[1]);
7826 if (mode == QImode)
7827 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7828 else
7829 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7830 }
7831
7832 default:
7833 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7834 if (get_attr_mode (insn) == MODE_SI)
7835 return "and{l}\t{%k2, %k0|%k0, %k2}";
7836 else
7837 return "and{q}\t{%2, %0|%0, %2}";
7838 }
7839 }
7840 [(set_attr "type" "alu,alu,alu,imovx")
7841 (set_attr "length_immediate" "*,*,*,0")
7842 (set (attr "prefix_rex")
7843 (if_then_else
7844 (and (eq_attr "type" "imovx")
7845 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7846 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7847 (const_string "1")
7848 (const_string "*")))
7849 (set_attr "mode" "SI,DI,DI,SI")])
7850
7851 (define_insn "*andsi_1"
7852 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7853 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7854 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7855 (clobber (reg:CC FLAGS_REG))]
7856 "ix86_binary_operator_ok (AND, SImode, operands)"
7857 {
7858 switch (get_attr_type (insn))
7859 {
7860 case TYPE_IMOVX:
7861 {
7862 enum machine_mode mode;
7863
7864 gcc_assert (CONST_INT_P (operands[2]));
7865 if (INTVAL (operands[2]) == 0xff)
7866 mode = QImode;
7867 else
7868 {
7869 gcc_assert (INTVAL (operands[2]) == 0xffff);
7870 mode = HImode;
7871 }
7872
7873 operands[1] = gen_lowpart (mode, operands[1]);
7874 if (mode == QImode)
7875 return "movz{bl|x}\t{%1, %0|%0, %1}";
7876 else
7877 return "movz{wl|x}\t{%1, %0|%0, %1}";
7878 }
7879
7880 default:
7881 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7882 return "and{l}\t{%2, %0|%0, %2}";
7883 }
7884 }
7885 [(set_attr "type" "alu,alu,imovx")
7886 (set (attr "prefix_rex")
7887 (if_then_else
7888 (and (eq_attr "type" "imovx")
7889 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7890 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7891 (const_string "1")
7892 (const_string "*")))
7893 (set_attr "length_immediate" "*,*,0")
7894 (set_attr "mode" "SI")])
7895
7896 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7897 (define_insn "*andsi_1_zext"
7898 [(set (match_operand:DI 0 "register_operand" "=r")
7899 (zero_extend:DI
7900 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7901 (match_operand:SI 2 "general_operand" "g"))))
7902 (clobber (reg:CC FLAGS_REG))]
7903 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7904 "and{l}\t{%2, %k0|%k0, %2}"
7905 [(set_attr "type" "alu")
7906 (set_attr "mode" "SI")])
7907
7908 (define_insn "*andhi_1"
7909 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7910 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7911 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7912 (clobber (reg:CC FLAGS_REG))]
7913 "ix86_binary_operator_ok (AND, HImode, operands)"
7914 {
7915 switch (get_attr_type (insn))
7916 {
7917 case TYPE_IMOVX:
7918 gcc_assert (CONST_INT_P (operands[2]));
7919 gcc_assert (INTVAL (operands[2]) == 0xff);
7920 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7921
7922 default:
7923 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7924
7925 return "and{w}\t{%2, %0|%0, %2}";
7926 }
7927 }
7928 [(set_attr "type" "alu,alu,imovx")
7929 (set_attr "length_immediate" "*,*,0")
7930 (set (attr "prefix_rex")
7931 (if_then_else
7932 (and (eq_attr "type" "imovx")
7933 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7934 (const_string "1")
7935 (const_string "*")))
7936 (set_attr "mode" "HI,HI,SI")])
7937
7938 ;; %%% Potential partial reg stall on alternative 2. What to do?
7939 (define_insn "*andqi_1"
7940 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7941 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7942 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7943 (clobber (reg:CC FLAGS_REG))]
7944 "ix86_binary_operator_ok (AND, QImode, operands)"
7945 "@
7946 and{b}\t{%2, %0|%0, %2}
7947 and{b}\t{%2, %0|%0, %2}
7948 and{l}\t{%k2, %k0|%k0, %k2}"
7949 [(set_attr "type" "alu")
7950 (set_attr "mode" "QI,QI,SI")])
7951
7952 (define_insn "*andqi_1_slp"
7953 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7954 (and:QI (match_dup 0)
7955 (match_operand:QI 1 "general_operand" "qn,qmn")))
7956 (clobber (reg:CC FLAGS_REG))]
7957 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7958 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7959 "and{b}\t{%1, %0|%0, %1}"
7960 [(set_attr "type" "alu1")
7961 (set_attr "mode" "QI")])
7962
7963 (define_split
7964 [(set (match_operand 0 "register_operand" "")
7965 (and (match_dup 0)
7966 (const_int -65536)))
7967 (clobber (reg:CC FLAGS_REG))]
7968 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7969 || optimize_function_for_size_p (cfun)"
7970 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7971 "operands[1] = gen_lowpart (HImode, operands[0]);")
7972
7973 (define_split
7974 [(set (match_operand 0 "ext_register_operand" "")
7975 (and (match_dup 0)
7976 (const_int -256)))
7977 (clobber (reg:CC FLAGS_REG))]
7978 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7979 && reload_completed"
7980 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7981 "operands[1] = gen_lowpart (QImode, operands[0]);")
7982
7983 (define_split
7984 [(set (match_operand 0 "ext_register_operand" "")
7985 (and (match_dup 0)
7986 (const_int -65281)))
7987 (clobber (reg:CC FLAGS_REG))]
7988 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7989 && reload_completed"
7990 [(parallel [(set (zero_extract:SI (match_dup 0)
7991 (const_int 8)
7992 (const_int 8))
7993 (xor:SI
7994 (zero_extract:SI (match_dup 0)
7995 (const_int 8)
7996 (const_int 8))
7997 (zero_extract:SI (match_dup 0)
7998 (const_int 8)
7999 (const_int 8))))
8000 (clobber (reg:CC FLAGS_REG))])]
8001 "operands[0] = gen_lowpart (SImode, operands[0]);")
8002
8003 (define_insn "*anddi_2"
8004 [(set (reg FLAGS_REG)
8005 (compare
8006 (and:DI
8007 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8008 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8009 (const_int 0)))
8010 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8011 (and:DI (match_dup 1) (match_dup 2)))]
8012 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8013 && ix86_binary_operator_ok (AND, DImode, operands)"
8014 "@
8015 and{l}\t{%k2, %k0|%k0, %k2}
8016 and{q}\t{%2, %0|%0, %2}
8017 and{q}\t{%2, %0|%0, %2}"
8018 [(set_attr "type" "alu")
8019 (set_attr "mode" "SI,DI,DI")])
8020
8021 (define_insn "*andqi_2_maybe_si"
8022 [(set (reg FLAGS_REG)
8023 (compare (and:QI
8024 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8025 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8026 (const_int 0)))
8027 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8028 (and:QI (match_dup 1) (match_dup 2)))]
8029 "ix86_binary_operator_ok (AND, QImode, operands)
8030 && ix86_match_ccmode (insn,
8031 CONST_INT_P (operands[2])
8032 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8033 {
8034 if (which_alternative == 2)
8035 {
8036 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8037 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8038 return "and{l}\t{%2, %k0|%k0, %2}";
8039 }
8040 return "and{b}\t{%2, %0|%0, %2}";
8041 }
8042 [(set_attr "type" "alu")
8043 (set_attr "mode" "QI,QI,SI")])
8044
8045 (define_insn "*and<mode>_2"
8046 [(set (reg FLAGS_REG)
8047 (compare (and:SWI124
8048 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8049 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8050 (const_int 0)))
8051 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8052 (and:SWI124 (match_dup 1) (match_dup 2)))]
8053 "ix86_match_ccmode (insn, CCNOmode)
8054 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8055 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8056 [(set_attr "type" "alu")
8057 (set_attr "mode" "<MODE>")])
8058
8059 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8060 (define_insn "*andsi_2_zext"
8061 [(set (reg FLAGS_REG)
8062 (compare (and:SI
8063 (match_operand:SI 1 "nonimmediate_operand" "%0")
8064 (match_operand:SI 2 "general_operand" "g"))
8065 (const_int 0)))
8066 (set (match_operand:DI 0 "register_operand" "=r")
8067 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8068 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8069 && ix86_binary_operator_ok (AND, SImode, operands)"
8070 "and{l}\t{%2, %k0|%k0, %2}"
8071 [(set_attr "type" "alu")
8072 (set_attr "mode" "SI")])
8073
8074 (define_insn "*andqi_2_slp"
8075 [(set (reg FLAGS_REG)
8076 (compare (and:QI
8077 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8078 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8079 (const_int 0)))
8080 (set (strict_low_part (match_dup 0))
8081 (and:QI (match_dup 0) (match_dup 1)))]
8082 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8083 && ix86_match_ccmode (insn, CCNOmode)
8084 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8085 "and{b}\t{%1, %0|%0, %1}"
8086 [(set_attr "type" "alu1")
8087 (set_attr "mode" "QI")])
8088
8089 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8090 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8091 ;; for a QImode operand, which of course failed.
8092 (define_insn "andqi_ext_0"
8093 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8094 (const_int 8)
8095 (const_int 8))
8096 (and:SI
8097 (zero_extract:SI
8098 (match_operand 1 "ext_register_operand" "0")
8099 (const_int 8)
8100 (const_int 8))
8101 (match_operand 2 "const_int_operand" "n")))
8102 (clobber (reg:CC FLAGS_REG))]
8103 ""
8104 "and{b}\t{%2, %h0|%h0, %2}"
8105 [(set_attr "type" "alu")
8106 (set_attr "length_immediate" "1")
8107 (set_attr "modrm" "1")
8108 (set_attr "mode" "QI")])
8109
8110 ;; Generated by peephole translating test to and. This shows up
8111 ;; often in fp comparisons.
8112 (define_insn "*andqi_ext_0_cc"
8113 [(set (reg FLAGS_REG)
8114 (compare
8115 (and:SI
8116 (zero_extract:SI
8117 (match_operand 1 "ext_register_operand" "0")
8118 (const_int 8)
8119 (const_int 8))
8120 (match_operand 2 "const_int_operand" "n"))
8121 (const_int 0)))
8122 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8123 (const_int 8)
8124 (const_int 8))
8125 (and:SI
8126 (zero_extract:SI
8127 (match_dup 1)
8128 (const_int 8)
8129 (const_int 8))
8130 (match_dup 2)))]
8131 "ix86_match_ccmode (insn, CCNOmode)"
8132 "and{b}\t{%2, %h0|%h0, %2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "length_immediate" "1")
8135 (set_attr "modrm" "1")
8136 (set_attr "mode" "QI")])
8137
8138 (define_insn "*andqi_ext_1_rex64"
8139 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8140 (const_int 8)
8141 (const_int 8))
8142 (and:SI
8143 (zero_extract:SI
8144 (match_operand 1 "ext_register_operand" "0")
8145 (const_int 8)
8146 (const_int 8))
8147 (zero_extend:SI
8148 (match_operand 2 "ext_register_operand" "Q"))))
8149 (clobber (reg:CC FLAGS_REG))]
8150 "TARGET_64BIT"
8151 "and{b}\t{%2, %h0|%h0, %2}"
8152 [(set_attr "type" "alu")
8153 (set_attr "length_immediate" "0")
8154 (set_attr "mode" "QI")])
8155
8156 (define_insn "*andqi_ext_1"
8157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8158 (const_int 8)
8159 (const_int 8))
8160 (and:SI
8161 (zero_extract:SI
8162 (match_operand 1 "ext_register_operand" "0")
8163 (const_int 8)
8164 (const_int 8))
8165 (zero_extend:SI
8166 (match_operand:QI 2 "general_operand" "Qm"))))
8167 (clobber (reg:CC FLAGS_REG))]
8168 "!TARGET_64BIT"
8169 "and{b}\t{%2, %h0|%h0, %2}"
8170 [(set_attr "type" "alu")
8171 (set_attr "length_immediate" "0")
8172 (set_attr "mode" "QI")])
8173
8174 (define_insn "*andqi_ext_2"
8175 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8176 (const_int 8)
8177 (const_int 8))
8178 (and:SI
8179 (zero_extract:SI
8180 (match_operand 1 "ext_register_operand" "%0")
8181 (const_int 8)
8182 (const_int 8))
8183 (zero_extract:SI
8184 (match_operand 2 "ext_register_operand" "Q")
8185 (const_int 8)
8186 (const_int 8))))
8187 (clobber (reg:CC FLAGS_REG))]
8188 ""
8189 "and{b}\t{%h2, %h0|%h0, %h2}"
8190 [(set_attr "type" "alu")
8191 (set_attr "length_immediate" "0")
8192 (set_attr "mode" "QI")])
8193
8194 ;; Convert wide AND instructions with immediate operand to shorter QImode
8195 ;; equivalents when possible.
8196 ;; Don't do the splitting with memory operands, since it introduces risk
8197 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8198 ;; for size, but that can (should?) be handled by generic code instead.
8199 (define_split
8200 [(set (match_operand 0 "register_operand" "")
8201 (and (match_operand 1 "register_operand" "")
8202 (match_operand 2 "const_int_operand" "")))
8203 (clobber (reg:CC FLAGS_REG))]
8204 "reload_completed
8205 && QI_REG_P (operands[0])
8206 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8207 && !(~INTVAL (operands[2]) & ~(255 << 8))
8208 && GET_MODE (operands[0]) != QImode"
8209 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8210 (and:SI (zero_extract:SI (match_dup 1)
8211 (const_int 8) (const_int 8))
8212 (match_dup 2)))
8213 (clobber (reg:CC FLAGS_REG))])]
8214 "operands[0] = gen_lowpart (SImode, operands[0]);
8215 operands[1] = gen_lowpart (SImode, operands[1]);
8216 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8217
8218 ;; Since AND can be encoded with sign extended immediate, this is only
8219 ;; profitable when 7th bit is not set.
8220 (define_split
8221 [(set (match_operand 0 "register_operand" "")
8222 (and (match_operand 1 "general_operand" "")
8223 (match_operand 2 "const_int_operand" "")))
8224 (clobber (reg:CC FLAGS_REG))]
8225 "reload_completed
8226 && ANY_QI_REG_P (operands[0])
8227 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8228 && !(~INTVAL (operands[2]) & ~255)
8229 && !(INTVAL (operands[2]) & 128)
8230 && GET_MODE (operands[0]) != QImode"
8231 [(parallel [(set (strict_low_part (match_dup 0))
8232 (and:QI (match_dup 1)
8233 (match_dup 2)))
8234 (clobber (reg:CC FLAGS_REG))])]
8235 "operands[0] = gen_lowpart (QImode, operands[0]);
8236 operands[1] = gen_lowpart (QImode, operands[1]);
8237 operands[2] = gen_lowpart (QImode, operands[2]);")
8238 \f
8239 ;; Logical inclusive and exclusive OR instructions
8240
8241 ;; %%% This used to optimize known byte-wide and operations to memory.
8242 ;; If this is considered useful, it should be done with splitters.
8243
8244 (define_expand "<code><mode>3"
8245 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8246 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8247 (match_operand:SWIM 2 "<general_operand>" "")))]
8248 ""
8249 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8250
8251 (define_insn "*<code><mode>_1"
8252 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8253 (any_or:SWI248
8254 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8255 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8256 (clobber (reg:CC FLAGS_REG))]
8257 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8258 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8259 [(set_attr "type" "alu")
8260 (set_attr "mode" "<MODE>")])
8261
8262 ;; %%% Potential partial reg stall on alternative 2. What to do?
8263 (define_insn "*<code>qi_1"
8264 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8265 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8266 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8267 (clobber (reg:CC FLAGS_REG))]
8268 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8269 "@
8270 <logic>{b}\t{%2, %0|%0, %2}
8271 <logic>{b}\t{%2, %0|%0, %2}
8272 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8273 [(set_attr "type" "alu")
8274 (set_attr "mode" "QI,QI,SI")])
8275
8276 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8277 (define_insn "*<code>si_1_zext"
8278 [(set (match_operand:DI 0 "register_operand" "=r")
8279 (zero_extend:DI
8280 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8281 (match_operand:SI 2 "general_operand" "g"))))
8282 (clobber (reg:CC FLAGS_REG))]
8283 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8284 "<logic>{l}\t{%2, %k0|%k0, %2}"
8285 [(set_attr "type" "alu")
8286 (set_attr "mode" "SI")])
8287
8288 (define_insn "*<code>si_1_zext_imm"
8289 [(set (match_operand:DI 0 "register_operand" "=r")
8290 (any_or:DI
8291 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8292 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8293 (clobber (reg:CC FLAGS_REG))]
8294 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8295 "<logic>{l}\t{%2, %k0|%k0, %2}"
8296 [(set_attr "type" "alu")
8297 (set_attr "mode" "SI")])
8298
8299 (define_insn "*<code>qi_1_slp"
8300 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8301 (any_or:QI (match_dup 0)
8302 (match_operand:QI 1 "general_operand" "qmn,qn")))
8303 (clobber (reg:CC FLAGS_REG))]
8304 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8305 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8306 "<logic>{b}\t{%1, %0|%0, %1}"
8307 [(set_attr "type" "alu1")
8308 (set_attr "mode" "QI")])
8309
8310 (define_insn "*<code><mode>_2"
8311 [(set (reg FLAGS_REG)
8312 (compare (any_or:SWI
8313 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8314 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8315 (const_int 0)))
8316 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8317 (any_or:SWI (match_dup 1) (match_dup 2)))]
8318 "ix86_match_ccmode (insn, CCNOmode)
8319 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8320 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "mode" "<MODE>")])
8323
8324 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8325 ;; ??? Special case for immediate operand is missing - it is tricky.
8326 (define_insn "*<code>si_2_zext"
8327 [(set (reg FLAGS_REG)
8328 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8329 (match_operand:SI 2 "general_operand" "g"))
8330 (const_int 0)))
8331 (set (match_operand:DI 0 "register_operand" "=r")
8332 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8333 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8334 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8335 "<logic>{l}\t{%2, %k0|%k0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "mode" "SI")])
8338
8339 (define_insn "*<code>si_2_zext_imm"
8340 [(set (reg FLAGS_REG)
8341 (compare (any_or:SI
8342 (match_operand:SI 1 "nonimmediate_operand" "%0")
8343 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8344 (const_int 0)))
8345 (set (match_operand:DI 0 "register_operand" "=r")
8346 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8347 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8348 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8349 "<logic>{l}\t{%2, %k0|%k0, %2}"
8350 [(set_attr "type" "alu")
8351 (set_attr "mode" "SI")])
8352
8353 (define_insn "*<code>qi_2_slp"
8354 [(set (reg FLAGS_REG)
8355 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8356 (match_operand:QI 1 "general_operand" "qmn,qn"))
8357 (const_int 0)))
8358 (set (strict_low_part (match_dup 0))
8359 (any_or:QI (match_dup 0) (match_dup 1)))]
8360 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8361 && ix86_match_ccmode (insn, CCNOmode)
8362 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8363 "<logic>{b}\t{%1, %0|%0, %1}"
8364 [(set_attr "type" "alu1")
8365 (set_attr "mode" "QI")])
8366
8367 (define_insn "*<code><mode>_3"
8368 [(set (reg FLAGS_REG)
8369 (compare (any_or:SWI
8370 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8371 (match_operand:SWI 2 "<general_operand>" "<g>"))
8372 (const_int 0)))
8373 (clobber (match_scratch:SWI 0 "=<r>"))]
8374 "ix86_match_ccmode (insn, CCNOmode)
8375 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8376 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8377 [(set_attr "type" "alu")
8378 (set_attr "mode" "<MODE>")])
8379
8380 (define_insn "*<code>qi_ext_0"
8381 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8382 (const_int 8)
8383 (const_int 8))
8384 (any_or:SI
8385 (zero_extract:SI
8386 (match_operand 1 "ext_register_operand" "0")
8387 (const_int 8)
8388 (const_int 8))
8389 (match_operand 2 "const_int_operand" "n")))
8390 (clobber (reg:CC FLAGS_REG))]
8391 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8392 "<logic>{b}\t{%2, %h0|%h0, %2}"
8393 [(set_attr "type" "alu")
8394 (set_attr "length_immediate" "1")
8395 (set_attr "modrm" "1")
8396 (set_attr "mode" "QI")])
8397
8398 (define_insn "*<code>qi_ext_1_rex64"
8399 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8400 (const_int 8)
8401 (const_int 8))
8402 (any_or:SI
8403 (zero_extract:SI
8404 (match_operand 1 "ext_register_operand" "0")
8405 (const_int 8)
8406 (const_int 8))
8407 (zero_extend:SI
8408 (match_operand 2 "ext_register_operand" "Q"))))
8409 (clobber (reg:CC FLAGS_REG))]
8410 "TARGET_64BIT
8411 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8412 "<logic>{b}\t{%2, %h0|%h0, %2}"
8413 [(set_attr "type" "alu")
8414 (set_attr "length_immediate" "0")
8415 (set_attr "mode" "QI")])
8416
8417 (define_insn "*<code>qi_ext_1"
8418 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8419 (const_int 8)
8420 (const_int 8))
8421 (any_or:SI
8422 (zero_extract:SI
8423 (match_operand 1 "ext_register_operand" "0")
8424 (const_int 8)
8425 (const_int 8))
8426 (zero_extend:SI
8427 (match_operand:QI 2 "general_operand" "Qm"))))
8428 (clobber (reg:CC FLAGS_REG))]
8429 "!TARGET_64BIT
8430 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8431 "<logic>{b}\t{%2, %h0|%h0, %2}"
8432 [(set_attr "type" "alu")
8433 (set_attr "length_immediate" "0")
8434 (set_attr "mode" "QI")])
8435
8436 (define_insn "*<code>qi_ext_2"
8437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8438 (const_int 8)
8439 (const_int 8))
8440 (any_or:SI
8441 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8442 (const_int 8)
8443 (const_int 8))
8444 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8445 (const_int 8)
8446 (const_int 8))))
8447 (clobber (reg:CC FLAGS_REG))]
8448 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8449 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8450 [(set_attr "type" "alu")
8451 (set_attr "length_immediate" "0")
8452 (set_attr "mode" "QI")])
8453
8454 (define_split
8455 [(set (match_operand 0 "register_operand" "")
8456 (any_or (match_operand 1 "register_operand" "")
8457 (match_operand 2 "const_int_operand" "")))
8458 (clobber (reg:CC FLAGS_REG))]
8459 "reload_completed
8460 && QI_REG_P (operands[0])
8461 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8462 && !(INTVAL (operands[2]) & ~(255 << 8))
8463 && GET_MODE (operands[0]) != QImode"
8464 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8465 (any_or:SI (zero_extract:SI (match_dup 1)
8466 (const_int 8) (const_int 8))
8467 (match_dup 2)))
8468 (clobber (reg:CC FLAGS_REG))])]
8469 "operands[0] = gen_lowpart (SImode, operands[0]);
8470 operands[1] = gen_lowpart (SImode, operands[1]);
8471 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8472
8473 ;; Since OR can be encoded with sign extended immediate, this is only
8474 ;; profitable when 7th bit is set.
8475 (define_split
8476 [(set (match_operand 0 "register_operand" "")
8477 (any_or (match_operand 1 "general_operand" "")
8478 (match_operand 2 "const_int_operand" "")))
8479 (clobber (reg:CC FLAGS_REG))]
8480 "reload_completed
8481 && ANY_QI_REG_P (operands[0])
8482 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8483 && !(INTVAL (operands[2]) & ~255)
8484 && (INTVAL (operands[2]) & 128)
8485 && GET_MODE (operands[0]) != QImode"
8486 [(parallel [(set (strict_low_part (match_dup 0))
8487 (any_or:QI (match_dup 1)
8488 (match_dup 2)))
8489 (clobber (reg:CC FLAGS_REG))])]
8490 "operands[0] = gen_lowpart (QImode, operands[0]);
8491 operands[1] = gen_lowpart (QImode, operands[1]);
8492 operands[2] = gen_lowpart (QImode, operands[2]);")
8493
8494 (define_expand "xorqi_cc_ext_1"
8495 [(parallel [
8496 (set (reg:CCNO FLAGS_REG)
8497 (compare:CCNO
8498 (xor:SI
8499 (zero_extract:SI
8500 (match_operand 1 "ext_register_operand" "")
8501 (const_int 8)
8502 (const_int 8))
8503 (match_operand:QI 2 "general_operand" ""))
8504 (const_int 0)))
8505 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8506 (const_int 8)
8507 (const_int 8))
8508 (xor:SI
8509 (zero_extract:SI
8510 (match_dup 1)
8511 (const_int 8)
8512 (const_int 8))
8513 (match_dup 2)))])])
8514
8515 (define_insn "*xorqi_cc_ext_1_rex64"
8516 [(set (reg FLAGS_REG)
8517 (compare
8518 (xor:SI
8519 (zero_extract:SI
8520 (match_operand 1 "ext_register_operand" "0")
8521 (const_int 8)
8522 (const_int 8))
8523 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8524 (const_int 0)))
8525 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8526 (const_int 8)
8527 (const_int 8))
8528 (xor:SI
8529 (zero_extract:SI
8530 (match_dup 1)
8531 (const_int 8)
8532 (const_int 8))
8533 (match_dup 2)))]
8534 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8535 "xor{b}\t{%2, %h0|%h0, %2}"
8536 [(set_attr "type" "alu")
8537 (set_attr "modrm" "1")
8538 (set_attr "mode" "QI")])
8539
8540 (define_insn "*xorqi_cc_ext_1"
8541 [(set (reg FLAGS_REG)
8542 (compare
8543 (xor:SI
8544 (zero_extract:SI
8545 (match_operand 1 "ext_register_operand" "0")
8546 (const_int 8)
8547 (const_int 8))
8548 (match_operand:QI 2 "general_operand" "qmn"))
8549 (const_int 0)))
8550 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8551 (const_int 8)
8552 (const_int 8))
8553 (xor:SI
8554 (zero_extract:SI
8555 (match_dup 1)
8556 (const_int 8)
8557 (const_int 8))
8558 (match_dup 2)))]
8559 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8560 "xor{b}\t{%2, %h0|%h0, %2}"
8561 [(set_attr "type" "alu")
8562 (set_attr "modrm" "1")
8563 (set_attr "mode" "QI")])
8564 \f
8565 ;; Negation instructions
8566
8567 (define_expand "neg<mode>2"
8568 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8569 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8570 ""
8571 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8572
8573 (define_insn_and_split "*neg<dwi>2_doubleword"
8574 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8575 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8576 (clobber (reg:CC FLAGS_REG))]
8577 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8578 "#"
8579 "reload_completed"
8580 [(parallel
8581 [(set (reg:CCZ FLAGS_REG)
8582 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8583 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8584 (parallel
8585 [(set (match_dup 2)
8586 (plus:DWIH (match_dup 3)
8587 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8588 (const_int 0))))
8589 (clobber (reg:CC FLAGS_REG))])
8590 (parallel
8591 [(set (match_dup 2)
8592 (neg:DWIH (match_dup 2)))
8593 (clobber (reg:CC FLAGS_REG))])]
8594 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8595
8596 (define_insn "*neg<mode>2_1"
8597 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8598 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8601 "neg{<imodesuffix>}\t%0"
8602 [(set_attr "type" "negnot")
8603 (set_attr "mode" "<MODE>")])
8604
8605 ;; Combine is quite creative about this pattern.
8606 (define_insn "*negsi2_1_zext"
8607 [(set (match_operand:DI 0 "register_operand" "=r")
8608 (lshiftrt:DI
8609 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8610 (const_int 32)))
8611 (const_int 32)))
8612 (clobber (reg:CC FLAGS_REG))]
8613 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8614 "neg{l}\t%k0"
8615 [(set_attr "type" "negnot")
8616 (set_attr "mode" "SI")])
8617
8618 ;; The problem with neg is that it does not perform (compare x 0),
8619 ;; it really performs (compare 0 x), which leaves us with the zero
8620 ;; flag being the only useful item.
8621
8622 (define_insn "*neg<mode>2_cmpz"
8623 [(set (reg:CCZ FLAGS_REG)
8624 (compare:CCZ
8625 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8626 (const_int 0)))
8627 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8628 (neg:SWI (match_dup 1)))]
8629 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8630 "neg{<imodesuffix>}\t%0"
8631 [(set_attr "type" "negnot")
8632 (set_attr "mode" "<MODE>")])
8633
8634 (define_insn "*negsi2_cmpz_zext"
8635 [(set (reg:CCZ FLAGS_REG)
8636 (compare:CCZ
8637 (lshiftrt:DI
8638 (neg:DI (ashift:DI
8639 (match_operand:DI 1 "register_operand" "0")
8640 (const_int 32)))
8641 (const_int 32))
8642 (const_int 0)))
8643 (set (match_operand:DI 0 "register_operand" "=r")
8644 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8645 (const_int 32)))
8646 (const_int 32)))]
8647 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8648 "neg{l}\t%k0"
8649 [(set_attr "type" "negnot")
8650 (set_attr "mode" "SI")])
8651
8652 ;; Changing of sign for FP values is doable using integer unit too.
8653
8654 (define_expand "<code><mode>2"
8655 [(set (match_operand:X87MODEF 0 "register_operand" "")
8656 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8657 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8658 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8659
8660 (define_insn "*absneg<mode>2_mixed"
8661 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8662 (match_operator:MODEF 3 "absneg_operator"
8663 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8664 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8665 (clobber (reg:CC FLAGS_REG))]
8666 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8667 "#")
8668
8669 (define_insn "*absneg<mode>2_sse"
8670 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8671 (match_operator:MODEF 3 "absneg_operator"
8672 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8673 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8674 (clobber (reg:CC FLAGS_REG))]
8675 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8676 "#")
8677
8678 (define_insn "*absneg<mode>2_i387"
8679 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8680 (match_operator:X87MODEF 3 "absneg_operator"
8681 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8682 (use (match_operand 2 "" ""))
8683 (clobber (reg:CC FLAGS_REG))]
8684 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8685 "#")
8686
8687 (define_expand "<code>tf2"
8688 [(set (match_operand:TF 0 "register_operand" "")
8689 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8690 "TARGET_SSE2"
8691 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8692
8693 (define_insn "*absnegtf2_sse"
8694 [(set (match_operand:TF 0 "register_operand" "=x,x")
8695 (match_operator:TF 3 "absneg_operator"
8696 [(match_operand:TF 1 "register_operand" "0,x")]))
8697 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8698 (clobber (reg:CC FLAGS_REG))]
8699 "TARGET_SSE2"
8700 "#")
8701
8702 ;; Splitters for fp abs and neg.
8703
8704 (define_split
8705 [(set (match_operand 0 "fp_register_operand" "")
8706 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8707 (use (match_operand 2 "" ""))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "reload_completed"
8710 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8711
8712 (define_split
8713 [(set (match_operand 0 "register_operand" "")
8714 (match_operator 3 "absneg_operator"
8715 [(match_operand 1 "register_operand" "")]))
8716 (use (match_operand 2 "nonimmediate_operand" ""))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "reload_completed && SSE_REG_P (operands[0])"
8719 [(set (match_dup 0) (match_dup 3))]
8720 {
8721 enum machine_mode mode = GET_MODE (operands[0]);
8722 enum machine_mode vmode = GET_MODE (operands[2]);
8723 rtx tmp;
8724
8725 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8726 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8727 if (operands_match_p (operands[0], operands[2]))
8728 {
8729 tmp = operands[1];
8730 operands[1] = operands[2];
8731 operands[2] = tmp;
8732 }
8733 if (GET_CODE (operands[3]) == ABS)
8734 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8735 else
8736 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8737 operands[3] = tmp;
8738 })
8739
8740 (define_split
8741 [(set (match_operand:SF 0 "register_operand" "")
8742 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8743 (use (match_operand:V4SF 2 "" ""))
8744 (clobber (reg:CC FLAGS_REG))]
8745 "reload_completed"
8746 [(parallel [(set (match_dup 0) (match_dup 1))
8747 (clobber (reg:CC FLAGS_REG))])]
8748 {
8749 rtx tmp;
8750 operands[0] = gen_lowpart (SImode, operands[0]);
8751 if (GET_CODE (operands[1]) == ABS)
8752 {
8753 tmp = gen_int_mode (0x7fffffff, SImode);
8754 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8755 }
8756 else
8757 {
8758 tmp = gen_int_mode (0x80000000, SImode);
8759 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8760 }
8761 operands[1] = tmp;
8762 })
8763
8764 (define_split
8765 [(set (match_operand:DF 0 "register_operand" "")
8766 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8767 (use (match_operand 2 "" ""))
8768 (clobber (reg:CC FLAGS_REG))]
8769 "reload_completed"
8770 [(parallel [(set (match_dup 0) (match_dup 1))
8771 (clobber (reg:CC FLAGS_REG))])]
8772 {
8773 rtx tmp;
8774 if (TARGET_64BIT)
8775 {
8776 tmp = gen_lowpart (DImode, operands[0]);
8777 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8778 operands[0] = tmp;
8779
8780 if (GET_CODE (operands[1]) == ABS)
8781 tmp = const0_rtx;
8782 else
8783 tmp = gen_rtx_NOT (DImode, tmp);
8784 }
8785 else
8786 {
8787 operands[0] = gen_highpart (SImode, operands[0]);
8788 if (GET_CODE (operands[1]) == ABS)
8789 {
8790 tmp = gen_int_mode (0x7fffffff, SImode);
8791 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8792 }
8793 else
8794 {
8795 tmp = gen_int_mode (0x80000000, SImode);
8796 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8797 }
8798 }
8799 operands[1] = tmp;
8800 })
8801
8802 (define_split
8803 [(set (match_operand:XF 0 "register_operand" "")
8804 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8805 (use (match_operand 2 "" ""))
8806 (clobber (reg:CC FLAGS_REG))]
8807 "reload_completed"
8808 [(parallel [(set (match_dup 0) (match_dup 1))
8809 (clobber (reg:CC FLAGS_REG))])]
8810 {
8811 rtx tmp;
8812 operands[0] = gen_rtx_REG (SImode,
8813 true_regnum (operands[0])
8814 + (TARGET_64BIT ? 1 : 2));
8815 if (GET_CODE (operands[1]) == ABS)
8816 {
8817 tmp = GEN_INT (0x7fff);
8818 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8819 }
8820 else
8821 {
8822 tmp = GEN_INT (0x8000);
8823 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8824 }
8825 operands[1] = tmp;
8826 })
8827
8828 ;; Conditionalize these after reload. If they match before reload, we
8829 ;; lose the clobber and ability to use integer instructions.
8830
8831 (define_insn "*<code><mode>2_1"
8832 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8833 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8834 "TARGET_80387
8835 && (reload_completed
8836 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8837 "f<absneg_mnemonic>"
8838 [(set_attr "type" "fsgn")
8839 (set_attr "mode" "<MODE>")])
8840
8841 (define_insn "*<code>extendsfdf2"
8842 [(set (match_operand:DF 0 "register_operand" "=f")
8843 (absneg:DF (float_extend:DF
8844 (match_operand:SF 1 "register_operand" "0"))))]
8845 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8846 "f<absneg_mnemonic>"
8847 [(set_attr "type" "fsgn")
8848 (set_attr "mode" "DF")])
8849
8850 (define_insn "*<code>extendsfxf2"
8851 [(set (match_operand:XF 0 "register_operand" "=f")
8852 (absneg:XF (float_extend:XF
8853 (match_operand:SF 1 "register_operand" "0"))))]
8854 "TARGET_80387"
8855 "f<absneg_mnemonic>"
8856 [(set_attr "type" "fsgn")
8857 (set_attr "mode" "XF")])
8858
8859 (define_insn "*<code>extenddfxf2"
8860 [(set (match_operand:XF 0 "register_operand" "=f")
8861 (absneg:XF (float_extend:XF
8862 (match_operand:DF 1 "register_operand" "0"))))]
8863 "TARGET_80387"
8864 "f<absneg_mnemonic>"
8865 [(set_attr "type" "fsgn")
8866 (set_attr "mode" "XF")])
8867
8868 ;; Copysign instructions
8869
8870 (define_mode_iterator CSGNMODE [SF DF TF])
8871 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8872
8873 (define_expand "copysign<mode>3"
8874 [(match_operand:CSGNMODE 0 "register_operand" "")
8875 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8876 (match_operand:CSGNMODE 2 "register_operand" "")]
8877 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8878 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8879 "ix86_expand_copysign (operands); DONE;")
8880
8881 (define_insn_and_split "copysign<mode>3_const"
8882 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8883 (unspec:CSGNMODE
8884 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8885 (match_operand:CSGNMODE 2 "register_operand" "0")
8886 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8887 UNSPEC_COPYSIGN))]
8888 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8889 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8890 "#"
8891 "&& reload_completed"
8892 [(const_int 0)]
8893 "ix86_split_copysign_const (operands); DONE;")
8894
8895 (define_insn "copysign<mode>3_var"
8896 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8897 (unspec:CSGNMODE
8898 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8899 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8900 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8901 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8902 UNSPEC_COPYSIGN))
8903 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8904 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8905 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8906 "#")
8907
8908 (define_split
8909 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8910 (unspec:CSGNMODE
8911 [(match_operand:CSGNMODE 2 "register_operand" "")
8912 (match_operand:CSGNMODE 3 "register_operand" "")
8913 (match_operand:<CSGNVMODE> 4 "" "")
8914 (match_operand:<CSGNVMODE> 5 "" "")]
8915 UNSPEC_COPYSIGN))
8916 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8917 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8918 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8919 && reload_completed"
8920 [(const_int 0)]
8921 "ix86_split_copysign_var (operands); DONE;")
8922 \f
8923 ;; One complement instructions
8924
8925 (define_expand "one_cmpl<mode>2"
8926 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8927 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8928 ""
8929 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8930
8931 (define_insn "*one_cmpl<mode>2_1"
8932 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8933 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8934 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8935 "not{<imodesuffix>}\t%0"
8936 [(set_attr "type" "negnot")
8937 (set_attr "mode" "<MODE>")])
8938
8939 ;; %%% Potential partial reg stall on alternative 1. What to do?
8940 (define_insn "*one_cmplqi2_1"
8941 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8942 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8943 "ix86_unary_operator_ok (NOT, QImode, operands)"
8944 "@
8945 not{b}\t%0
8946 not{l}\t%k0"
8947 [(set_attr "type" "negnot")
8948 (set_attr "mode" "QI,SI")])
8949
8950 ;; ??? Currently never generated - xor is used instead.
8951 (define_insn "*one_cmplsi2_1_zext"
8952 [(set (match_operand:DI 0 "register_operand" "=r")
8953 (zero_extend:DI
8954 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8955 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8956 "not{l}\t%k0"
8957 [(set_attr "type" "negnot")
8958 (set_attr "mode" "SI")])
8959
8960 (define_insn "*one_cmpl<mode>2_2"
8961 [(set (reg FLAGS_REG)
8962 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8963 (const_int 0)))
8964 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8965 (not:SWI (match_dup 1)))]
8966 "ix86_match_ccmode (insn, CCNOmode)
8967 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8968 "#"
8969 [(set_attr "type" "alu1")
8970 (set_attr "mode" "<MODE>")])
8971
8972 (define_split
8973 [(set (match_operand 0 "flags_reg_operand" "")
8974 (match_operator 2 "compare_operator"
8975 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8976 (const_int 0)]))
8977 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8978 (not:SWI (match_dup 3)))]
8979 "ix86_match_ccmode (insn, CCNOmode)"
8980 [(parallel [(set (match_dup 0)
8981 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8982 (const_int 0)]))
8983 (set (match_dup 1)
8984 (xor:SWI (match_dup 3) (const_int -1)))])])
8985
8986 ;; ??? Currently never generated - xor is used instead.
8987 (define_insn "*one_cmplsi2_2_zext"
8988 [(set (reg FLAGS_REG)
8989 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8990 (const_int 0)))
8991 (set (match_operand:DI 0 "register_operand" "=r")
8992 (zero_extend:DI (not:SI (match_dup 1))))]
8993 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8994 && ix86_unary_operator_ok (NOT, SImode, operands)"
8995 "#"
8996 [(set_attr "type" "alu1")
8997 (set_attr "mode" "SI")])
8998
8999 (define_split
9000 [(set (match_operand 0 "flags_reg_operand" "")
9001 (match_operator 2 "compare_operator"
9002 [(not:SI (match_operand:SI 3 "register_operand" ""))
9003 (const_int 0)]))
9004 (set (match_operand:DI 1 "register_operand" "")
9005 (zero_extend:DI (not:SI (match_dup 3))))]
9006 "ix86_match_ccmode (insn, CCNOmode)"
9007 [(parallel [(set (match_dup 0)
9008 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9009 (const_int 0)]))
9010 (set (match_dup 1)
9011 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9012 \f
9013 ;; Shift instructions
9014
9015 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9016 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9017 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9018 ;; from the assembler input.
9019 ;;
9020 ;; This instruction shifts the target reg/mem as usual, but instead of
9021 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9022 ;; is a left shift double, bits are taken from the high order bits of
9023 ;; reg, else if the insn is a shift right double, bits are taken from the
9024 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9025 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9026 ;;
9027 ;; Since sh[lr]d does not change the `reg' operand, that is done
9028 ;; separately, making all shifts emit pairs of shift double and normal
9029 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9030 ;; support a 63 bit shift, each shift where the count is in a reg expands
9031 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9032 ;;
9033 ;; If the shift count is a constant, we need never emit more than one
9034 ;; shift pair, instead using moves and sign extension for counts greater
9035 ;; than 31.
9036
9037 (define_expand "ashl<mode>3"
9038 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9039 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9040 (match_operand:QI 2 "nonmemory_operand" "")))]
9041 ""
9042 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9043
9044 (define_insn "*ashl<mode>3_doubleword"
9045 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9046 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9047 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9048 (clobber (reg:CC FLAGS_REG))]
9049 ""
9050 "#"
9051 [(set_attr "type" "multi")])
9052
9053 (define_split
9054 [(set (match_operand:DWI 0 "register_operand" "")
9055 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9056 (match_operand:QI 2 "nonmemory_operand" "")))
9057 (clobber (reg:CC FLAGS_REG))]
9058 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9059 [(const_int 0)]
9060 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9061
9062 ;; By default we don't ask for a scratch register, because when DWImode
9063 ;; values are manipulated, registers are already at a premium. But if
9064 ;; we have one handy, we won't turn it away.
9065
9066 (define_peephole2
9067 [(match_scratch:DWIH 3 "r")
9068 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9069 (ashift:<DWI>
9070 (match_operand:<DWI> 1 "nonmemory_operand" "")
9071 (match_operand:QI 2 "nonmemory_operand" "")))
9072 (clobber (reg:CC FLAGS_REG))])
9073 (match_dup 3)]
9074 "TARGET_CMOVE"
9075 [(const_int 0)]
9076 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9077
9078 (define_insn "x86_64_shld"
9079 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9080 (ior:DI (ashift:DI (match_dup 0)
9081 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9082 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9083 (minus:QI (const_int 64) (match_dup 2)))))
9084 (clobber (reg:CC FLAGS_REG))]
9085 "TARGET_64BIT"
9086 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9087 [(set_attr "type" "ishift")
9088 (set_attr "prefix_0f" "1")
9089 (set_attr "mode" "DI")
9090 (set_attr "athlon_decode" "vector")
9091 (set_attr "amdfam10_decode" "vector")])
9092
9093 (define_insn "x86_shld"
9094 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9095 (ior:SI (ashift:SI (match_dup 0)
9096 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9097 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9098 (minus:QI (const_int 32) (match_dup 2)))))
9099 (clobber (reg:CC FLAGS_REG))]
9100 ""
9101 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9102 [(set_attr "type" "ishift")
9103 (set_attr "prefix_0f" "1")
9104 (set_attr "mode" "SI")
9105 (set_attr "pent_pair" "np")
9106 (set_attr "athlon_decode" "vector")
9107 (set_attr "amdfam10_decode" "vector")])
9108
9109 (define_expand "x86_shift<mode>_adj_1"
9110 [(set (reg:CCZ FLAGS_REG)
9111 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9112 (match_dup 4))
9113 (const_int 0)))
9114 (set (match_operand:SWI48 0 "register_operand" "")
9115 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9116 (match_operand:SWI48 1 "register_operand" "")
9117 (match_dup 0)))
9118 (set (match_dup 1)
9119 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9120 (match_operand:SWI48 3 "register_operand" "r")
9121 (match_dup 1)))]
9122 "TARGET_CMOVE"
9123 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9124
9125 (define_expand "x86_shift<mode>_adj_2"
9126 [(use (match_operand:SWI48 0 "register_operand" ""))
9127 (use (match_operand:SWI48 1 "register_operand" ""))
9128 (use (match_operand:QI 2 "register_operand" ""))]
9129 ""
9130 {
9131 rtx label = gen_label_rtx ();
9132 rtx tmp;
9133
9134 emit_insn (gen_testqi_ccz_1 (operands[2],
9135 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9136
9137 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9138 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9139 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9140 gen_rtx_LABEL_REF (VOIDmode, label),
9141 pc_rtx);
9142 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9143 JUMP_LABEL (tmp) = label;
9144
9145 emit_move_insn (operands[0], operands[1]);
9146 ix86_expand_clear (operands[1]);
9147
9148 emit_label (label);
9149 LABEL_NUSES (label) = 1;
9150
9151 DONE;
9152 })
9153
9154 (define_insn "*ashl<mode>3_1"
9155 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9156 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9157 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9158 (clobber (reg:CC FLAGS_REG))]
9159 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9160 {
9161 switch (get_attr_type (insn))
9162 {
9163 case TYPE_LEA:
9164 return "#";
9165
9166 case TYPE_ALU:
9167 gcc_assert (operands[2] == const1_rtx);
9168 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9169 return "add{<imodesuffix>}\t%0, %0";
9170
9171 default:
9172 if (operands[2] == const1_rtx
9173 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9174 return "sal{<imodesuffix>}\t%0";
9175 else
9176 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9177 }
9178 }
9179 [(set (attr "type")
9180 (cond [(eq_attr "alternative" "1")
9181 (const_string "lea")
9182 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9183 (const_int 0))
9184 (match_operand 0 "register_operand" ""))
9185 (match_operand 2 "const1_operand" ""))
9186 (const_string "alu")
9187 ]
9188 (const_string "ishift")))
9189 (set (attr "length_immediate")
9190 (if_then_else
9191 (ior (eq_attr "type" "alu")
9192 (and (eq_attr "type" "ishift")
9193 (and (match_operand 2 "const1_operand" "")
9194 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9195 (const_int 0)))))
9196 (const_string "0")
9197 (const_string "*")))
9198 (set_attr "mode" "<MODE>")])
9199
9200 (define_insn "*ashlsi3_1_zext"
9201 [(set (match_operand:DI 0 "register_operand" "=r,r")
9202 (zero_extend:DI
9203 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9204 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9205 (clobber (reg:CC FLAGS_REG))]
9206 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9207 {
9208 switch (get_attr_type (insn))
9209 {
9210 case TYPE_LEA:
9211 return "#";
9212
9213 case TYPE_ALU:
9214 gcc_assert (operands[2] == const1_rtx);
9215 return "add{l}\t%k0, %k0";
9216
9217 default:
9218 if (operands[2] == const1_rtx
9219 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9220 return "sal{l}\t%k0";
9221 else
9222 return "sal{l}\t{%2, %k0|%k0, %2}";
9223 }
9224 }
9225 [(set (attr "type")
9226 (cond [(eq_attr "alternative" "1")
9227 (const_string "lea")
9228 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9229 (const_int 0))
9230 (match_operand 2 "const1_operand" ""))
9231 (const_string "alu")
9232 ]
9233 (const_string "ishift")))
9234 (set (attr "length_immediate")
9235 (if_then_else
9236 (ior (eq_attr "type" "alu")
9237 (and (eq_attr "type" "ishift")
9238 (and (match_operand 2 "const1_operand" "")
9239 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9240 (const_int 0)))))
9241 (const_string "0")
9242 (const_string "*")))
9243 (set_attr "mode" "SI")])
9244
9245 (define_insn "*ashlhi3_1"
9246 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9247 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9248 (match_operand:QI 2 "nonmemory_operand" "cI")))
9249 (clobber (reg:CC FLAGS_REG))]
9250 "TARGET_PARTIAL_REG_STALL
9251 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9252 {
9253 switch (get_attr_type (insn))
9254 {
9255 case TYPE_ALU:
9256 gcc_assert (operands[2] == const1_rtx);
9257 return "add{w}\t%0, %0";
9258
9259 default:
9260 if (operands[2] == const1_rtx
9261 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9262 return "sal{w}\t%0";
9263 else
9264 return "sal{w}\t{%2, %0|%0, %2}";
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" "HI")])
9285
9286 (define_insn "*ashlhi3_1_lea"
9287 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9288 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9289 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9290 (clobber (reg:CC FLAGS_REG))]
9291 "!TARGET_PARTIAL_REG_STALL
9292 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9293 {
9294 switch (get_attr_type (insn))
9295 {
9296 case TYPE_LEA:
9297 return "#";
9298
9299 case TYPE_ALU:
9300 gcc_assert (operands[2] == const1_rtx);
9301 return "add{w}\t%0, %0";
9302
9303 default:
9304 if (operands[2] == const1_rtx
9305 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9306 return "sal{w}\t%0";
9307 else
9308 return "sal{w}\t{%2, %0|%0, %2}";
9309 }
9310 }
9311 [(set (attr "type")
9312 (cond [(eq_attr "alternative" "1")
9313 (const_string "lea")
9314 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9315 (const_int 0))
9316 (match_operand 0 "register_operand" ""))
9317 (match_operand 2 "const1_operand" ""))
9318 (const_string "alu")
9319 ]
9320 (const_string "ishift")))
9321 (set (attr "length_immediate")
9322 (if_then_else
9323 (ior (eq_attr "type" "alu")
9324 (and (eq_attr "type" "ishift")
9325 (and (match_operand 2 "const1_operand" "")
9326 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9327 (const_int 0)))))
9328 (const_string "0")
9329 (const_string "*")))
9330 (set_attr "mode" "HI,SI")])
9331
9332 (define_insn "*ashlqi3_1"
9333 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9334 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9335 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9336 (clobber (reg:CC FLAGS_REG))]
9337 "TARGET_PARTIAL_REG_STALL
9338 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9339 {
9340 switch (get_attr_type (insn))
9341 {
9342 case TYPE_ALU:
9343 gcc_assert (operands[2] == const1_rtx);
9344 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9345 return "add{l}\t%k0, %k0";
9346 else
9347 return "add{b}\t%0, %0";
9348
9349 default:
9350 if (operands[2] == const1_rtx
9351 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9352 {
9353 if (get_attr_mode (insn) == MODE_SI)
9354 return "sal{l}\t%k0";
9355 else
9356 return "sal{b}\t%0";
9357 }
9358 else
9359 {
9360 if (get_attr_mode (insn) == MODE_SI)
9361 return "sal{l}\t{%2, %k0|%k0, %2}";
9362 else
9363 return "sal{b}\t{%2, %0|%0, %2}";
9364 }
9365 }
9366 }
9367 [(set (attr "type")
9368 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9369 (const_int 0))
9370 (match_operand 0 "register_operand" ""))
9371 (match_operand 2 "const1_operand" ""))
9372 (const_string "alu")
9373 ]
9374 (const_string "ishift")))
9375 (set (attr "length_immediate")
9376 (if_then_else
9377 (ior (eq_attr "type" "alu")
9378 (and (eq_attr "type" "ishift")
9379 (and (match_operand 2 "const1_operand" "")
9380 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9381 (const_int 0)))))
9382 (const_string "0")
9383 (const_string "*")))
9384 (set_attr "mode" "QI,SI")])
9385
9386 ;; %%% Potential partial reg stall on alternative 2. What to do?
9387 (define_insn "*ashlqi3_1_lea"
9388 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9389 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9390 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9391 (clobber (reg:CC FLAGS_REG))]
9392 "!TARGET_PARTIAL_REG_STALL
9393 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9394 {
9395 switch (get_attr_type (insn))
9396 {
9397 case TYPE_LEA:
9398 return "#";
9399
9400 case TYPE_ALU:
9401 gcc_assert (operands[2] == const1_rtx);
9402 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9403 return "add{l}\t%k0, %k0";
9404 else
9405 return "add{b}\t%0, %0";
9406
9407 default:
9408 if (operands[2] == const1_rtx
9409 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9410 {
9411 if (get_attr_mode (insn) == MODE_SI)
9412 return "sal{l}\t%k0";
9413 else
9414 return "sal{b}\t%0";
9415 }
9416 else
9417 {
9418 if (get_attr_mode (insn) == MODE_SI)
9419 return "sal{l}\t{%2, %k0|%k0, %2}";
9420 else
9421 return "sal{b}\t{%2, %0|%0, %2}";
9422 }
9423 }
9424 }
9425 [(set (attr "type")
9426 (cond [(eq_attr "alternative" "2")
9427 (const_string "lea")
9428 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9429 (const_int 0))
9430 (match_operand 0 "register_operand" ""))
9431 (match_operand 2 "const1_operand" ""))
9432 (const_string "alu")
9433 ]
9434 (const_string "ishift")))
9435 (set (attr "length_immediate")
9436 (if_then_else
9437 (ior (eq_attr "type" "alu")
9438 (and (eq_attr "type" "ishift")
9439 (and (match_operand 2 "const1_operand" "")
9440 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9441 (const_int 0)))))
9442 (const_string "0")
9443 (const_string "*")))
9444 (set_attr "mode" "QI,SI,SI")])
9445
9446 (define_insn "*ashlqi3_1_slp"
9447 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9448 (ashift:QI (match_dup 0)
9449 (match_operand:QI 1 "nonmemory_operand" "cI")))
9450 (clobber (reg:CC FLAGS_REG))]
9451 "(optimize_function_for_size_p (cfun)
9452 || !TARGET_PARTIAL_FLAG_REG_STALL
9453 || (operands[1] == const1_rtx
9454 && (TARGET_SHIFT1
9455 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9456 {
9457 switch (get_attr_type (insn))
9458 {
9459 case TYPE_ALU:
9460 gcc_assert (operands[1] == const1_rtx);
9461 return "add{b}\t%0, %0";
9462
9463 default:
9464 if (operands[1] == const1_rtx
9465 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9466 return "sal{b}\t%0";
9467 else
9468 return "sal{b}\t{%1, %0|%0, %1}";
9469 }
9470 }
9471 [(set (attr "type")
9472 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9473 (const_int 0))
9474 (match_operand 0 "register_operand" ""))
9475 (match_operand 1 "const1_operand" ""))
9476 (const_string "alu")
9477 ]
9478 (const_string "ishift1")))
9479 (set (attr "length_immediate")
9480 (if_then_else
9481 (ior (eq_attr "type" "alu")
9482 (and (eq_attr "type" "ishift1")
9483 (and (match_operand 1 "const1_operand" "")
9484 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9485 (const_int 0)))))
9486 (const_string "0")
9487 (const_string "*")))
9488 (set_attr "mode" "QI")])
9489
9490 ;; Convert lea to the lea pattern to avoid flags dependency.
9491 (define_split
9492 [(set (match_operand 0 "register_operand" "")
9493 (ashift (match_operand 1 "index_register_operand" "")
9494 (match_operand:QI 2 "const_int_operand" "")))
9495 (clobber (reg:CC FLAGS_REG))]
9496 "reload_completed
9497 && true_regnum (operands[0]) != true_regnum (operands[1])"
9498 [(const_int 0)]
9499 {
9500 rtx pat;
9501 enum machine_mode mode = GET_MODE (operands[0]);
9502
9503 if (mode != Pmode)
9504 operands[1] = gen_lowpart (Pmode, operands[1]);
9505 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9506
9507 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9508
9509 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9510 operands[0] = gen_lowpart (SImode, operands[0]);
9511
9512 if (TARGET_64BIT && mode != Pmode)
9513 pat = gen_rtx_SUBREG (SImode, pat, 0);
9514
9515 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9516 DONE;
9517 })
9518
9519 ;; Convert lea to the lea pattern to avoid flags dependency.
9520 (define_split
9521 [(set (match_operand:DI 0 "register_operand" "")
9522 (zero_extend:DI
9523 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9524 (match_operand:QI 2 "const_int_operand" ""))))
9525 (clobber (reg:CC FLAGS_REG))]
9526 "TARGET_64BIT && reload_completed
9527 && true_regnum (operands[0]) != true_regnum (operands[1])"
9528 [(set (match_dup 0)
9529 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9530 {
9531 operands[1] = gen_lowpart (DImode, operands[1]);
9532 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9533 })
9534
9535 ;; This pattern can't accept a variable shift count, since shifts by
9536 ;; zero don't affect the flags. We assume that shifts by constant
9537 ;; zero are optimized away.
9538 (define_insn "*ashl<mode>3_cmp"
9539 [(set (reg FLAGS_REG)
9540 (compare
9541 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9542 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9543 (const_int 0)))
9544 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9545 (ashift:SWI (match_dup 1) (match_dup 2)))]
9546 "(optimize_function_for_size_p (cfun)
9547 || !TARGET_PARTIAL_FLAG_REG_STALL
9548 || (operands[2] == const1_rtx
9549 && (TARGET_SHIFT1
9550 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9551 && ix86_match_ccmode (insn, CCGOCmode)
9552 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9553 {
9554 switch (get_attr_type (insn))
9555 {
9556 case TYPE_ALU:
9557 gcc_assert (operands[2] == const1_rtx);
9558 return "add{<imodesuffix>}\t%0, %0";
9559
9560 default:
9561 if (operands[2] == const1_rtx
9562 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9563 return "sal{<imodesuffix>}\t%0";
9564 else
9565 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9566 }
9567 }
9568 [(set (attr "type")
9569 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9570 (const_int 0))
9571 (match_operand 0 "register_operand" ""))
9572 (match_operand 2 "const1_operand" ""))
9573 (const_string "alu")
9574 ]
9575 (const_string "ishift")))
9576 (set (attr "length_immediate")
9577 (if_then_else
9578 (ior (eq_attr "type" "alu")
9579 (and (eq_attr "type" "ishift")
9580 (and (match_operand 2 "const1_operand" "")
9581 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9582 (const_int 0)))))
9583 (const_string "0")
9584 (const_string "*")))
9585 (set_attr "mode" "<MODE>")])
9586
9587 (define_insn "*ashlsi3_cmp_zext"
9588 [(set (reg FLAGS_REG)
9589 (compare
9590 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9591 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9592 (const_int 0)))
9593 (set (match_operand:DI 0 "register_operand" "=r")
9594 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9595 "TARGET_64BIT
9596 && (optimize_function_for_size_p (cfun)
9597 || !TARGET_PARTIAL_FLAG_REG_STALL
9598 || (operands[2] == const1_rtx
9599 && (TARGET_SHIFT1
9600 || TARGET_DOUBLE_WITH_ADD)))
9601 && ix86_match_ccmode (insn, CCGOCmode)
9602 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9603 {
9604 switch (get_attr_type (insn))
9605 {
9606 case TYPE_ALU:
9607 gcc_assert (operands[2] == const1_rtx);
9608 return "add{l}\t%k0, %k0";
9609
9610 default:
9611 if (operands[2] == const1_rtx
9612 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9613 return "sal{l}\t%k0";
9614 else
9615 return "sal{l}\t{%2, %k0|%k0, %2}";
9616 }
9617 }
9618 [(set (attr "type")
9619 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9620 (const_int 0))
9621 (match_operand 2 "const1_operand" ""))
9622 (const_string "alu")
9623 ]
9624 (const_string "ishift")))
9625 (set (attr "length_immediate")
9626 (if_then_else
9627 (ior (eq_attr "type" "alu")
9628 (and (eq_attr "type" "ishift")
9629 (and (match_operand 2 "const1_operand" "")
9630 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9631 (const_int 0)))))
9632 (const_string "0")
9633 (const_string "*")))
9634 (set_attr "mode" "SI")])
9635
9636 (define_insn "*ashl<mode>3_cconly"
9637 [(set (reg FLAGS_REG)
9638 (compare
9639 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9640 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9641 (const_int 0)))
9642 (clobber (match_scratch:SWI 0 "=<r>"))]
9643 "(optimize_function_for_size_p (cfun)
9644 || !TARGET_PARTIAL_FLAG_REG_STALL
9645 || (operands[2] == const1_rtx
9646 && (TARGET_SHIFT1
9647 || TARGET_DOUBLE_WITH_ADD)))
9648 && ix86_match_ccmode (insn, CCGOCmode)
9649 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9650 {
9651 switch (get_attr_type (insn))
9652 {
9653 case TYPE_ALU:
9654 gcc_assert (operands[2] == const1_rtx);
9655 return "add{<imodesuffix>}\t%0, %0";
9656
9657 default:
9658 if (operands[2] == const1_rtx
9659 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9660 return "sal{<imodesuffix>}\t%0";
9661 else
9662 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9663 }
9664 }
9665 [(set (attr "type")
9666 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9667 (const_int 0))
9668 (match_operand 0 "register_operand" ""))
9669 (match_operand 2 "const1_operand" ""))
9670 (const_string "alu")
9671 ]
9672 (const_string "ishift")))
9673 (set (attr "length_immediate")
9674 (if_then_else
9675 (ior (eq_attr "type" "alu")
9676 (and (eq_attr "type" "ishift")
9677 (and (match_operand 2 "const1_operand" "")
9678 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9679 (const_int 0)))))
9680 (const_string "0")
9681 (const_string "*")))
9682 (set_attr "mode" "<MODE>")])
9683
9684 ;; See comment above `ashl<mode>3' about how this works.
9685
9686 (define_expand "<shiftrt_insn><mode>3"
9687 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9688 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9689 (match_operand:QI 2 "nonmemory_operand" "")))]
9690 ""
9691 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9692
9693 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9694 [(set (match_operand:DWI 0 "register_operand" "=r")
9695 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9696 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9697 (clobber (reg:CC FLAGS_REG))]
9698 ""
9699 "#"
9700 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9701 [(const_int 0)]
9702 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9703 [(set_attr "type" "multi")])
9704
9705 ;; By default we don't ask for a scratch register, because when DWImode
9706 ;; values are manipulated, registers are already at a premium. But if
9707 ;; we have one handy, we won't turn it away.
9708
9709 (define_peephole2
9710 [(match_scratch:DWIH 3 "r")
9711 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9712 (any_shiftrt:<DWI>
9713 (match_operand:<DWI> 1 "register_operand" "")
9714 (match_operand:QI 2 "nonmemory_operand" "")))
9715 (clobber (reg:CC FLAGS_REG))])
9716 (match_dup 3)]
9717 "TARGET_CMOVE"
9718 [(const_int 0)]
9719 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9720
9721 (define_insn "x86_64_shrd"
9722 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9723 (ior:DI (ashiftrt:DI (match_dup 0)
9724 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9725 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9726 (minus:QI (const_int 64) (match_dup 2)))))
9727 (clobber (reg:CC FLAGS_REG))]
9728 "TARGET_64BIT"
9729 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9730 [(set_attr "type" "ishift")
9731 (set_attr "prefix_0f" "1")
9732 (set_attr "mode" "DI")
9733 (set_attr "athlon_decode" "vector")
9734 (set_attr "amdfam10_decode" "vector")])
9735
9736 (define_insn "x86_shrd"
9737 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9738 (ior:SI (ashiftrt:SI (match_dup 0)
9739 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9740 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9741 (minus:QI (const_int 32) (match_dup 2)))))
9742 (clobber (reg:CC FLAGS_REG))]
9743 ""
9744 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9745 [(set_attr "type" "ishift")
9746 (set_attr "prefix_0f" "1")
9747 (set_attr "mode" "SI")
9748 (set_attr "pent_pair" "np")
9749 (set_attr "athlon_decode" "vector")
9750 (set_attr "amdfam10_decode" "vector")])
9751
9752 (define_insn "ashrdi3_cvt"
9753 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9754 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9755 (match_operand:QI 2 "const_int_operand" "")))
9756 (clobber (reg:CC FLAGS_REG))]
9757 "TARGET_64BIT && INTVAL (operands[2]) == 63
9758 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9759 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9760 "@
9761 {cqto|cqo}
9762 sar{q}\t{%2, %0|%0, %2}"
9763 [(set_attr "type" "imovx,ishift")
9764 (set_attr "prefix_0f" "0,*")
9765 (set_attr "length_immediate" "0,*")
9766 (set_attr "modrm" "0,1")
9767 (set_attr "mode" "DI")])
9768
9769 (define_insn "ashrsi3_cvt"
9770 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9771 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9772 (match_operand:QI 2 "const_int_operand" "")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "INTVAL (operands[2]) == 31
9775 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9776 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9777 "@
9778 {cltd|cdq}
9779 sar{l}\t{%2, %0|%0, %2}"
9780 [(set_attr "type" "imovx,ishift")
9781 (set_attr "prefix_0f" "0,*")
9782 (set_attr "length_immediate" "0,*")
9783 (set_attr "modrm" "0,1")
9784 (set_attr "mode" "SI")])
9785
9786 (define_insn "*ashrsi3_cvt_zext"
9787 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9788 (zero_extend:DI
9789 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9790 (match_operand:QI 2 "const_int_operand" ""))))
9791 (clobber (reg:CC FLAGS_REG))]
9792 "TARGET_64BIT && INTVAL (operands[2]) == 31
9793 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9794 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9795 "@
9796 {cltd|cdq}
9797 sar{l}\t{%2, %k0|%k0, %2}"
9798 [(set_attr "type" "imovx,ishift")
9799 (set_attr "prefix_0f" "0,*")
9800 (set_attr "length_immediate" "0,*")
9801 (set_attr "modrm" "0,1")
9802 (set_attr "mode" "SI")])
9803
9804 (define_expand "x86_shift<mode>_adj_3"
9805 [(use (match_operand:SWI48 0 "register_operand" ""))
9806 (use (match_operand:SWI48 1 "register_operand" ""))
9807 (use (match_operand:QI 2 "register_operand" ""))]
9808 ""
9809 {
9810 rtx label = gen_label_rtx ();
9811 rtx tmp;
9812
9813 emit_insn (gen_testqi_ccz_1 (operands[2],
9814 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9815
9816 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9817 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9818 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9819 gen_rtx_LABEL_REF (VOIDmode, label),
9820 pc_rtx);
9821 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9822 JUMP_LABEL (tmp) = label;
9823
9824 emit_move_insn (operands[0], operands[1]);
9825 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9826 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9827 emit_label (label);
9828 LABEL_NUSES (label) = 1;
9829
9830 DONE;
9831 })
9832
9833 (define_insn "*<shiftrt_insn><mode>3_1"
9834 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9835 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9836 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9839 {
9840 if (operands[2] == const1_rtx
9841 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9842 return "<shiftrt>{<imodesuffix>}\t%0";
9843 else
9844 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9845 }
9846 [(set_attr "type" "ishift")
9847 (set (attr "length_immediate")
9848 (if_then_else
9849 (and (match_operand 2 "const1_operand" "")
9850 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9851 (const_int 0)))
9852 (const_string "0")
9853 (const_string "*")))
9854 (set_attr "mode" "<MODE>")])
9855
9856 (define_insn "*<shiftrt_insn>si3_1_zext"
9857 [(set (match_operand:DI 0 "register_operand" "=r")
9858 (zero_extend:DI
9859 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9860 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9863 {
9864 if (operands[2] == const1_rtx
9865 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9866 return "<shiftrt>{l}\t%k0";
9867 else
9868 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9869 }
9870 [(set_attr "type" "ishift")
9871 (set (attr "length_immediate")
9872 (if_then_else
9873 (and (match_operand 2 "const1_operand" "")
9874 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9875 (const_int 0)))
9876 (const_string "0")
9877 (const_string "*")))
9878 (set_attr "mode" "SI")])
9879
9880 (define_insn "*<shiftrt_insn>qi3_1_slp"
9881 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9882 (any_shiftrt:QI (match_dup 0)
9883 (match_operand:QI 1 "nonmemory_operand" "cI")))
9884 (clobber (reg:CC FLAGS_REG))]
9885 "(optimize_function_for_size_p (cfun)
9886 || !TARGET_PARTIAL_REG_STALL
9887 || (operands[1] == const1_rtx
9888 && TARGET_SHIFT1))"
9889 {
9890 if (operands[1] == const1_rtx
9891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9892 return "<shiftrt>{b}\t%0";
9893 else
9894 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9895 }
9896 [(set_attr "type" "ishift1")
9897 (set (attr "length_immediate")
9898 (if_then_else
9899 (and (match_operand 1 "const1_operand" "")
9900 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9901 (const_int 0)))
9902 (const_string "0")
9903 (const_string "*")))
9904 (set_attr "mode" "QI")])
9905
9906 ;; This pattern can't accept a variable shift count, since shifts by
9907 ;; zero don't affect the flags. We assume that shifts by constant
9908 ;; zero are optimized away.
9909 (define_insn "*<shiftrt_insn><mode>3_cmp"
9910 [(set (reg FLAGS_REG)
9911 (compare
9912 (any_shiftrt:SWI
9913 (match_operand:SWI 1 "nonimmediate_operand" "0")
9914 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9915 (const_int 0)))
9916 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9917 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9918 "(optimize_function_for_size_p (cfun)
9919 || !TARGET_PARTIAL_FLAG_REG_STALL
9920 || (operands[2] == const1_rtx
9921 && TARGET_SHIFT1))
9922 && ix86_match_ccmode (insn, CCGOCmode)
9923 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9924 {
9925 if (operands[2] == const1_rtx
9926 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9927 return "<shiftrt>{<imodesuffix>}\t%0";
9928 else
9929 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9930 }
9931 [(set_attr "type" "ishift")
9932 (set (attr "length_immediate")
9933 (if_then_else
9934 (and (match_operand 2 "const1_operand" "")
9935 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9936 (const_int 0)))
9937 (const_string "0")
9938 (const_string "*")))
9939 (set_attr "mode" "<MODE>")])
9940
9941 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9942 [(set (reg FLAGS_REG)
9943 (compare
9944 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9945 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9946 (const_int 0)))
9947 (set (match_operand:DI 0 "register_operand" "=r")
9948 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9949 "TARGET_64BIT
9950 && (optimize_function_for_size_p (cfun)
9951 || !TARGET_PARTIAL_FLAG_REG_STALL
9952 || (operands[2] == const1_rtx
9953 && TARGET_SHIFT1))
9954 && ix86_match_ccmode (insn, CCGOCmode)
9955 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9956 {
9957 if (operands[2] == const1_rtx
9958 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9959 return "<shiftrt>{l}\t%k0";
9960 else
9961 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9962 }
9963 [(set_attr "type" "ishift")
9964 (set (attr "length_immediate")
9965 (if_then_else
9966 (and (match_operand 2 "const1_operand" "")
9967 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9968 (const_int 0)))
9969 (const_string "0")
9970 (const_string "*")))
9971 (set_attr "mode" "SI")])
9972
9973 (define_insn "*<shiftrt_insn><mode>3_cconly"
9974 [(set (reg FLAGS_REG)
9975 (compare
9976 (any_shiftrt:SWI
9977 (match_operand:SWI 1 "nonimmediate_operand" "0")
9978 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9979 (const_int 0)))
9980 (clobber (match_scratch:SWI 0 "=<r>"))]
9981 "(optimize_function_for_size_p (cfun)
9982 || !TARGET_PARTIAL_FLAG_REG_STALL
9983 || (operands[2] == const1_rtx
9984 && TARGET_SHIFT1))
9985 && ix86_match_ccmode (insn, CCGOCmode)
9986 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9987 {
9988 if (operands[2] == const1_rtx
9989 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9990 return "<shiftrt>{<imodesuffix>}\t%0";
9991 else
9992 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9993 }
9994 [(set_attr "type" "ishift")
9995 (set (attr "length_immediate")
9996 (if_then_else
9997 (and (match_operand 2 "const1_operand" "")
9998 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9999 (const_int 0)))
10000 (const_string "0")
10001 (const_string "*")))
10002 (set_attr "mode" "<MODE>")])
10003 \f
10004 ;; Rotate instructions
10005
10006 (define_expand "<rotate_insn>ti3"
10007 [(set (match_operand:TI 0 "register_operand" "")
10008 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10009 (match_operand:QI 2 "nonmemory_operand" "")))]
10010 "TARGET_64BIT"
10011 {
10012 if (const_1_to_63_operand (operands[2], VOIDmode))
10013 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10014 (operands[0], operands[1], operands[2]));
10015 else
10016 FAIL;
10017
10018 DONE;
10019 })
10020
10021 (define_expand "<rotate_insn>di3"
10022 [(set (match_operand:DI 0 "shiftdi_operand" "")
10023 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10024 (match_operand:QI 2 "nonmemory_operand" "")))]
10025 ""
10026 {
10027 if (TARGET_64BIT)
10028 ix86_expand_binary_operator (<CODE>, DImode, operands);
10029 else if (const_1_to_31_operand (operands[2], VOIDmode))
10030 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10031 (operands[0], operands[1], operands[2]));
10032 else
10033 FAIL;
10034
10035 DONE;
10036 })
10037
10038 (define_expand "<rotate_insn><mode>3"
10039 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10040 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10041 (match_operand:QI 2 "nonmemory_operand" "")))]
10042 ""
10043 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10044
10045 ;; Implement rotation using two double-precision
10046 ;; shift instructions and a scratch register.
10047
10048 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10049 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10050 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10051 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10052 (clobber (reg:CC FLAGS_REG))
10053 (clobber (match_scratch:DWIH 3 "=&r"))]
10054 ""
10055 "#"
10056 "reload_completed"
10057 [(set (match_dup 3) (match_dup 4))
10058 (parallel
10059 [(set (match_dup 4)
10060 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10061 (lshiftrt:DWIH (match_dup 5)
10062 (minus:QI (match_dup 6) (match_dup 2)))))
10063 (clobber (reg:CC FLAGS_REG))])
10064 (parallel
10065 [(set (match_dup 5)
10066 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10067 (lshiftrt:DWIH (match_dup 3)
10068 (minus:QI (match_dup 6) (match_dup 2)))))
10069 (clobber (reg:CC FLAGS_REG))])]
10070 {
10071 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10072
10073 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10074 })
10075
10076 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10077 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10078 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10079 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10080 (clobber (reg:CC FLAGS_REG))
10081 (clobber (match_scratch:DWIH 3 "=&r"))]
10082 ""
10083 "#"
10084 "reload_completed"
10085 [(set (match_dup 3) (match_dup 4))
10086 (parallel
10087 [(set (match_dup 4)
10088 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10089 (ashift:DWIH (match_dup 5)
10090 (minus:QI (match_dup 6) (match_dup 2)))))
10091 (clobber (reg:CC FLAGS_REG))])
10092 (parallel
10093 [(set (match_dup 5)
10094 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10095 (ashift:DWIH (match_dup 3)
10096 (minus:QI (match_dup 6) (match_dup 2)))))
10097 (clobber (reg:CC FLAGS_REG))])]
10098 {
10099 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10100
10101 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10102 })
10103
10104 (define_insn "*<rotate_insn><mode>3_1"
10105 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10106 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10107 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10108 (clobber (reg:CC FLAGS_REG))]
10109 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10110 {
10111 if (operands[2] == const1_rtx
10112 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10113 return "<rotate>{<imodesuffix>}\t%0";
10114 else
10115 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10116 }
10117 [(set_attr "type" "rotate")
10118 (set (attr "length_immediate")
10119 (if_then_else
10120 (and (match_operand 2 "const1_operand" "")
10121 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10122 (const_int 0)))
10123 (const_string "0")
10124 (const_string "*")))
10125 (set_attr "mode" "<MODE>")])
10126
10127 (define_insn "*<rotate_insn>si3_1_zext"
10128 [(set (match_operand:DI 0 "register_operand" "=r")
10129 (zero_extend:DI
10130 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10131 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10132 (clobber (reg:CC FLAGS_REG))]
10133 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10134 {
10135 if (operands[2] == const1_rtx
10136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10137 return "<rotate>{l}\t%k0";
10138 else
10139 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10140 }
10141 [(set_attr "type" "rotate")
10142 (set (attr "length_immediate")
10143 (if_then_else
10144 (and (match_operand 2 "const1_operand" "")
10145 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10146 (const_int 0)))
10147 (const_string "0")
10148 (const_string "*")))
10149 (set_attr "mode" "SI")])
10150
10151 (define_insn "*<rotate_insn>qi3_1_slp"
10152 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10153 (any_rotate:QI (match_dup 0)
10154 (match_operand:QI 1 "nonmemory_operand" "cI")))
10155 (clobber (reg:CC FLAGS_REG))]
10156 "(optimize_function_for_size_p (cfun)
10157 || !TARGET_PARTIAL_REG_STALL
10158 || (operands[1] == const1_rtx
10159 && TARGET_SHIFT1))"
10160 {
10161 if (operands[1] == const1_rtx
10162 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10163 return "<rotate>{b}\t%0";
10164 else
10165 return "<rotate>{b}\t{%1, %0|%0, %1}";
10166 }
10167 [(set_attr "type" "rotate1")
10168 (set (attr "length_immediate")
10169 (if_then_else
10170 (and (match_operand 1 "const1_operand" "")
10171 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10172 (const_int 0)))
10173 (const_string "0")
10174 (const_string "*")))
10175 (set_attr "mode" "QI")])
10176
10177 (define_split
10178 [(set (match_operand:HI 0 "register_operand" "")
10179 (any_rotate:HI (match_dup 0) (const_int 8)))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "reload_completed
10182 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10183 [(parallel [(set (strict_low_part (match_dup 0))
10184 (bswap:HI (match_dup 0)))
10185 (clobber (reg:CC FLAGS_REG))])])
10186 \f
10187 ;; Bit set / bit test instructions
10188
10189 (define_expand "extv"
10190 [(set (match_operand:SI 0 "register_operand" "")
10191 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10192 (match_operand:SI 2 "const8_operand" "")
10193 (match_operand:SI 3 "const8_operand" "")))]
10194 ""
10195 {
10196 /* Handle extractions from %ah et al. */
10197 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10198 FAIL;
10199
10200 /* From mips.md: extract_bit_field doesn't verify that our source
10201 matches the predicate, so check it again here. */
10202 if (! ext_register_operand (operands[1], VOIDmode))
10203 FAIL;
10204 })
10205
10206 (define_expand "extzv"
10207 [(set (match_operand:SI 0 "register_operand" "")
10208 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10209 (match_operand:SI 2 "const8_operand" "")
10210 (match_operand:SI 3 "const8_operand" "")))]
10211 ""
10212 {
10213 /* Handle extractions from %ah et al. */
10214 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10215 FAIL;
10216
10217 /* From mips.md: extract_bit_field doesn't verify that our source
10218 matches the predicate, so check it again here. */
10219 if (! ext_register_operand (operands[1], VOIDmode))
10220 FAIL;
10221 })
10222
10223 (define_expand "insv"
10224 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10225 (match_operand 1 "const8_operand" "")
10226 (match_operand 2 "const8_operand" ""))
10227 (match_operand 3 "register_operand" ""))]
10228 ""
10229 {
10230 rtx (*gen_mov_insv_1) (rtx, rtx);
10231
10232 /* Handle insertions to %ah et al. */
10233 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10234 FAIL;
10235
10236 /* From mips.md: insert_bit_field doesn't verify that our source
10237 matches the predicate, so check it again here. */
10238 if (! ext_register_operand (operands[0], VOIDmode))
10239 FAIL;
10240
10241 gen_mov_insv_1 = (TARGET_64BIT
10242 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10243
10244 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10245 DONE;
10246 })
10247
10248 ;; %%% bts, btr, btc, bt.
10249 ;; In general these instructions are *slow* when applied to memory,
10250 ;; since they enforce atomic operation. When applied to registers,
10251 ;; it depends on the cpu implementation. They're never faster than
10252 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10253 ;; no point. But in 64-bit, we can't hold the relevant immediates
10254 ;; within the instruction itself, so operating on bits in the high
10255 ;; 32-bits of a register becomes easier.
10256 ;;
10257 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10258 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10259 ;; negdf respectively, so they can never be disabled entirely.
10260
10261 (define_insn "*btsq"
10262 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10263 (const_int 1)
10264 (match_operand:DI 1 "const_0_to_63_operand" ""))
10265 (const_int 1))
10266 (clobber (reg:CC FLAGS_REG))]
10267 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10268 "bts{q}\t{%1, %0|%0, %1}"
10269 [(set_attr "type" "alu1")
10270 (set_attr "prefix_0f" "1")
10271 (set_attr "mode" "DI")])
10272
10273 (define_insn "*btrq"
10274 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10275 (const_int 1)
10276 (match_operand:DI 1 "const_0_to_63_operand" ""))
10277 (const_int 0))
10278 (clobber (reg:CC FLAGS_REG))]
10279 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10280 "btr{q}\t{%1, %0|%0, %1}"
10281 [(set_attr "type" "alu1")
10282 (set_attr "prefix_0f" "1")
10283 (set_attr "mode" "DI")])
10284
10285 (define_insn "*btcq"
10286 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10287 (const_int 1)
10288 (match_operand:DI 1 "const_0_to_63_operand" ""))
10289 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10290 (clobber (reg:CC FLAGS_REG))]
10291 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10292 "btc{q}\t{%1, %0|%0, %1}"
10293 [(set_attr "type" "alu1")
10294 (set_attr "prefix_0f" "1")
10295 (set_attr "mode" "DI")])
10296
10297 ;; Allow Nocona to avoid these instructions if a register is available.
10298
10299 (define_peephole2
10300 [(match_scratch:DI 2 "r")
10301 (parallel [(set (zero_extract:DI
10302 (match_operand:DI 0 "register_operand" "")
10303 (const_int 1)
10304 (match_operand:DI 1 "const_0_to_63_operand" ""))
10305 (const_int 1))
10306 (clobber (reg:CC FLAGS_REG))])]
10307 "TARGET_64BIT && !TARGET_USE_BT"
10308 [(const_int 0)]
10309 {
10310 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10311 rtx op1;
10312
10313 if (HOST_BITS_PER_WIDE_INT >= 64)
10314 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10315 else if (i < HOST_BITS_PER_WIDE_INT)
10316 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10317 else
10318 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10319
10320 op1 = immed_double_const (lo, hi, DImode);
10321 if (i >= 31)
10322 {
10323 emit_move_insn (operands[2], op1);
10324 op1 = operands[2];
10325 }
10326
10327 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10328 DONE;
10329 })
10330
10331 (define_peephole2
10332 [(match_scratch:DI 2 "r")
10333 (parallel [(set (zero_extract:DI
10334 (match_operand:DI 0 "register_operand" "")
10335 (const_int 1)
10336 (match_operand:DI 1 "const_0_to_63_operand" ""))
10337 (const_int 0))
10338 (clobber (reg:CC FLAGS_REG))])]
10339 "TARGET_64BIT && !TARGET_USE_BT"
10340 [(const_int 0)]
10341 {
10342 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10343 rtx op1;
10344
10345 if (HOST_BITS_PER_WIDE_INT >= 64)
10346 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10347 else if (i < HOST_BITS_PER_WIDE_INT)
10348 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10349 else
10350 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10351
10352 op1 = immed_double_const (~lo, ~hi, DImode);
10353 if (i >= 32)
10354 {
10355 emit_move_insn (operands[2], op1);
10356 op1 = operands[2];
10357 }
10358
10359 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10360 DONE;
10361 })
10362
10363 (define_peephole2
10364 [(match_scratch:DI 2 "r")
10365 (parallel [(set (zero_extract:DI
10366 (match_operand:DI 0 "register_operand" "")
10367 (const_int 1)
10368 (match_operand:DI 1 "const_0_to_63_operand" ""))
10369 (not:DI (zero_extract:DI
10370 (match_dup 0) (const_int 1) (match_dup 1))))
10371 (clobber (reg:CC FLAGS_REG))])]
10372 "TARGET_64BIT && !TARGET_USE_BT"
10373 [(const_int 0)]
10374 {
10375 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10376 rtx op1;
10377
10378 if (HOST_BITS_PER_WIDE_INT >= 64)
10379 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10380 else if (i < HOST_BITS_PER_WIDE_INT)
10381 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10382 else
10383 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10384
10385 op1 = immed_double_const (lo, hi, DImode);
10386 if (i >= 31)
10387 {
10388 emit_move_insn (operands[2], op1);
10389 op1 = operands[2];
10390 }
10391
10392 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10393 DONE;
10394 })
10395
10396 (define_insn "*bt<mode>"
10397 [(set (reg:CCC FLAGS_REG)
10398 (compare:CCC
10399 (zero_extract:SWI48
10400 (match_operand:SWI48 0 "register_operand" "r")
10401 (const_int 1)
10402 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10403 (const_int 0)))]
10404 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10405 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10406 [(set_attr "type" "alu1")
10407 (set_attr "prefix_0f" "1")
10408 (set_attr "mode" "<MODE>")])
10409 \f
10410 ;; Store-flag instructions.
10411
10412 ;; For all sCOND expanders, also expand the compare or test insn that
10413 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10414
10415 (define_insn_and_split "*setcc_di_1"
10416 [(set (match_operand:DI 0 "register_operand" "=q")
10417 (match_operator:DI 1 "ix86_comparison_operator"
10418 [(reg FLAGS_REG) (const_int 0)]))]
10419 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10420 "#"
10421 "&& reload_completed"
10422 [(set (match_dup 2) (match_dup 1))
10423 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10424 {
10425 PUT_MODE (operands[1], QImode);
10426 operands[2] = gen_lowpart (QImode, operands[0]);
10427 })
10428
10429 (define_insn_and_split "*setcc_si_1_and"
10430 [(set (match_operand:SI 0 "register_operand" "=q")
10431 (match_operator:SI 1 "ix86_comparison_operator"
10432 [(reg FLAGS_REG) (const_int 0)]))
10433 (clobber (reg:CC FLAGS_REG))]
10434 "!TARGET_PARTIAL_REG_STALL
10435 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10436 "#"
10437 "&& reload_completed"
10438 [(set (match_dup 2) (match_dup 1))
10439 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10440 (clobber (reg:CC FLAGS_REG))])]
10441 {
10442 PUT_MODE (operands[1], QImode);
10443 operands[2] = gen_lowpart (QImode, operands[0]);
10444 })
10445
10446 (define_insn_and_split "*setcc_si_1_movzbl"
10447 [(set (match_operand:SI 0 "register_operand" "=q")
10448 (match_operator:SI 1 "ix86_comparison_operator"
10449 [(reg FLAGS_REG) (const_int 0)]))]
10450 "!TARGET_PARTIAL_REG_STALL
10451 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10452 "#"
10453 "&& reload_completed"
10454 [(set (match_dup 2) (match_dup 1))
10455 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10456 {
10457 PUT_MODE (operands[1], QImode);
10458 operands[2] = gen_lowpart (QImode, operands[0]);
10459 })
10460
10461 (define_insn "*setcc_qi"
10462 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10463 (match_operator:QI 1 "ix86_comparison_operator"
10464 [(reg FLAGS_REG) (const_int 0)]))]
10465 ""
10466 "set%C1\t%0"
10467 [(set_attr "type" "setcc")
10468 (set_attr "mode" "QI")])
10469
10470 (define_insn "*setcc_qi_slp"
10471 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10472 (match_operator:QI 1 "ix86_comparison_operator"
10473 [(reg FLAGS_REG) (const_int 0)]))]
10474 ""
10475 "set%C1\t%0"
10476 [(set_attr "type" "setcc")
10477 (set_attr "mode" "QI")])
10478
10479 ;; In general it is not safe to assume too much about CCmode registers,
10480 ;; so simplify-rtx stops when it sees a second one. Under certain
10481 ;; conditions this is safe on x86, so help combine not create
10482 ;;
10483 ;; seta %al
10484 ;; testb %al, %al
10485 ;; sete %al
10486
10487 (define_split
10488 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10489 (ne:QI (match_operator 1 "ix86_comparison_operator"
10490 [(reg FLAGS_REG) (const_int 0)])
10491 (const_int 0)))]
10492 ""
10493 [(set (match_dup 0) (match_dup 1))]
10494 "PUT_MODE (operands[1], QImode);")
10495
10496 (define_split
10497 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10498 (ne:QI (match_operator 1 "ix86_comparison_operator"
10499 [(reg FLAGS_REG) (const_int 0)])
10500 (const_int 0)))]
10501 ""
10502 [(set (match_dup 0) (match_dup 1))]
10503 "PUT_MODE (operands[1], QImode);")
10504
10505 (define_split
10506 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10507 (eq:QI (match_operator 1 "ix86_comparison_operator"
10508 [(reg FLAGS_REG) (const_int 0)])
10509 (const_int 0)))]
10510 ""
10511 [(set (match_dup 0) (match_dup 1))]
10512 {
10513 rtx new_op1 = copy_rtx (operands[1]);
10514 operands[1] = new_op1;
10515 PUT_MODE (new_op1, QImode);
10516 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10517 GET_MODE (XEXP (new_op1, 0))));
10518
10519 /* Make sure that (a) the CCmode we have for the flags is strong
10520 enough for the reversed compare or (b) we have a valid FP compare. */
10521 if (! ix86_comparison_operator (new_op1, VOIDmode))
10522 FAIL;
10523 })
10524
10525 (define_split
10526 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10527 (eq:QI (match_operator 1 "ix86_comparison_operator"
10528 [(reg FLAGS_REG) (const_int 0)])
10529 (const_int 0)))]
10530 ""
10531 [(set (match_dup 0) (match_dup 1))]
10532 {
10533 rtx new_op1 = copy_rtx (operands[1]);
10534 operands[1] = new_op1;
10535 PUT_MODE (new_op1, QImode);
10536 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10537 GET_MODE (XEXP (new_op1, 0))));
10538
10539 /* Make sure that (a) the CCmode we have for the flags is strong
10540 enough for the reversed compare or (b) we have a valid FP compare. */
10541 if (! ix86_comparison_operator (new_op1, VOIDmode))
10542 FAIL;
10543 })
10544
10545 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10546 ;; subsequent logical operations are used to imitate conditional moves.
10547 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10548 ;; it directly.
10549
10550 (define_insn "*avx_setcc<mode>"
10551 [(set (match_operand:MODEF 0 "register_operand" "=x")
10552 (match_operator:MODEF 1 "avx_comparison_float_operator"
10553 [(match_operand:MODEF 2 "register_operand" "x")
10554 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10555 "TARGET_AVX"
10556 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10557 [(set_attr "type" "ssecmp")
10558 (set_attr "prefix" "vex")
10559 (set_attr "length_immediate" "1")
10560 (set_attr "mode" "<MODE>")])
10561
10562 (define_insn "*sse_setcc<mode>"
10563 [(set (match_operand:MODEF 0 "register_operand" "=x")
10564 (match_operator:MODEF 1 "sse_comparison_operator"
10565 [(match_operand:MODEF 2 "register_operand" "0")
10566 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10567 "SSE_FLOAT_MODE_P (<MODE>mode)"
10568 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10569 [(set_attr "type" "ssecmp")
10570 (set_attr "length_immediate" "1")
10571 (set_attr "mode" "<MODE>")])
10572 \f
10573 ;; Basic conditional jump instructions.
10574 ;; We ignore the overflow flag for signed branch instructions.
10575
10576 (define_insn "*jcc_1"
10577 [(set (pc)
10578 (if_then_else (match_operator 1 "ix86_comparison_operator"
10579 [(reg FLAGS_REG) (const_int 0)])
10580 (label_ref (match_operand 0 "" ""))
10581 (pc)))]
10582 ""
10583 "%+j%C1\t%l0"
10584 [(set_attr "type" "ibr")
10585 (set_attr "modrm" "0")
10586 (set (attr "length")
10587 (if_then_else (and (ge (minus (match_dup 0) (pc))
10588 (const_int -126))
10589 (lt (minus (match_dup 0) (pc))
10590 (const_int 128)))
10591 (const_int 2)
10592 (const_int 6)))])
10593
10594 (define_insn "*jcc_2"
10595 [(set (pc)
10596 (if_then_else (match_operator 1 "ix86_comparison_operator"
10597 [(reg FLAGS_REG) (const_int 0)])
10598 (pc)
10599 (label_ref (match_operand 0 "" ""))))]
10600 ""
10601 "%+j%c1\t%l0"
10602 [(set_attr "type" "ibr")
10603 (set_attr "modrm" "0")
10604 (set (attr "length")
10605 (if_then_else (and (ge (minus (match_dup 0) (pc))
10606 (const_int -126))
10607 (lt (minus (match_dup 0) (pc))
10608 (const_int 128)))
10609 (const_int 2)
10610 (const_int 6)))])
10611
10612 ;; In general it is not safe to assume too much about CCmode registers,
10613 ;; so simplify-rtx stops when it sees a second one. Under certain
10614 ;; conditions this is safe on x86, so help combine not create
10615 ;;
10616 ;; seta %al
10617 ;; testb %al, %al
10618 ;; je Lfoo
10619
10620 (define_split
10621 [(set (pc)
10622 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10623 [(reg FLAGS_REG) (const_int 0)])
10624 (const_int 0))
10625 (label_ref (match_operand 1 "" ""))
10626 (pc)))]
10627 ""
10628 [(set (pc)
10629 (if_then_else (match_dup 0)
10630 (label_ref (match_dup 1))
10631 (pc)))]
10632 "PUT_MODE (operands[0], VOIDmode);")
10633
10634 (define_split
10635 [(set (pc)
10636 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10637 [(reg FLAGS_REG) (const_int 0)])
10638 (const_int 0))
10639 (label_ref (match_operand 1 "" ""))
10640 (pc)))]
10641 ""
10642 [(set (pc)
10643 (if_then_else (match_dup 0)
10644 (label_ref (match_dup 1))
10645 (pc)))]
10646 {
10647 rtx new_op0 = copy_rtx (operands[0]);
10648 operands[0] = new_op0;
10649 PUT_MODE (new_op0, VOIDmode);
10650 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10651 GET_MODE (XEXP (new_op0, 0))));
10652
10653 /* Make sure that (a) the CCmode we have for the flags is strong
10654 enough for the reversed compare or (b) we have a valid FP compare. */
10655 if (! ix86_comparison_operator (new_op0, VOIDmode))
10656 FAIL;
10657 })
10658
10659 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10660 ;; pass generates from shift insn with QImode operand. Actually, the mode
10661 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10662 ;; appropriate modulo of the bit offset value.
10663
10664 (define_insn_and_split "*jcc_bt<mode>"
10665 [(set (pc)
10666 (if_then_else (match_operator 0 "bt_comparison_operator"
10667 [(zero_extract:SWI48
10668 (match_operand:SWI48 1 "register_operand" "r")
10669 (const_int 1)
10670 (zero_extend:SI
10671 (match_operand:QI 2 "register_operand" "r")))
10672 (const_int 0)])
10673 (label_ref (match_operand 3 "" ""))
10674 (pc)))
10675 (clobber (reg:CC FLAGS_REG))]
10676 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10677 "#"
10678 "&& 1"
10679 [(set (reg:CCC FLAGS_REG)
10680 (compare:CCC
10681 (zero_extract:SWI48
10682 (match_dup 1)
10683 (const_int 1)
10684 (match_dup 2))
10685 (const_int 0)))
10686 (set (pc)
10687 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10688 (label_ref (match_dup 3))
10689 (pc)))]
10690 {
10691 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10692
10693 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10694 })
10695
10696 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10697 ;; also for DImode, this is what combine produces.
10698 (define_insn_and_split "*jcc_bt<mode>_mask"
10699 [(set (pc)
10700 (if_then_else (match_operator 0 "bt_comparison_operator"
10701 [(zero_extract:SWI48
10702 (match_operand:SWI48 1 "register_operand" "r")
10703 (const_int 1)
10704 (and:SI
10705 (match_operand:SI 2 "register_operand" "r")
10706 (match_operand:SI 3 "const_int_operand" "n")))])
10707 (label_ref (match_operand 4 "" ""))
10708 (pc)))
10709 (clobber (reg:CC FLAGS_REG))]
10710 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10711 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10712 == GET_MODE_BITSIZE (<MODE>mode)-1"
10713 "#"
10714 "&& 1"
10715 [(set (reg:CCC FLAGS_REG)
10716 (compare:CCC
10717 (zero_extract:SWI48
10718 (match_dup 1)
10719 (const_int 1)
10720 (match_dup 2))
10721 (const_int 0)))
10722 (set (pc)
10723 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10724 (label_ref (match_dup 4))
10725 (pc)))]
10726 {
10727 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10728
10729 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10730 })
10731
10732 (define_insn_and_split "*jcc_btsi_1"
10733 [(set (pc)
10734 (if_then_else (match_operator 0 "bt_comparison_operator"
10735 [(and:SI
10736 (lshiftrt:SI
10737 (match_operand:SI 1 "register_operand" "r")
10738 (match_operand:QI 2 "register_operand" "r"))
10739 (const_int 1))
10740 (const_int 0)])
10741 (label_ref (match_operand 3 "" ""))
10742 (pc)))
10743 (clobber (reg:CC FLAGS_REG))]
10744 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10745 "#"
10746 "&& 1"
10747 [(set (reg:CCC FLAGS_REG)
10748 (compare:CCC
10749 (zero_extract:SI
10750 (match_dup 1)
10751 (const_int 1)
10752 (match_dup 2))
10753 (const_int 0)))
10754 (set (pc)
10755 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10756 (label_ref (match_dup 3))
10757 (pc)))]
10758 {
10759 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10760
10761 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10762 })
10763
10764 ;; avoid useless masking of bit offset operand
10765 (define_insn_and_split "*jcc_btsi_mask_1"
10766 [(set (pc)
10767 (if_then_else
10768 (match_operator 0 "bt_comparison_operator"
10769 [(and:SI
10770 (lshiftrt:SI
10771 (match_operand:SI 1 "register_operand" "r")
10772 (subreg:QI
10773 (and:SI
10774 (match_operand:SI 2 "register_operand" "r")
10775 (match_operand:SI 3 "const_int_operand" "n")) 0))
10776 (const_int 1))
10777 (const_int 0)])
10778 (label_ref (match_operand 4 "" ""))
10779 (pc)))
10780 (clobber (reg:CC FLAGS_REG))]
10781 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10782 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10783 "#"
10784 "&& 1"
10785 [(set (reg:CCC FLAGS_REG)
10786 (compare:CCC
10787 (zero_extract:SI
10788 (match_dup 1)
10789 (const_int 1)
10790 (match_dup 2))
10791 (const_int 0)))
10792 (set (pc)
10793 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10794 (label_ref (match_dup 4))
10795 (pc)))]
10796 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10797
10798 ;; Define combination compare-and-branch fp compare instructions to help
10799 ;; combine.
10800
10801 (define_insn "*fp_jcc_1_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 "nonimmediate_operand" "fm")])
10806 (label_ref (match_operand 3 "" ""))
10807 (pc)))
10808 (clobber (reg:CCFP FPSR_REG))
10809 (clobber (reg:CCFP FLAGS_REG))
10810 (clobber (match_scratch:HI 4 "=a"))]
10811 "TARGET_80387
10812 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10813 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10814 && SELECT_CC_MODE (GET_CODE (operands[0]),
10815 operands[1], operands[2]) == CCFPmode
10816 && !TARGET_CMOVE"
10817 "#")
10818
10819 (define_insn "*fp_jcc_1r_387"
10820 [(set (pc)
10821 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10822 [(match_operand 1 "register_operand" "f")
10823 (match_operand 2 "nonimmediate_operand" "fm")])
10824 (pc)
10825 (label_ref (match_operand 3 "" ""))))
10826 (clobber (reg:CCFP FPSR_REG))
10827 (clobber (reg:CCFP FLAGS_REG))
10828 (clobber (match_scratch:HI 4 "=a"))]
10829 "TARGET_80387
10830 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10831 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10832 && SELECT_CC_MODE (GET_CODE (operands[0]),
10833 operands[1], operands[2]) == CCFPmode
10834 && !TARGET_CMOVE"
10835 "#")
10836
10837 (define_insn "*fp_jcc_2_387"
10838 [(set (pc)
10839 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10840 [(match_operand 1 "register_operand" "f")
10841 (match_operand 2 "register_operand" "f")])
10842 (label_ref (match_operand 3 "" ""))
10843 (pc)))
10844 (clobber (reg:CCFP FPSR_REG))
10845 (clobber (reg:CCFP FLAGS_REG))
10846 (clobber (match_scratch:HI 4 "=a"))]
10847 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10848 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10849 && !TARGET_CMOVE"
10850 "#")
10851
10852 (define_insn "*fp_jcc_2r_387"
10853 [(set (pc)
10854 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10855 [(match_operand 1 "register_operand" "f")
10856 (match_operand 2 "register_operand" "f")])
10857 (pc)
10858 (label_ref (match_operand 3 "" ""))))
10859 (clobber (reg:CCFP FPSR_REG))
10860 (clobber (reg:CCFP FLAGS_REG))
10861 (clobber (match_scratch:HI 4 "=a"))]
10862 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10863 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10864 && !TARGET_CMOVE"
10865 "#")
10866
10867 (define_insn "*fp_jcc_3_387"
10868 [(set (pc)
10869 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10870 [(match_operand 1 "register_operand" "f")
10871 (match_operand 2 "const0_operand" "")])
10872 (label_ref (match_operand 3 "" ""))
10873 (pc)))
10874 (clobber (reg:CCFP FPSR_REG))
10875 (clobber (reg:CCFP FLAGS_REG))
10876 (clobber (match_scratch:HI 4 "=a"))]
10877 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10878 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10879 && SELECT_CC_MODE (GET_CODE (operands[0]),
10880 operands[1], operands[2]) == CCFPmode
10881 && !TARGET_CMOVE"
10882 "#")
10883
10884 (define_split
10885 [(set (pc)
10886 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10887 [(match_operand 1 "register_operand" "")
10888 (match_operand 2 "nonimmediate_operand" "")])
10889 (match_operand 3 "" "")
10890 (match_operand 4 "" "")))
10891 (clobber (reg:CCFP FPSR_REG))
10892 (clobber (reg:CCFP FLAGS_REG))]
10893 "reload_completed"
10894 [(const_int 0)]
10895 {
10896 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10897 operands[3], operands[4], NULL_RTX, NULL_RTX);
10898 DONE;
10899 })
10900
10901 (define_split
10902 [(set (pc)
10903 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10904 [(match_operand 1 "register_operand" "")
10905 (match_operand 2 "general_operand" "")])
10906 (match_operand 3 "" "")
10907 (match_operand 4 "" "")))
10908 (clobber (reg:CCFP FPSR_REG))
10909 (clobber (reg:CCFP FLAGS_REG))
10910 (clobber (match_scratch:HI 5 "=a"))]
10911 "reload_completed"
10912 [(const_int 0)]
10913 {
10914 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10915 operands[3], operands[4], operands[5], NULL_RTX);
10916 DONE;
10917 })
10918
10919 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10920 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10921 ;; with a precedence over other operators and is always put in the first
10922 ;; place. Swap condition and operands to match ficom instruction.
10923
10924 (define_insn "*fp_jcc_4_<mode>_387"
10925 [(set (pc)
10926 (if_then_else
10927 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10928 [(match_operator 1 "float_operator"
10929 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10930 (match_operand 3 "register_operand" "f,f")])
10931 (label_ref (match_operand 4 "" ""))
10932 (pc)))
10933 (clobber (reg:CCFP FPSR_REG))
10934 (clobber (reg:CCFP FLAGS_REG))
10935 (clobber (match_scratch:HI 5 "=a,a"))]
10936 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10937 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10938 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10939 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10940 && !TARGET_CMOVE"
10941 "#")
10942
10943 (define_split
10944 [(set (pc)
10945 (if_then_else
10946 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10947 [(match_operator 1 "float_operator"
10948 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10949 (match_operand 3 "register_operand" "")])
10950 (match_operand 4 "" "")
10951 (match_operand 5 "" "")))
10952 (clobber (reg:CCFP FPSR_REG))
10953 (clobber (reg:CCFP FLAGS_REG))
10954 (clobber (match_scratch:HI 6 "=a"))]
10955 "reload_completed"
10956 [(const_int 0)]
10957 {
10958 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10959
10960 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10961 operands[3], operands[7],
10962 operands[4], operands[5], operands[6], NULL_RTX);
10963 DONE;
10964 })
10965
10966 ;; %%% Kill this when reload knows how to do it.
10967 (define_split
10968 [(set (pc)
10969 (if_then_else
10970 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10971 [(match_operator 1 "float_operator"
10972 [(match_operand:X87MODEI12 2 "register_operand" "")])
10973 (match_operand 3 "register_operand" "")])
10974 (match_operand 4 "" "")
10975 (match_operand 5 "" "")))
10976 (clobber (reg:CCFP FPSR_REG))
10977 (clobber (reg:CCFP FLAGS_REG))
10978 (clobber (match_scratch:HI 6 "=a"))]
10979 "reload_completed"
10980 [(const_int 0)]
10981 {
10982 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10983 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10984
10985 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10986 operands[3], operands[7],
10987 operands[4], operands[5], operands[6], operands[2]);
10988 DONE;
10989 })
10990 \f
10991 ;; Unconditional and other jump instructions
10992
10993 (define_insn "jump"
10994 [(set (pc)
10995 (label_ref (match_operand 0 "" "")))]
10996 ""
10997 "jmp\t%l0"
10998 [(set_attr "type" "ibr")
10999 (set (attr "length")
11000 (if_then_else (and (ge (minus (match_dup 0) (pc))
11001 (const_int -126))
11002 (lt (minus (match_dup 0) (pc))
11003 (const_int 128)))
11004 (const_int 2)
11005 (const_int 5)))
11006 (set_attr "modrm" "0")])
11007
11008 (define_expand "indirect_jump"
11009 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11010 ""
11011 "")
11012
11013 (define_insn "*indirect_jump"
11014 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11015 ""
11016 "jmp\t%A0"
11017 [(set_attr "type" "ibr")
11018 (set_attr "length_immediate" "0")])
11019
11020 (define_expand "tablejump"
11021 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11022 (use (label_ref (match_operand 1 "" "")))])]
11023 ""
11024 {
11025 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11026 relative. Convert the relative address to an absolute address. */
11027 if (flag_pic)
11028 {
11029 rtx op0, op1;
11030 enum rtx_code code;
11031
11032 /* We can't use @GOTOFF for text labels on VxWorks;
11033 see gotoff_operand. */
11034 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11035 {
11036 code = PLUS;
11037 op0 = operands[0];
11038 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11039 }
11040 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11041 {
11042 code = PLUS;
11043 op0 = operands[0];
11044 op1 = pic_offset_table_rtx;
11045 }
11046 else
11047 {
11048 code = MINUS;
11049 op0 = pic_offset_table_rtx;
11050 op1 = operands[0];
11051 }
11052
11053 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11054 OPTAB_DIRECT);
11055 }
11056 })
11057
11058 (define_insn "*tablejump_1"
11059 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11060 (use (label_ref (match_operand 1 "" "")))]
11061 ""
11062 "jmp\t%A0"
11063 [(set_attr "type" "ibr")
11064 (set_attr "length_immediate" "0")])
11065 \f
11066 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11067
11068 (define_peephole2
11069 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11070 (set (match_operand:QI 1 "register_operand" "")
11071 (match_operator:QI 2 "ix86_comparison_operator"
11072 [(reg FLAGS_REG) (const_int 0)]))
11073 (set (match_operand 3 "q_regs_operand" "")
11074 (zero_extend (match_dup 1)))]
11075 "(peep2_reg_dead_p (3, operands[1])
11076 || operands_match_p (operands[1], operands[3]))
11077 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11078 [(set (match_dup 4) (match_dup 0))
11079 (set (strict_low_part (match_dup 5))
11080 (match_dup 2))]
11081 {
11082 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11083 operands[5] = gen_lowpart (QImode, operands[3]);
11084 ix86_expand_clear (operands[3]);
11085 })
11086
11087 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11088
11089 (define_peephole2
11090 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11091 (set (match_operand:QI 1 "register_operand" "")
11092 (match_operator:QI 2 "ix86_comparison_operator"
11093 [(reg FLAGS_REG) (const_int 0)]))
11094 (parallel [(set (match_operand 3 "q_regs_operand" "")
11095 (zero_extend (match_dup 1)))
11096 (clobber (reg:CC FLAGS_REG))])]
11097 "(peep2_reg_dead_p (3, operands[1])
11098 || operands_match_p (operands[1], operands[3]))
11099 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11100 [(set (match_dup 4) (match_dup 0))
11101 (set (strict_low_part (match_dup 5))
11102 (match_dup 2))]
11103 {
11104 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11105 operands[5] = gen_lowpart (QImode, operands[3]);
11106 ix86_expand_clear (operands[3]);
11107 })
11108 \f
11109 ;; Call instructions.
11110
11111 ;; The predicates normally associated with named expanders are not properly
11112 ;; checked for calls. This is a bug in the generic code, but it isn't that
11113 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11114
11115 ;; P6 processors will jump to the address after the decrement when %esp
11116 ;; is used as a call operand, so they will execute return address as a code.
11117 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11118
11119 ;; Call subroutine returning no value.
11120
11121 (define_expand "call_pop"
11122 [(parallel [(call (match_operand:QI 0 "" "")
11123 (match_operand:SI 1 "" ""))
11124 (set (reg:SI SP_REG)
11125 (plus:SI (reg:SI SP_REG)
11126 (match_operand:SI 3 "" "")))])]
11127 "!TARGET_64BIT"
11128 {
11129 ix86_expand_call (NULL, operands[0], operands[1],
11130 operands[2], operands[3], 0);
11131 DONE;
11132 })
11133
11134 (define_insn "*call_pop_0"
11135 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11136 (match_operand:SI 1 "" ""))
11137 (set (reg:SI SP_REG)
11138 (plus:SI (reg:SI SP_REG)
11139 (match_operand:SI 2 "immediate_operand" "")))]
11140 "!TARGET_64BIT"
11141 {
11142 if (SIBLING_CALL_P (insn))
11143 return "jmp\t%P0";
11144 else
11145 return "call\t%P0";
11146 }
11147 [(set_attr "type" "call")])
11148
11149 (define_insn "*call_pop_1"
11150 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11151 (match_operand:SI 1 "" ""))
11152 (set (reg:SI SP_REG)
11153 (plus:SI (reg:SI SP_REG)
11154 (match_operand:SI 2 "immediate_operand" "i")))]
11155 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11156 {
11157 if (constant_call_address_operand (operands[0], Pmode))
11158 return "call\t%P0";
11159 return "call\t%A0";
11160 }
11161 [(set_attr "type" "call")])
11162
11163 (define_insn "*sibcall_pop_1"
11164 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11165 (match_operand:SI 1 "" ""))
11166 (set (reg:SI SP_REG)
11167 (plus:SI (reg:SI SP_REG)
11168 (match_operand:SI 2 "immediate_operand" "i,i")))]
11169 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11170 "@
11171 jmp\t%P0
11172 jmp\t%A0"
11173 [(set_attr "type" "call")])
11174
11175 (define_expand "call"
11176 [(call (match_operand:QI 0 "" "")
11177 (match_operand 1 "" ""))
11178 (use (match_operand 2 "" ""))]
11179 ""
11180 {
11181 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11182 DONE;
11183 })
11184
11185 (define_expand "sibcall"
11186 [(call (match_operand:QI 0 "" "")
11187 (match_operand 1 "" ""))
11188 (use (match_operand 2 "" ""))]
11189 ""
11190 {
11191 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11192 DONE;
11193 })
11194
11195 (define_insn "*call_0"
11196 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11197 (match_operand 1 "" ""))]
11198 ""
11199 {
11200 if (SIBLING_CALL_P (insn))
11201 return "jmp\t%P0";
11202 else
11203 return "call\t%P0";
11204 }
11205 [(set_attr "type" "call")])
11206
11207 (define_insn "*call_1"
11208 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11209 (match_operand 1 "" ""))]
11210 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11211 {
11212 if (constant_call_address_operand (operands[0], Pmode))
11213 return "call\t%P0";
11214 return "call\t%A0";
11215 }
11216 [(set_attr "type" "call")])
11217
11218 (define_insn "*sibcall_1"
11219 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11220 (match_operand 1 "" ""))]
11221 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11222 "@
11223 jmp\t%P0
11224 jmp\t%A0"
11225 [(set_attr "type" "call")])
11226
11227 (define_insn "*call_1_rex64"
11228 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11229 (match_operand 1 "" ""))]
11230 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11231 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11232 {
11233 if (constant_call_address_operand (operands[0], Pmode))
11234 return "call\t%P0";
11235 return "call\t%A0";
11236 }
11237 [(set_attr "type" "call")])
11238
11239 (define_insn "*call_1_rex64_ms_sysv"
11240 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11241 (match_operand 1 "" ""))
11242 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11243 (clobber (reg:TI XMM6_REG))
11244 (clobber (reg:TI XMM7_REG))
11245 (clobber (reg:TI XMM8_REG))
11246 (clobber (reg:TI XMM9_REG))
11247 (clobber (reg:TI XMM10_REG))
11248 (clobber (reg:TI XMM11_REG))
11249 (clobber (reg:TI XMM12_REG))
11250 (clobber (reg:TI XMM13_REG))
11251 (clobber (reg:TI XMM14_REG))
11252 (clobber (reg:TI XMM15_REG))
11253 (clobber (reg:DI SI_REG))
11254 (clobber (reg:DI DI_REG))]
11255 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11256 {
11257 if (constant_call_address_operand (operands[0], Pmode))
11258 return "call\t%P0";
11259 return "call\t%A0";
11260 }
11261 [(set_attr "type" "call")])
11262
11263 (define_insn "*call_1_rex64_large"
11264 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11265 (match_operand 1 "" ""))]
11266 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11267 "call\t%A0"
11268 [(set_attr "type" "call")])
11269
11270 (define_insn "*sibcall_1_rex64"
11271 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11272 (match_operand 1 "" ""))]
11273 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11274 "@
11275 jmp\t%P0
11276 jmp\t%A0"
11277 [(set_attr "type" "call")])
11278
11279 ;; Call subroutine, returning value in operand 0
11280 (define_expand "call_value_pop"
11281 [(parallel [(set (match_operand 0 "" "")
11282 (call (match_operand:QI 1 "" "")
11283 (match_operand:SI 2 "" "")))
11284 (set (reg:SI SP_REG)
11285 (plus:SI (reg:SI SP_REG)
11286 (match_operand:SI 4 "" "")))])]
11287 "!TARGET_64BIT"
11288 {
11289 ix86_expand_call (operands[0], operands[1], operands[2],
11290 operands[3], operands[4], 0);
11291 DONE;
11292 })
11293
11294 (define_expand "call_value"
11295 [(set (match_operand 0 "" "")
11296 (call (match_operand:QI 1 "" "")
11297 (match_operand:SI 2 "" "")))
11298 (use (match_operand:SI 3 "" ""))]
11299 ;; Operand 3 is not used on the i386.
11300 ""
11301 {
11302 ix86_expand_call (operands[0], operands[1], operands[2],
11303 operands[3], NULL, 0);
11304 DONE;
11305 })
11306
11307 (define_expand "sibcall_value"
11308 [(set (match_operand 0 "" "")
11309 (call (match_operand:QI 1 "" "")
11310 (match_operand:SI 2 "" "")))
11311 (use (match_operand:SI 3 "" ""))]
11312 ;; Operand 3 is not used on the i386.
11313 ""
11314 {
11315 ix86_expand_call (operands[0], operands[1], operands[2],
11316 operands[3], NULL, 1);
11317 DONE;
11318 })
11319
11320 ;; Call subroutine returning any type.
11321
11322 (define_expand "untyped_call"
11323 [(parallel [(call (match_operand 0 "" "")
11324 (const_int 0))
11325 (match_operand 1 "" "")
11326 (match_operand 2 "" "")])]
11327 ""
11328 {
11329 int i;
11330
11331 /* In order to give reg-stack an easier job in validating two
11332 coprocessor registers as containing a possible return value,
11333 simply pretend the untyped call returns a complex long double
11334 value.
11335
11336 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11337 and should have the default ABI. */
11338
11339 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11340 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11341 operands[0], const0_rtx,
11342 GEN_INT ((TARGET_64BIT
11343 ? (ix86_abi == SYSV_ABI
11344 ? X86_64_SSE_REGPARM_MAX
11345 : X86_64_MS_SSE_REGPARM_MAX)
11346 : X86_32_SSE_REGPARM_MAX)
11347 - 1),
11348 NULL, 0);
11349
11350 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11351 {
11352 rtx set = XVECEXP (operands[2], 0, i);
11353 emit_move_insn (SET_DEST (set), SET_SRC (set));
11354 }
11355
11356 /* The optimizer does not know that the call sets the function value
11357 registers we stored in the result block. We avoid problems by
11358 claiming that all hard registers are used and clobbered at this
11359 point. */
11360 emit_insn (gen_blockage ());
11361
11362 DONE;
11363 })
11364 \f
11365 ;; Prologue and epilogue instructions
11366
11367 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11368 ;; all of memory. This blocks insns from being moved across this point.
11369
11370 (define_insn "blockage"
11371 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11372 ""
11373 ""
11374 [(set_attr "length" "0")])
11375
11376 ;; Do not schedule instructions accessing memory across this point.
11377
11378 (define_expand "memory_blockage"
11379 [(set (match_dup 0)
11380 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11381 ""
11382 {
11383 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11384 MEM_VOLATILE_P (operands[0]) = 1;
11385 })
11386
11387 (define_insn "*memory_blockage"
11388 [(set (match_operand:BLK 0 "" "")
11389 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11390 ""
11391 ""
11392 [(set_attr "length" "0")])
11393
11394 ;; As USE insns aren't meaningful after reload, this is used instead
11395 ;; to prevent deleting instructions setting registers for PIC code
11396 (define_insn "prologue_use"
11397 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11398 ""
11399 ""
11400 [(set_attr "length" "0")])
11401
11402 ;; Insn emitted into the body of a function to return from a function.
11403 ;; This is only done if the function's epilogue is known to be simple.
11404 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11405
11406 (define_expand "return"
11407 [(return)]
11408 "ix86_can_use_return_insn_p ()"
11409 {
11410 if (crtl->args.pops_args)
11411 {
11412 rtx popc = GEN_INT (crtl->args.pops_args);
11413 emit_jump_insn (gen_return_pop_internal (popc));
11414 DONE;
11415 }
11416 })
11417
11418 (define_insn "return_internal"
11419 [(return)]
11420 "reload_completed"
11421 "ret"
11422 [(set_attr "length" "1")
11423 (set_attr "atom_unit" "jeu")
11424 (set_attr "length_immediate" "0")
11425 (set_attr "modrm" "0")])
11426
11427 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11428 ;; instruction Athlon and K8 have.
11429
11430 (define_insn "return_internal_long"
11431 [(return)
11432 (unspec [(const_int 0)] UNSPEC_REP)]
11433 "reload_completed"
11434 "rep\;ret"
11435 [(set_attr "length" "2")
11436 (set_attr "atom_unit" "jeu")
11437 (set_attr "length_immediate" "0")
11438 (set_attr "prefix_rep" "1")
11439 (set_attr "modrm" "0")])
11440
11441 (define_insn "return_pop_internal"
11442 [(return)
11443 (use (match_operand:SI 0 "const_int_operand" ""))]
11444 "reload_completed"
11445 "ret\t%0"
11446 [(set_attr "length" "3")
11447 (set_attr "atom_unit" "jeu")
11448 (set_attr "length_immediate" "2")
11449 (set_attr "modrm" "0")])
11450
11451 (define_insn "return_indirect_internal"
11452 [(return)
11453 (use (match_operand:SI 0 "register_operand" "r"))]
11454 "reload_completed"
11455 "jmp\t%A0"
11456 [(set_attr "type" "ibr")
11457 (set_attr "length_immediate" "0")])
11458
11459 (define_insn "nop"
11460 [(const_int 0)]
11461 ""
11462 "nop"
11463 [(set_attr "length" "1")
11464 (set_attr "length_immediate" "0")
11465 (set_attr "modrm" "0")])
11466
11467 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11468 (define_insn "nops"
11469 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11470 UNSPECV_NOPS)]
11471 "reload_completed"
11472 {
11473 int num = INTVAL (operands[0]);
11474
11475 gcc_assert (num >= 1 && num <= 8);
11476
11477 while (num--)
11478 fputs ("\tnop\n", asm_out_file);
11479
11480 return "";
11481 }
11482 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11483 (set_attr "length_immediate" "0")
11484 (set_attr "modrm" "0")])
11485
11486 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11487 ;; branch prediction penalty for the third jump in a 16-byte
11488 ;; block on K8.
11489
11490 (define_insn "pad"
11491 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11492 ""
11493 {
11494 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11495 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11496 #else
11497 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11498 The align insn is used to avoid 3 jump instructions in the row to improve
11499 branch prediction and the benefits hardly outweigh the cost of extra 8
11500 nops on the average inserted by full alignment pseudo operation. */
11501 #endif
11502 return "";
11503 }
11504 [(set_attr "length" "16")])
11505
11506 (define_expand "prologue"
11507 [(const_int 0)]
11508 ""
11509 "ix86_expand_prologue (); DONE;")
11510
11511 (define_insn "set_got"
11512 [(set (match_operand:SI 0 "register_operand" "=r")
11513 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11514 (clobber (reg:CC FLAGS_REG))]
11515 "!TARGET_64BIT"
11516 "* return output_set_got (operands[0], NULL_RTX);"
11517 [(set_attr "type" "multi")
11518 (set_attr "length" "12")])
11519
11520 (define_insn "set_got_labelled"
11521 [(set (match_operand:SI 0 "register_operand" "=r")
11522 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11523 UNSPEC_SET_GOT))
11524 (clobber (reg:CC FLAGS_REG))]
11525 "!TARGET_64BIT"
11526 "* return output_set_got (operands[0], operands[1]);"
11527 [(set_attr "type" "multi")
11528 (set_attr "length" "12")])
11529
11530 (define_insn "set_got_rex64"
11531 [(set (match_operand:DI 0 "register_operand" "=r")
11532 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11533 "TARGET_64BIT"
11534 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11535 [(set_attr "type" "lea")
11536 (set_attr "length_address" "4")
11537 (set_attr "mode" "DI")])
11538
11539 (define_insn "set_rip_rex64"
11540 [(set (match_operand:DI 0 "register_operand" "=r")
11541 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11542 "TARGET_64BIT"
11543 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11544 [(set_attr "type" "lea")
11545 (set_attr "length_address" "4")
11546 (set_attr "mode" "DI")])
11547
11548 (define_insn "set_got_offset_rex64"
11549 [(set (match_operand:DI 0 "register_operand" "=r")
11550 (unspec:DI
11551 [(label_ref (match_operand 1 "" ""))]
11552 UNSPEC_SET_GOT_OFFSET))]
11553 "TARGET_64BIT"
11554 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11555 [(set_attr "type" "imov")
11556 (set_attr "length_immediate" "0")
11557 (set_attr "length_address" "8")
11558 (set_attr "mode" "DI")])
11559
11560 (define_expand "epilogue"
11561 [(const_int 0)]
11562 ""
11563 "ix86_expand_epilogue (1); DONE;")
11564
11565 (define_expand "sibcall_epilogue"
11566 [(const_int 0)]
11567 ""
11568 "ix86_expand_epilogue (0); DONE;")
11569
11570 (define_expand "eh_return"
11571 [(use (match_operand 0 "register_operand" ""))]
11572 ""
11573 {
11574 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11575
11576 /* Tricky bit: we write the address of the handler to which we will
11577 be returning into someone else's stack frame, one word below the
11578 stack address we wish to restore. */
11579 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11580 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11581 tmp = gen_rtx_MEM (Pmode, tmp);
11582 emit_move_insn (tmp, ra);
11583
11584 emit_jump_insn (gen_eh_return_internal ());
11585 emit_barrier ();
11586 DONE;
11587 })
11588
11589 (define_insn_and_split "eh_return_internal"
11590 [(eh_return)]
11591 ""
11592 "#"
11593 "epilogue_completed"
11594 [(const_int 0)]
11595 "ix86_expand_epilogue (2); DONE;")
11596
11597 (define_insn "leave"
11598 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11599 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11600 (clobber (mem:BLK (scratch)))]
11601 "!TARGET_64BIT"
11602 "leave"
11603 [(set_attr "type" "leave")])
11604
11605 (define_insn "leave_rex64"
11606 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11607 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11608 (clobber (mem:BLK (scratch)))]
11609 "TARGET_64BIT"
11610 "leave"
11611 [(set_attr "type" "leave")])
11612 \f
11613 ;; Handle -fsplit-stack.
11614
11615 (define_expand "split_stack_prologue"
11616 [(const_int 0)]
11617 ""
11618 {
11619 ix86_expand_split_stack_prologue ();
11620 DONE;
11621 })
11622
11623 ;; In order to support the call/return predictor, we use a return
11624 ;; instruction which the middle-end doesn't see.
11625 (define_insn "split_stack_return"
11626 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11627 UNSPEC_STACK_CHECK)]
11628 ""
11629 {
11630 if (operands[0] == const0_rtx)
11631 return "ret";
11632 else
11633 return "ret\t%0";
11634 }
11635 [(set_attr "atom_unit" "jeu")
11636 (set_attr "modrm" "0")
11637 (set (attr "length")
11638 (if_then_else (match_operand:SI 0 "const0_operand" "")
11639 (const_int 1)
11640 (const_int 3)))
11641 (set (attr "length_immediate")
11642 (if_then_else (match_operand:SI 0 "const0_operand" "")
11643 (const_int 0)
11644 (const_int 2)))])
11645
11646 ;; If there are operand 0 bytes available on the stack, jump to
11647 ;; operand 1.
11648
11649 (define_expand "split_stack_space_check"
11650 [(set (pc) (if_then_else
11651 (ltu (minus (reg SP_REG)
11652 (match_operand 0 "register_operand" ""))
11653 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11654 (label_ref (match_operand 1 "" ""))
11655 (pc)))]
11656 ""
11657 {
11658 rtx reg, size, limit;
11659
11660 reg = gen_reg_rtx (Pmode);
11661 size = force_reg (Pmode, operands[0]);
11662 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11663 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11664 UNSPEC_STACK_CHECK);
11665 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11666 ix86_expand_branch (GEU, reg, limit, operands[1]);
11667
11668 DONE;
11669 })
11670 \f
11671 ;; Bit manipulation instructions.
11672
11673 (define_expand "ffs<mode>2"
11674 [(set (match_dup 2) (const_int -1))
11675 (parallel [(set (reg:CCZ FLAGS_REG)
11676 (compare:CCZ
11677 (match_operand:SWI48 1 "nonimmediate_operand" "")
11678 (const_int 0)))
11679 (set (match_operand:SWI48 0 "register_operand" "")
11680 (ctz:SWI48 (match_dup 1)))])
11681 (set (match_dup 0) (if_then_else:SWI48
11682 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11683 (match_dup 2)
11684 (match_dup 0)))
11685 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11686 (clobber (reg:CC FLAGS_REG))])]
11687 ""
11688 {
11689 if (<MODE>mode == SImode && !TARGET_CMOVE)
11690 {
11691 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11692 DONE;
11693 }
11694 operands[2] = gen_reg_rtx (<MODE>mode);
11695 })
11696
11697 (define_insn_and_split "ffssi2_no_cmove"
11698 [(set (match_operand:SI 0 "register_operand" "=r")
11699 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11700 (clobber (match_scratch:SI 2 "=&q"))
11701 (clobber (reg:CC FLAGS_REG))]
11702 "!TARGET_CMOVE"
11703 "#"
11704 "&& reload_completed"
11705 [(parallel [(set (reg:CCZ FLAGS_REG)
11706 (compare:CCZ (match_dup 1) (const_int 0)))
11707 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11708 (set (strict_low_part (match_dup 3))
11709 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11710 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11711 (clobber (reg:CC FLAGS_REG))])
11712 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11713 (clobber (reg:CC FLAGS_REG))])
11714 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11715 (clobber (reg:CC FLAGS_REG))])]
11716 {
11717 operands[3] = gen_lowpart (QImode, operands[2]);
11718 ix86_expand_clear (operands[2]);
11719 })
11720
11721 (define_insn "*ffs<mode>_1"
11722 [(set (reg:CCZ FLAGS_REG)
11723 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11724 (const_int 0)))
11725 (set (match_operand:SWI48 0 "register_operand" "=r")
11726 (ctz:SWI48 (match_dup 1)))]
11727 ""
11728 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11729 [(set_attr "type" "alu1")
11730 (set_attr "prefix_0f" "1")
11731 (set_attr "mode" "<MODE>")])
11732
11733 (define_insn "ctz<mode>2"
11734 [(set (match_operand:SWI48 0 "register_operand" "=r")
11735 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11736 (clobber (reg:CC FLAGS_REG))]
11737 ""
11738 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11739 [(set_attr "type" "alu1")
11740 (set_attr "prefix_0f" "1")
11741 (set_attr "mode" "<MODE>")])
11742
11743 (define_expand "clz<mode>2"
11744 [(parallel
11745 [(set (match_operand:SWI248 0 "register_operand" "")
11746 (minus:SWI248
11747 (match_dup 2)
11748 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11749 (clobber (reg:CC FLAGS_REG))])
11750 (parallel
11751 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11752 (clobber (reg:CC FLAGS_REG))])]
11753 ""
11754 {
11755 if (TARGET_ABM)
11756 {
11757 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11758 DONE;
11759 }
11760 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11761 })
11762
11763 (define_insn "clz<mode>2_abm"
11764 [(set (match_operand:SWI248 0 "register_operand" "=r")
11765 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11766 (clobber (reg:CC FLAGS_REG))]
11767 "TARGET_ABM"
11768 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11769 [(set_attr "prefix_rep" "1")
11770 (set_attr "type" "bitmanip")
11771 (set_attr "mode" "<MODE>")])
11772
11773 (define_insn "bsr_rex64"
11774 [(set (match_operand:DI 0 "register_operand" "=r")
11775 (minus:DI (const_int 63)
11776 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11777 (clobber (reg:CC FLAGS_REG))]
11778 "TARGET_64BIT"
11779 "bsr{q}\t{%1, %0|%0, %1}"
11780 [(set_attr "type" "alu1")
11781 (set_attr "prefix_0f" "1")
11782 (set_attr "mode" "DI")])
11783
11784 (define_insn "bsr"
11785 [(set (match_operand:SI 0 "register_operand" "=r")
11786 (minus:SI (const_int 31)
11787 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11788 (clobber (reg:CC FLAGS_REG))]
11789 ""
11790 "bsr{l}\t{%1, %0|%0, %1}"
11791 [(set_attr "type" "alu1")
11792 (set_attr "prefix_0f" "1")
11793 (set_attr "mode" "SI")])
11794
11795 (define_insn "*bsrhi"
11796 [(set (match_operand:HI 0 "register_operand" "=r")
11797 (minus:HI (const_int 15)
11798 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11799 (clobber (reg:CC FLAGS_REG))]
11800 ""
11801 "bsr{w}\t{%1, %0|%0, %1}"
11802 [(set_attr "type" "alu1")
11803 (set_attr "prefix_0f" "1")
11804 (set_attr "mode" "HI")])
11805
11806 (define_insn "popcount<mode>2"
11807 [(set (match_operand:SWI248 0 "register_operand" "=r")
11808 (popcount:SWI248
11809 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11810 (clobber (reg:CC FLAGS_REG))]
11811 "TARGET_POPCNT"
11812 {
11813 #if TARGET_MACHO
11814 return "popcnt\t{%1, %0|%0, %1}";
11815 #else
11816 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11817 #endif
11818 }
11819 [(set_attr "prefix_rep" "1")
11820 (set_attr "type" "bitmanip")
11821 (set_attr "mode" "<MODE>")])
11822
11823 (define_insn "*popcount<mode>2_cmp"
11824 [(set (reg FLAGS_REG)
11825 (compare
11826 (popcount:SWI248
11827 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11828 (const_int 0)))
11829 (set (match_operand:SWI248 0 "register_operand" "=r")
11830 (popcount:SWI248 (match_dup 1)))]
11831 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11832 {
11833 #if TARGET_MACHO
11834 return "popcnt\t{%1, %0|%0, %1}";
11835 #else
11836 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11837 #endif
11838 }
11839 [(set_attr "prefix_rep" "1")
11840 (set_attr "type" "bitmanip")
11841 (set_attr "mode" "<MODE>")])
11842
11843 (define_insn "*popcountsi2_cmp_zext"
11844 [(set (reg FLAGS_REG)
11845 (compare
11846 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11847 (const_int 0)))
11848 (set (match_operand:DI 0 "register_operand" "=r")
11849 (zero_extend:DI(popcount:SI (match_dup 1))))]
11850 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11851 {
11852 #if TARGET_MACHO
11853 return "popcnt\t{%1, %0|%0, %1}";
11854 #else
11855 return "popcnt{l}\t{%1, %0|%0, %1}";
11856 #endif
11857 }
11858 [(set_attr "prefix_rep" "1")
11859 (set_attr "type" "bitmanip")
11860 (set_attr "mode" "SI")])
11861
11862 (define_expand "bswap<mode>2"
11863 [(set (match_operand:SWI48 0 "register_operand" "")
11864 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11865 ""
11866 {
11867 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11868 {
11869 rtx x = operands[0];
11870
11871 emit_move_insn (x, operands[1]);
11872 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11873 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11874 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11875 DONE;
11876 }
11877 })
11878
11879 (define_insn "*bswap<mode>2_movbe"
11880 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11881 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11882 "TARGET_MOVBE
11883 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11884 "@
11885 bswap\t%0
11886 movbe\t{%1, %0|%0, %1}
11887 movbe\t{%1, %0|%0, %1}"
11888 [(set_attr "type" "bitmanip,imov,imov")
11889 (set_attr "modrm" "0,1,1")
11890 (set_attr "prefix_0f" "*,1,1")
11891 (set_attr "prefix_extra" "*,1,1")
11892 (set_attr "mode" "<MODE>")])
11893
11894 (define_insn "*bswap<mode>2_1"
11895 [(set (match_operand:SWI48 0 "register_operand" "=r")
11896 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11897 "TARGET_BSWAP"
11898 "bswap\t%0"
11899 [(set_attr "type" "bitmanip")
11900 (set_attr "modrm" "0")
11901 (set_attr "mode" "<MODE>")])
11902
11903 (define_insn "*bswaphi_lowpart_1"
11904 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11905 (bswap:HI (match_dup 0)))
11906 (clobber (reg:CC FLAGS_REG))]
11907 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11908 "@
11909 xchg{b}\t{%h0, %b0|%b0, %h0}
11910 rol{w}\t{$8, %0|%0, 8}"
11911 [(set_attr "length" "2,4")
11912 (set_attr "mode" "QI,HI")])
11913
11914 (define_insn "bswaphi_lowpart"
11915 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11916 (bswap:HI (match_dup 0)))
11917 (clobber (reg:CC FLAGS_REG))]
11918 ""
11919 "rol{w}\t{$8, %0|%0, 8}"
11920 [(set_attr "length" "4")
11921 (set_attr "mode" "HI")])
11922
11923 (define_expand "paritydi2"
11924 [(set (match_operand:DI 0 "register_operand" "")
11925 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11926 "! TARGET_POPCNT"
11927 {
11928 rtx scratch = gen_reg_rtx (QImode);
11929 rtx cond;
11930
11931 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11932 NULL_RTX, operands[1]));
11933
11934 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11935 gen_rtx_REG (CCmode, FLAGS_REG),
11936 const0_rtx);
11937 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11938
11939 if (TARGET_64BIT)
11940 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11941 else
11942 {
11943 rtx tmp = gen_reg_rtx (SImode);
11944
11945 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11946 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11947 }
11948 DONE;
11949 })
11950
11951 (define_expand "paritysi2"
11952 [(set (match_operand:SI 0 "register_operand" "")
11953 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11954 "! TARGET_POPCNT"
11955 {
11956 rtx scratch = gen_reg_rtx (QImode);
11957 rtx cond;
11958
11959 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11960
11961 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11962 gen_rtx_REG (CCmode, FLAGS_REG),
11963 const0_rtx);
11964 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11965
11966 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11967 DONE;
11968 })
11969
11970 (define_insn_and_split "paritydi2_cmp"
11971 [(set (reg:CC FLAGS_REG)
11972 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11973 UNSPEC_PARITY))
11974 (clobber (match_scratch:DI 0 "=r"))
11975 (clobber (match_scratch:SI 1 "=&r"))
11976 (clobber (match_scratch:HI 2 "=Q"))]
11977 "! TARGET_POPCNT"
11978 "#"
11979 "&& reload_completed"
11980 [(parallel
11981 [(set (match_dup 1)
11982 (xor:SI (match_dup 1) (match_dup 4)))
11983 (clobber (reg:CC FLAGS_REG))])
11984 (parallel
11985 [(set (reg:CC FLAGS_REG)
11986 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11987 (clobber (match_dup 1))
11988 (clobber (match_dup 2))])]
11989 {
11990 operands[4] = gen_lowpart (SImode, operands[3]);
11991
11992 if (TARGET_64BIT)
11993 {
11994 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11995 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11996 }
11997 else
11998 operands[1] = gen_highpart (SImode, operands[3]);
11999 })
12000
12001 (define_insn_and_split "paritysi2_cmp"
12002 [(set (reg:CC FLAGS_REG)
12003 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12004 UNSPEC_PARITY))
12005 (clobber (match_scratch:SI 0 "=r"))
12006 (clobber (match_scratch:HI 1 "=&Q"))]
12007 "! TARGET_POPCNT"
12008 "#"
12009 "&& reload_completed"
12010 [(parallel
12011 [(set (match_dup 1)
12012 (xor:HI (match_dup 1) (match_dup 3)))
12013 (clobber (reg:CC FLAGS_REG))])
12014 (parallel
12015 [(set (reg:CC FLAGS_REG)
12016 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12017 (clobber (match_dup 1))])]
12018 {
12019 operands[3] = gen_lowpart (HImode, operands[2]);
12020
12021 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12022 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12023 })
12024
12025 (define_insn "*parityhi2_cmp"
12026 [(set (reg:CC FLAGS_REG)
12027 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12028 UNSPEC_PARITY))
12029 (clobber (match_scratch:HI 0 "=Q"))]
12030 "! TARGET_POPCNT"
12031 "xor{b}\t{%h0, %b0|%b0, %h0}"
12032 [(set_attr "length" "2")
12033 (set_attr "mode" "HI")])
12034 \f
12035 ;; Thread-local storage patterns for ELF.
12036 ;;
12037 ;; Note that these code sequences must appear exactly as shown
12038 ;; in order to allow linker relaxation.
12039
12040 (define_insn "*tls_global_dynamic_32_gnu"
12041 [(set (match_operand:SI 0 "register_operand" "=a")
12042 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12043 (match_operand:SI 2 "tls_symbolic_operand" "")
12044 (match_operand:SI 3 "call_insn_operand" "")]
12045 UNSPEC_TLS_GD))
12046 (clobber (match_scratch:SI 4 "=d"))
12047 (clobber (match_scratch:SI 5 "=c"))
12048 (clobber (reg:CC FLAGS_REG))]
12049 "!TARGET_64BIT && TARGET_GNU_TLS"
12050 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12051 [(set_attr "type" "multi")
12052 (set_attr "length" "12")])
12053
12054 (define_expand "tls_global_dynamic_32"
12055 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12056 (unspec:SI
12057 [(match_dup 2)
12058 (match_operand:SI 1 "tls_symbolic_operand" "")
12059 (match_dup 3)]
12060 UNSPEC_TLS_GD))
12061 (clobber (match_scratch:SI 4 ""))
12062 (clobber (match_scratch:SI 5 ""))
12063 (clobber (reg:CC FLAGS_REG))])]
12064 ""
12065 {
12066 if (flag_pic)
12067 operands[2] = pic_offset_table_rtx;
12068 else
12069 {
12070 operands[2] = gen_reg_rtx (Pmode);
12071 emit_insn (gen_set_got (operands[2]));
12072 }
12073 if (TARGET_GNU2_TLS)
12074 {
12075 emit_insn (gen_tls_dynamic_gnu2_32
12076 (operands[0], operands[1], operands[2]));
12077 DONE;
12078 }
12079 operands[3] = ix86_tls_get_addr ();
12080 })
12081
12082 (define_insn "*tls_global_dynamic_64"
12083 [(set (match_operand:DI 0 "register_operand" "=a")
12084 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12085 (match_operand:DI 3 "" "")))
12086 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12087 UNSPEC_TLS_GD)]
12088 "TARGET_64BIT"
12089 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12090 [(set_attr "type" "multi")
12091 (set_attr "length" "16")])
12092
12093 (define_expand "tls_global_dynamic_64"
12094 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12095 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12096 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12097 UNSPEC_TLS_GD)])]
12098 ""
12099 {
12100 if (TARGET_GNU2_TLS)
12101 {
12102 emit_insn (gen_tls_dynamic_gnu2_64
12103 (operands[0], operands[1]));
12104 DONE;
12105 }
12106 operands[2] = ix86_tls_get_addr ();
12107 })
12108
12109 (define_insn "*tls_local_dynamic_base_32_gnu"
12110 [(set (match_operand:SI 0 "register_operand" "=a")
12111 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12112 (match_operand:SI 2 "call_insn_operand" "")]
12113 UNSPEC_TLS_LD_BASE))
12114 (clobber (match_scratch:SI 3 "=d"))
12115 (clobber (match_scratch:SI 4 "=c"))
12116 (clobber (reg:CC FLAGS_REG))]
12117 "!TARGET_64BIT && TARGET_GNU_TLS"
12118 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12119 [(set_attr "type" "multi")
12120 (set_attr "length" "11")])
12121
12122 (define_expand "tls_local_dynamic_base_32"
12123 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12124 (unspec:SI [(match_dup 1) (match_dup 2)]
12125 UNSPEC_TLS_LD_BASE))
12126 (clobber (match_scratch:SI 3 ""))
12127 (clobber (match_scratch:SI 4 ""))
12128 (clobber (reg:CC FLAGS_REG))])]
12129 ""
12130 {
12131 if (flag_pic)
12132 operands[1] = pic_offset_table_rtx;
12133 else
12134 {
12135 operands[1] = gen_reg_rtx (Pmode);
12136 emit_insn (gen_set_got (operands[1]));
12137 }
12138 if (TARGET_GNU2_TLS)
12139 {
12140 emit_insn (gen_tls_dynamic_gnu2_32
12141 (operands[0], ix86_tls_module_base (), operands[1]));
12142 DONE;
12143 }
12144 operands[2] = ix86_tls_get_addr ();
12145 })
12146
12147 (define_insn "*tls_local_dynamic_base_64"
12148 [(set (match_operand:DI 0 "register_operand" "=a")
12149 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12150 (match_operand:DI 2 "" "")))
12151 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12152 "TARGET_64BIT"
12153 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12154 [(set_attr "type" "multi")
12155 (set_attr "length" "12")])
12156
12157 (define_expand "tls_local_dynamic_base_64"
12158 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12159 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12160 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12161 ""
12162 {
12163 if (TARGET_GNU2_TLS)
12164 {
12165 emit_insn (gen_tls_dynamic_gnu2_64
12166 (operands[0], ix86_tls_module_base ()));
12167 DONE;
12168 }
12169 operands[1] = ix86_tls_get_addr ();
12170 })
12171
12172 ;; Local dynamic of a single variable is a lose. Show combine how
12173 ;; to convert that back to global dynamic.
12174
12175 (define_insn_and_split "*tls_local_dynamic_32_once"
12176 [(set (match_operand:SI 0 "register_operand" "=a")
12177 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12178 (match_operand:SI 2 "call_insn_operand" "")]
12179 UNSPEC_TLS_LD_BASE)
12180 (const:SI (unspec:SI
12181 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12182 UNSPEC_DTPOFF))))
12183 (clobber (match_scratch:SI 4 "=d"))
12184 (clobber (match_scratch:SI 5 "=c"))
12185 (clobber (reg:CC FLAGS_REG))]
12186 ""
12187 "#"
12188 ""
12189 [(parallel [(set (match_dup 0)
12190 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12191 UNSPEC_TLS_GD))
12192 (clobber (match_dup 4))
12193 (clobber (match_dup 5))
12194 (clobber (reg:CC FLAGS_REG))])])
12195
12196 ;; Segment register for the thread base ptr load
12197 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12198
12199 ;; Load and add the thread base pointer from %gs:0.
12200 (define_insn "*load_tp_<mode>"
12201 [(set (match_operand:P 0 "register_operand" "=r")
12202 (unspec:P [(const_int 0)] UNSPEC_TP))]
12203 ""
12204 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12205 [(set_attr "type" "imov")
12206 (set_attr "modrm" "0")
12207 (set_attr "length" "7")
12208 (set_attr "memory" "load")
12209 (set_attr "imm_disp" "false")])
12210
12211 (define_insn "*add_tp_<mode>"
12212 [(set (match_operand:P 0 "register_operand" "=r")
12213 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12214 (match_operand:P 1 "register_operand" "0")))
12215 (clobber (reg:CC FLAGS_REG))]
12216 ""
12217 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12218 [(set_attr "type" "alu")
12219 (set_attr "modrm" "0")
12220 (set_attr "length" "7")
12221 (set_attr "memory" "load")
12222 (set_attr "imm_disp" "false")])
12223
12224 ;; GNU2 TLS patterns can be split.
12225
12226 (define_expand "tls_dynamic_gnu2_32"
12227 [(set (match_dup 3)
12228 (plus:SI (match_operand:SI 2 "register_operand" "")
12229 (const:SI
12230 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12231 UNSPEC_TLSDESC))))
12232 (parallel
12233 [(set (match_operand:SI 0 "register_operand" "")
12234 (unspec:SI [(match_dup 1) (match_dup 3)
12235 (match_dup 2) (reg:SI SP_REG)]
12236 UNSPEC_TLSDESC))
12237 (clobber (reg:CC FLAGS_REG))])]
12238 "!TARGET_64BIT && TARGET_GNU2_TLS"
12239 {
12240 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12241 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12242 })
12243
12244 (define_insn "*tls_dynamic_lea_32"
12245 [(set (match_operand:SI 0 "register_operand" "=r")
12246 (plus:SI (match_operand:SI 1 "register_operand" "b")
12247 (const:SI
12248 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12249 UNSPEC_TLSDESC))))]
12250 "!TARGET_64BIT && TARGET_GNU2_TLS"
12251 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12252 [(set_attr "type" "lea")
12253 (set_attr "mode" "SI")
12254 (set_attr "length" "6")
12255 (set_attr "length_address" "4")])
12256
12257 (define_insn "*tls_dynamic_call_32"
12258 [(set (match_operand:SI 0 "register_operand" "=a")
12259 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12260 (match_operand:SI 2 "register_operand" "0")
12261 ;; we have to make sure %ebx still points to the GOT
12262 (match_operand:SI 3 "register_operand" "b")
12263 (reg:SI SP_REG)]
12264 UNSPEC_TLSDESC))
12265 (clobber (reg:CC FLAGS_REG))]
12266 "!TARGET_64BIT && TARGET_GNU2_TLS"
12267 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12268 [(set_attr "type" "call")
12269 (set_attr "length" "2")
12270 (set_attr "length_address" "0")])
12271
12272 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12273 [(set (match_operand:SI 0 "register_operand" "=&a")
12274 (plus:SI
12275 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12276 (match_operand:SI 4 "" "")
12277 (match_operand:SI 2 "register_operand" "b")
12278 (reg:SI SP_REG)]
12279 UNSPEC_TLSDESC)
12280 (const:SI (unspec:SI
12281 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12282 UNSPEC_DTPOFF))))
12283 (clobber (reg:CC FLAGS_REG))]
12284 "!TARGET_64BIT && TARGET_GNU2_TLS"
12285 "#"
12286 ""
12287 [(set (match_dup 0) (match_dup 5))]
12288 {
12289 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12290 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12291 })
12292
12293 (define_expand "tls_dynamic_gnu2_64"
12294 [(set (match_dup 2)
12295 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12296 UNSPEC_TLSDESC))
12297 (parallel
12298 [(set (match_operand:DI 0 "register_operand" "")
12299 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12300 UNSPEC_TLSDESC))
12301 (clobber (reg:CC FLAGS_REG))])]
12302 "TARGET_64BIT && TARGET_GNU2_TLS"
12303 {
12304 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12305 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12306 })
12307
12308 (define_insn "*tls_dynamic_lea_64"
12309 [(set (match_operand:DI 0 "register_operand" "=r")
12310 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12311 UNSPEC_TLSDESC))]
12312 "TARGET_64BIT && TARGET_GNU2_TLS"
12313 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12314 [(set_attr "type" "lea")
12315 (set_attr "mode" "DI")
12316 (set_attr "length" "7")
12317 (set_attr "length_address" "4")])
12318
12319 (define_insn "*tls_dynamic_call_64"
12320 [(set (match_operand:DI 0 "register_operand" "=a")
12321 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12322 (match_operand:DI 2 "register_operand" "0")
12323 (reg:DI SP_REG)]
12324 UNSPEC_TLSDESC))
12325 (clobber (reg:CC FLAGS_REG))]
12326 "TARGET_64BIT && TARGET_GNU2_TLS"
12327 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12328 [(set_attr "type" "call")
12329 (set_attr "length" "2")
12330 (set_attr "length_address" "0")])
12331
12332 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12333 [(set (match_operand:DI 0 "register_operand" "=&a")
12334 (plus:DI
12335 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12336 (match_operand:DI 3 "" "")
12337 (reg:DI SP_REG)]
12338 UNSPEC_TLSDESC)
12339 (const:DI (unspec:DI
12340 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12341 UNSPEC_DTPOFF))))
12342 (clobber (reg:CC FLAGS_REG))]
12343 "TARGET_64BIT && TARGET_GNU2_TLS"
12344 "#"
12345 ""
12346 [(set (match_dup 0) (match_dup 4))]
12347 {
12348 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12349 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12350 })
12351 \f
12352 ;; These patterns match the binary 387 instructions for addM3, subM3,
12353 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12354 ;; SFmode. The first is the normal insn, the second the same insn but
12355 ;; with one operand a conversion, and the third the same insn but with
12356 ;; the other operand a conversion. The conversion may be SFmode or
12357 ;; SImode if the target mode DFmode, but only SImode if the target mode
12358 ;; is SFmode.
12359
12360 ;; Gcc is slightly more smart about handling normal two address instructions
12361 ;; so use special patterns for add and mull.
12362
12363 (define_insn "*fop_<mode>_comm_mixed_avx"
12364 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12365 (match_operator:MODEF 3 "binary_fp_operator"
12366 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12367 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12368 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12369 && COMMUTATIVE_ARITH_P (operands[3])
12370 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12371 "* return output_387_binary_op (insn, operands);"
12372 [(set (attr "type")
12373 (if_then_else (eq_attr "alternative" "1")
12374 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12375 (const_string "ssemul")
12376 (const_string "sseadd"))
12377 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12378 (const_string "fmul")
12379 (const_string "fop"))))
12380 (set_attr "prefix" "orig,maybe_vex")
12381 (set_attr "mode" "<MODE>")])
12382
12383 (define_insn "*fop_<mode>_comm_mixed"
12384 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12385 (match_operator:MODEF 3 "binary_fp_operator"
12386 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12387 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12388 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12389 && COMMUTATIVE_ARITH_P (operands[3])
12390 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12391 "* return output_387_binary_op (insn, operands);"
12392 [(set (attr "type")
12393 (if_then_else (eq_attr "alternative" "1")
12394 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12395 (const_string "ssemul")
12396 (const_string "sseadd"))
12397 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12398 (const_string "fmul")
12399 (const_string "fop"))))
12400 (set_attr "mode" "<MODE>")])
12401
12402 (define_insn "*fop_<mode>_comm_avx"
12403 [(set (match_operand:MODEF 0 "register_operand" "=x")
12404 (match_operator:MODEF 3 "binary_fp_operator"
12405 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12406 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12407 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12408 && COMMUTATIVE_ARITH_P (operands[3])
12409 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12410 "* return output_387_binary_op (insn, operands);"
12411 [(set (attr "type")
12412 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12413 (const_string "ssemul")
12414 (const_string "sseadd")))
12415 (set_attr "prefix" "vex")
12416 (set_attr "mode" "<MODE>")])
12417
12418 (define_insn "*fop_<mode>_comm_sse"
12419 [(set (match_operand:MODEF 0 "register_operand" "=x")
12420 (match_operator:MODEF 3 "binary_fp_operator"
12421 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12422 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12423 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12424 && COMMUTATIVE_ARITH_P (operands[3])
12425 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12426 "* return output_387_binary_op (insn, operands);"
12427 [(set (attr "type")
12428 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12429 (const_string "ssemul")
12430 (const_string "sseadd")))
12431 (set_attr "mode" "<MODE>")])
12432
12433 (define_insn "*fop_<mode>_comm_i387"
12434 [(set (match_operand:MODEF 0 "register_operand" "=f")
12435 (match_operator:MODEF 3 "binary_fp_operator"
12436 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12437 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12438 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12439 && COMMUTATIVE_ARITH_P (operands[3])
12440 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12441 "* return output_387_binary_op (insn, operands);"
12442 [(set (attr "type")
12443 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12444 (const_string "fmul")
12445 (const_string "fop")))
12446 (set_attr "mode" "<MODE>")])
12447
12448 (define_insn "*fop_<mode>_1_mixed_avx"
12449 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12450 (match_operator:MODEF 3 "binary_fp_operator"
12451 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12452 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12453 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12454 && !COMMUTATIVE_ARITH_P (operands[3])
12455 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12456 "* return output_387_binary_op (insn, operands);"
12457 [(set (attr "type")
12458 (cond [(and (eq_attr "alternative" "2")
12459 (match_operand:MODEF 3 "mult_operator" ""))
12460 (const_string "ssemul")
12461 (and (eq_attr "alternative" "2")
12462 (match_operand:MODEF 3 "div_operator" ""))
12463 (const_string "ssediv")
12464 (eq_attr "alternative" "2")
12465 (const_string "sseadd")
12466 (match_operand:MODEF 3 "mult_operator" "")
12467 (const_string "fmul")
12468 (match_operand:MODEF 3 "div_operator" "")
12469 (const_string "fdiv")
12470 ]
12471 (const_string "fop")))
12472 (set_attr "prefix" "orig,orig,maybe_vex")
12473 (set_attr "mode" "<MODE>")])
12474
12475 (define_insn "*fop_<mode>_1_mixed"
12476 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12477 (match_operator:MODEF 3 "binary_fp_operator"
12478 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12479 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12480 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12481 && !COMMUTATIVE_ARITH_P (operands[3])
12482 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12483 "* return output_387_binary_op (insn, operands);"
12484 [(set (attr "type")
12485 (cond [(and (eq_attr "alternative" "2")
12486 (match_operand:MODEF 3 "mult_operator" ""))
12487 (const_string "ssemul")
12488 (and (eq_attr "alternative" "2")
12489 (match_operand:MODEF 3 "div_operator" ""))
12490 (const_string "ssediv")
12491 (eq_attr "alternative" "2")
12492 (const_string "sseadd")
12493 (match_operand:MODEF 3 "mult_operator" "")
12494 (const_string "fmul")
12495 (match_operand:MODEF 3 "div_operator" "")
12496 (const_string "fdiv")
12497 ]
12498 (const_string "fop")))
12499 (set_attr "mode" "<MODE>")])
12500
12501 (define_insn "*rcpsf2_sse"
12502 [(set (match_operand:SF 0 "register_operand" "=x")
12503 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12504 UNSPEC_RCP))]
12505 "TARGET_SSE_MATH"
12506 "%vrcpss\t{%1, %d0|%d0, %1}"
12507 [(set_attr "type" "sse")
12508 (set_attr "atom_sse_attr" "rcp")
12509 (set_attr "prefix" "maybe_vex")
12510 (set_attr "mode" "SF")])
12511
12512 (define_insn "*fop_<mode>_1_avx"
12513 [(set (match_operand:MODEF 0 "register_operand" "=x")
12514 (match_operator:MODEF 3 "binary_fp_operator"
12515 [(match_operand:MODEF 1 "register_operand" "x")
12516 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12517 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12518 && !COMMUTATIVE_ARITH_P (operands[3])"
12519 "* return output_387_binary_op (insn, operands);"
12520 [(set (attr "type")
12521 (cond [(match_operand:MODEF 3 "mult_operator" "")
12522 (const_string "ssemul")
12523 (match_operand:MODEF 3 "div_operator" "")
12524 (const_string "ssediv")
12525 ]
12526 (const_string "sseadd")))
12527 (set_attr "prefix" "vex")
12528 (set_attr "mode" "<MODE>")])
12529
12530 (define_insn "*fop_<mode>_1_sse"
12531 [(set (match_operand:MODEF 0 "register_operand" "=x")
12532 (match_operator:MODEF 3 "binary_fp_operator"
12533 [(match_operand:MODEF 1 "register_operand" "0")
12534 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12535 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12536 && !COMMUTATIVE_ARITH_P (operands[3])"
12537 "* return output_387_binary_op (insn, operands);"
12538 [(set (attr "type")
12539 (cond [(match_operand:MODEF 3 "mult_operator" "")
12540 (const_string "ssemul")
12541 (match_operand:MODEF 3 "div_operator" "")
12542 (const_string "ssediv")
12543 ]
12544 (const_string "sseadd")))
12545 (set_attr "mode" "<MODE>")])
12546
12547 ;; This pattern is not fully shadowed by the pattern above.
12548 (define_insn "*fop_<mode>_1_i387"
12549 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12550 (match_operator:MODEF 3 "binary_fp_operator"
12551 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12552 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12553 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12554 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12555 && !COMMUTATIVE_ARITH_P (operands[3])
12556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12557 "* return output_387_binary_op (insn, operands);"
12558 [(set (attr "type")
12559 (cond [(match_operand:MODEF 3 "mult_operator" "")
12560 (const_string "fmul")
12561 (match_operand:MODEF 3 "div_operator" "")
12562 (const_string "fdiv")
12563 ]
12564 (const_string "fop")))
12565 (set_attr "mode" "<MODE>")])
12566
12567 ;; ??? Add SSE splitters for these!
12568 (define_insn "*fop_<MODEF:mode>_2_i387"
12569 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12570 (match_operator:MODEF 3 "binary_fp_operator"
12571 [(float:MODEF
12572 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12573 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12574 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12575 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12576 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12577 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12578 [(set (attr "type")
12579 (cond [(match_operand:MODEF 3 "mult_operator" "")
12580 (const_string "fmul")
12581 (match_operand:MODEF 3 "div_operator" "")
12582 (const_string "fdiv")
12583 ]
12584 (const_string "fop")))
12585 (set_attr "fp_int_src" "true")
12586 (set_attr "mode" "<X87MODEI12:MODE>")])
12587
12588 (define_insn "*fop_<MODEF:mode>_3_i387"
12589 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12590 (match_operator:MODEF 3 "binary_fp_operator"
12591 [(match_operand:MODEF 1 "register_operand" "0,0")
12592 (float:MODEF
12593 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12594 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12595 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12596 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12597 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12598 [(set (attr "type")
12599 (cond [(match_operand:MODEF 3 "mult_operator" "")
12600 (const_string "fmul")
12601 (match_operand:MODEF 3 "div_operator" "")
12602 (const_string "fdiv")
12603 ]
12604 (const_string "fop")))
12605 (set_attr "fp_int_src" "true")
12606 (set_attr "mode" "<MODE>")])
12607
12608 (define_insn "*fop_df_4_i387"
12609 [(set (match_operand:DF 0 "register_operand" "=f,f")
12610 (match_operator:DF 3 "binary_fp_operator"
12611 [(float_extend:DF
12612 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12613 (match_operand:DF 2 "register_operand" "0,f")]))]
12614 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12615 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12616 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12617 "* return output_387_binary_op (insn, operands);"
12618 [(set (attr "type")
12619 (cond [(match_operand:DF 3 "mult_operator" "")
12620 (const_string "fmul")
12621 (match_operand:DF 3 "div_operator" "")
12622 (const_string "fdiv")
12623 ]
12624 (const_string "fop")))
12625 (set_attr "mode" "SF")])
12626
12627 (define_insn "*fop_df_5_i387"
12628 [(set (match_operand:DF 0 "register_operand" "=f,f")
12629 (match_operator:DF 3 "binary_fp_operator"
12630 [(match_operand:DF 1 "register_operand" "0,f")
12631 (float_extend:DF
12632 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12633 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12634 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12635 "* return output_387_binary_op (insn, operands);"
12636 [(set (attr "type")
12637 (cond [(match_operand:DF 3 "mult_operator" "")
12638 (const_string "fmul")
12639 (match_operand:DF 3 "div_operator" "")
12640 (const_string "fdiv")
12641 ]
12642 (const_string "fop")))
12643 (set_attr "mode" "SF")])
12644
12645 (define_insn "*fop_df_6_i387"
12646 [(set (match_operand:DF 0 "register_operand" "=f,f")
12647 (match_operator:DF 3 "binary_fp_operator"
12648 [(float_extend:DF
12649 (match_operand:SF 1 "register_operand" "0,f"))
12650 (float_extend:DF
12651 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12652 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12653 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12654 "* return output_387_binary_op (insn, operands);"
12655 [(set (attr "type")
12656 (cond [(match_operand:DF 3 "mult_operator" "")
12657 (const_string "fmul")
12658 (match_operand:DF 3 "div_operator" "")
12659 (const_string "fdiv")
12660 ]
12661 (const_string "fop")))
12662 (set_attr "mode" "SF")])
12663
12664 (define_insn "*fop_xf_comm_i387"
12665 [(set (match_operand:XF 0 "register_operand" "=f")
12666 (match_operator:XF 3 "binary_fp_operator"
12667 [(match_operand:XF 1 "register_operand" "%0")
12668 (match_operand:XF 2 "register_operand" "f")]))]
12669 "TARGET_80387
12670 && COMMUTATIVE_ARITH_P (operands[3])"
12671 "* return output_387_binary_op (insn, operands);"
12672 [(set (attr "type")
12673 (if_then_else (match_operand:XF 3 "mult_operator" "")
12674 (const_string "fmul")
12675 (const_string "fop")))
12676 (set_attr "mode" "XF")])
12677
12678 (define_insn "*fop_xf_1_i387"
12679 [(set (match_operand:XF 0 "register_operand" "=f,f")
12680 (match_operator:XF 3 "binary_fp_operator"
12681 [(match_operand:XF 1 "register_operand" "0,f")
12682 (match_operand:XF 2 "register_operand" "f,0")]))]
12683 "TARGET_80387
12684 && !COMMUTATIVE_ARITH_P (operands[3])"
12685 "* return output_387_binary_op (insn, operands);"
12686 [(set (attr "type")
12687 (cond [(match_operand:XF 3 "mult_operator" "")
12688 (const_string "fmul")
12689 (match_operand:XF 3 "div_operator" "")
12690 (const_string "fdiv")
12691 ]
12692 (const_string "fop")))
12693 (set_attr "mode" "XF")])
12694
12695 (define_insn "*fop_xf_2_i387"
12696 [(set (match_operand:XF 0 "register_operand" "=f,f")
12697 (match_operator:XF 3 "binary_fp_operator"
12698 [(float:XF
12699 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12700 (match_operand:XF 2 "register_operand" "0,0")]))]
12701 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12702 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12703 [(set (attr "type")
12704 (cond [(match_operand:XF 3 "mult_operator" "")
12705 (const_string "fmul")
12706 (match_operand:XF 3 "div_operator" "")
12707 (const_string "fdiv")
12708 ]
12709 (const_string "fop")))
12710 (set_attr "fp_int_src" "true")
12711 (set_attr "mode" "<MODE>")])
12712
12713 (define_insn "*fop_xf_3_i387"
12714 [(set (match_operand:XF 0 "register_operand" "=f,f")
12715 (match_operator:XF 3 "binary_fp_operator"
12716 [(match_operand:XF 1 "register_operand" "0,0")
12717 (float:XF
12718 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12719 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12720 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12721 [(set (attr "type")
12722 (cond [(match_operand:XF 3 "mult_operator" "")
12723 (const_string "fmul")
12724 (match_operand:XF 3 "div_operator" "")
12725 (const_string "fdiv")
12726 ]
12727 (const_string "fop")))
12728 (set_attr "fp_int_src" "true")
12729 (set_attr "mode" "<MODE>")])
12730
12731 (define_insn "*fop_xf_4_i387"
12732 [(set (match_operand:XF 0 "register_operand" "=f,f")
12733 (match_operator:XF 3 "binary_fp_operator"
12734 [(float_extend:XF
12735 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12736 (match_operand:XF 2 "register_operand" "0,f")]))]
12737 "TARGET_80387"
12738 "* return output_387_binary_op (insn, operands);"
12739 [(set (attr "type")
12740 (cond [(match_operand:XF 3 "mult_operator" "")
12741 (const_string "fmul")
12742 (match_operand:XF 3 "div_operator" "")
12743 (const_string "fdiv")
12744 ]
12745 (const_string "fop")))
12746 (set_attr "mode" "<MODE>")])
12747
12748 (define_insn "*fop_xf_5_i387"
12749 [(set (match_operand:XF 0 "register_operand" "=f,f")
12750 (match_operator:XF 3 "binary_fp_operator"
12751 [(match_operand:XF 1 "register_operand" "0,f")
12752 (float_extend:XF
12753 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12754 "TARGET_80387"
12755 "* return output_387_binary_op (insn, operands);"
12756 [(set (attr "type")
12757 (cond [(match_operand:XF 3 "mult_operator" "")
12758 (const_string "fmul")
12759 (match_operand:XF 3 "div_operator" "")
12760 (const_string "fdiv")
12761 ]
12762 (const_string "fop")))
12763 (set_attr "mode" "<MODE>")])
12764
12765 (define_insn "*fop_xf_6_i387"
12766 [(set (match_operand:XF 0 "register_operand" "=f,f")
12767 (match_operator:XF 3 "binary_fp_operator"
12768 [(float_extend:XF
12769 (match_operand:MODEF 1 "register_operand" "0,f"))
12770 (float_extend:XF
12771 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12772 "TARGET_80387"
12773 "* return output_387_binary_op (insn, operands);"
12774 [(set (attr "type")
12775 (cond [(match_operand:XF 3 "mult_operator" "")
12776 (const_string "fmul")
12777 (match_operand:XF 3 "div_operator" "")
12778 (const_string "fdiv")
12779 ]
12780 (const_string "fop")))
12781 (set_attr "mode" "<MODE>")])
12782
12783 (define_split
12784 [(set (match_operand 0 "register_operand" "")
12785 (match_operator 3 "binary_fp_operator"
12786 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12787 (match_operand 2 "register_operand" "")]))]
12788 "reload_completed
12789 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12790 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12791 [(const_int 0)]
12792 {
12793 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12794 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12795 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12796 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12797 GET_MODE (operands[3]),
12798 operands[4],
12799 operands[2])));
12800 ix86_free_from_memory (GET_MODE (operands[1]));
12801 DONE;
12802 })
12803
12804 (define_split
12805 [(set (match_operand 0 "register_operand" "")
12806 (match_operator 3 "binary_fp_operator"
12807 [(match_operand 1 "register_operand" "")
12808 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12809 "reload_completed
12810 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12811 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12812 [(const_int 0)]
12813 {
12814 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12815 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12816 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12817 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12818 GET_MODE (operands[3]),
12819 operands[1],
12820 operands[4])));
12821 ix86_free_from_memory (GET_MODE (operands[2]));
12822 DONE;
12823 })
12824 \f
12825 ;; FPU special functions.
12826
12827 ;; This pattern implements a no-op XFmode truncation for
12828 ;; all fancy i386 XFmode math functions.
12829
12830 (define_insn "truncxf<mode>2_i387_noop_unspec"
12831 [(set (match_operand:MODEF 0 "register_operand" "=f")
12832 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12833 UNSPEC_TRUNC_NOOP))]
12834 "TARGET_USE_FANCY_MATH_387"
12835 "* return output_387_reg_move (insn, operands);"
12836 [(set_attr "type" "fmov")
12837 (set_attr "mode" "<MODE>")])
12838
12839 (define_insn "sqrtxf2"
12840 [(set (match_operand:XF 0 "register_operand" "=f")
12841 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12842 "TARGET_USE_FANCY_MATH_387"
12843 "fsqrt"
12844 [(set_attr "type" "fpspc")
12845 (set_attr "mode" "XF")
12846 (set_attr "athlon_decode" "direct")
12847 (set_attr "amdfam10_decode" "direct")])
12848
12849 (define_insn "sqrt_extend<mode>xf2_i387"
12850 [(set (match_operand:XF 0 "register_operand" "=f")
12851 (sqrt:XF
12852 (float_extend:XF
12853 (match_operand:MODEF 1 "register_operand" "0"))))]
12854 "TARGET_USE_FANCY_MATH_387"
12855 "fsqrt"
12856 [(set_attr "type" "fpspc")
12857 (set_attr "mode" "XF")
12858 (set_attr "athlon_decode" "direct")
12859 (set_attr "amdfam10_decode" "direct")])
12860
12861 (define_insn "*rsqrtsf2_sse"
12862 [(set (match_operand:SF 0 "register_operand" "=x")
12863 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12864 UNSPEC_RSQRT))]
12865 "TARGET_SSE_MATH"
12866 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12867 [(set_attr "type" "sse")
12868 (set_attr "atom_sse_attr" "rcp")
12869 (set_attr "prefix" "maybe_vex")
12870 (set_attr "mode" "SF")])
12871
12872 (define_expand "rsqrtsf2"
12873 [(set (match_operand:SF 0 "register_operand" "")
12874 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12875 UNSPEC_RSQRT))]
12876 "TARGET_SSE_MATH"
12877 {
12878 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12879 DONE;
12880 })
12881
12882 (define_insn "*sqrt<mode>2_sse"
12883 [(set (match_operand:MODEF 0 "register_operand" "=x")
12884 (sqrt:MODEF
12885 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12886 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12887 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12888 [(set_attr "type" "sse")
12889 (set_attr "atom_sse_attr" "sqrt")
12890 (set_attr "prefix" "maybe_vex")
12891 (set_attr "mode" "<MODE>")
12892 (set_attr "athlon_decode" "*")
12893 (set_attr "amdfam10_decode" "*")])
12894
12895 (define_expand "sqrt<mode>2"
12896 [(set (match_operand:MODEF 0 "register_operand" "")
12897 (sqrt:MODEF
12898 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12899 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12900 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12901 {
12902 if (<MODE>mode == SFmode
12903 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12904 && flag_finite_math_only && !flag_trapping_math
12905 && flag_unsafe_math_optimizations)
12906 {
12907 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12908 DONE;
12909 }
12910
12911 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12912 {
12913 rtx op0 = gen_reg_rtx (XFmode);
12914 rtx op1 = force_reg (<MODE>mode, operands[1]);
12915
12916 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12917 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12918 DONE;
12919 }
12920 })
12921
12922 (define_insn "fpremxf4_i387"
12923 [(set (match_operand:XF 0 "register_operand" "=f")
12924 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12925 (match_operand:XF 3 "register_operand" "1")]
12926 UNSPEC_FPREM_F))
12927 (set (match_operand:XF 1 "register_operand" "=u")
12928 (unspec:XF [(match_dup 2) (match_dup 3)]
12929 UNSPEC_FPREM_U))
12930 (set (reg:CCFP FPSR_REG)
12931 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12932 UNSPEC_C2_FLAG))]
12933 "TARGET_USE_FANCY_MATH_387"
12934 "fprem"
12935 [(set_attr "type" "fpspc")
12936 (set_attr "mode" "XF")])
12937
12938 (define_expand "fmodxf3"
12939 [(use (match_operand:XF 0 "register_operand" ""))
12940 (use (match_operand:XF 1 "general_operand" ""))
12941 (use (match_operand:XF 2 "general_operand" ""))]
12942 "TARGET_USE_FANCY_MATH_387"
12943 {
12944 rtx label = gen_label_rtx ();
12945
12946 rtx op1 = gen_reg_rtx (XFmode);
12947 rtx op2 = gen_reg_rtx (XFmode);
12948
12949 emit_move_insn (op2, operands[2]);
12950 emit_move_insn (op1, operands[1]);
12951
12952 emit_label (label);
12953 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12954 ix86_emit_fp_unordered_jump (label);
12955 LABEL_NUSES (label) = 1;
12956
12957 emit_move_insn (operands[0], op1);
12958 DONE;
12959 })
12960
12961 (define_expand "fmod<mode>3"
12962 [(use (match_operand:MODEF 0 "register_operand" ""))
12963 (use (match_operand:MODEF 1 "general_operand" ""))
12964 (use (match_operand:MODEF 2 "general_operand" ""))]
12965 "TARGET_USE_FANCY_MATH_387"
12966 {
12967 rtx (*gen_truncxf) (rtx, rtx);
12968
12969 rtx label = gen_label_rtx ();
12970
12971 rtx op1 = gen_reg_rtx (XFmode);
12972 rtx op2 = gen_reg_rtx (XFmode);
12973
12974 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12975 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12976
12977 emit_label (label);
12978 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12979 ix86_emit_fp_unordered_jump (label);
12980 LABEL_NUSES (label) = 1;
12981
12982 /* Truncate the result properly for strict SSE math. */
12983 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12984 && !TARGET_MIX_SSE_I387)
12985 gen_truncxf = gen_truncxf<mode>2;
12986 else
12987 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12988
12989 emit_insn (gen_truncxf (operands[0], op1));
12990 DONE;
12991 })
12992
12993 (define_insn "fprem1xf4_i387"
12994 [(set (match_operand:XF 0 "register_operand" "=f")
12995 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12996 (match_operand:XF 3 "register_operand" "1")]
12997 UNSPEC_FPREM1_F))
12998 (set (match_operand:XF 1 "register_operand" "=u")
12999 (unspec:XF [(match_dup 2) (match_dup 3)]
13000 UNSPEC_FPREM1_U))
13001 (set (reg:CCFP FPSR_REG)
13002 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13003 UNSPEC_C2_FLAG))]
13004 "TARGET_USE_FANCY_MATH_387"
13005 "fprem1"
13006 [(set_attr "type" "fpspc")
13007 (set_attr "mode" "XF")])
13008
13009 (define_expand "remainderxf3"
13010 [(use (match_operand:XF 0 "register_operand" ""))
13011 (use (match_operand:XF 1 "general_operand" ""))
13012 (use (match_operand:XF 2 "general_operand" ""))]
13013 "TARGET_USE_FANCY_MATH_387"
13014 {
13015 rtx label = gen_label_rtx ();
13016
13017 rtx op1 = gen_reg_rtx (XFmode);
13018 rtx op2 = gen_reg_rtx (XFmode);
13019
13020 emit_move_insn (op2, operands[2]);
13021 emit_move_insn (op1, operands[1]);
13022
13023 emit_label (label);
13024 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13025 ix86_emit_fp_unordered_jump (label);
13026 LABEL_NUSES (label) = 1;
13027
13028 emit_move_insn (operands[0], op1);
13029 DONE;
13030 })
13031
13032 (define_expand "remainder<mode>3"
13033 [(use (match_operand:MODEF 0 "register_operand" ""))
13034 (use (match_operand:MODEF 1 "general_operand" ""))
13035 (use (match_operand:MODEF 2 "general_operand" ""))]
13036 "TARGET_USE_FANCY_MATH_387"
13037 {
13038 rtx (*gen_truncxf) (rtx, rtx);
13039
13040 rtx label = gen_label_rtx ();
13041
13042 rtx op1 = gen_reg_rtx (XFmode);
13043 rtx op2 = gen_reg_rtx (XFmode);
13044
13045 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13046 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13047
13048 emit_label (label);
13049
13050 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13051 ix86_emit_fp_unordered_jump (label);
13052 LABEL_NUSES (label) = 1;
13053
13054 /* Truncate the result properly for strict SSE math. */
13055 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13056 && !TARGET_MIX_SSE_I387)
13057 gen_truncxf = gen_truncxf<mode>2;
13058 else
13059 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13060
13061 emit_insn (gen_truncxf (operands[0], op1));
13062 DONE;
13063 })
13064
13065 (define_insn "*sinxf2_i387"
13066 [(set (match_operand:XF 0 "register_operand" "=f")
13067 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13068 "TARGET_USE_FANCY_MATH_387
13069 && flag_unsafe_math_optimizations"
13070 "fsin"
13071 [(set_attr "type" "fpspc")
13072 (set_attr "mode" "XF")])
13073
13074 (define_insn "*sin_extend<mode>xf2_i387"
13075 [(set (match_operand:XF 0 "register_operand" "=f")
13076 (unspec:XF [(float_extend:XF
13077 (match_operand:MODEF 1 "register_operand" "0"))]
13078 UNSPEC_SIN))]
13079 "TARGET_USE_FANCY_MATH_387
13080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13081 || TARGET_MIX_SSE_I387)
13082 && flag_unsafe_math_optimizations"
13083 "fsin"
13084 [(set_attr "type" "fpspc")
13085 (set_attr "mode" "XF")])
13086
13087 (define_insn "*cosxf2_i387"
13088 [(set (match_operand:XF 0 "register_operand" "=f")
13089 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13090 "TARGET_USE_FANCY_MATH_387
13091 && flag_unsafe_math_optimizations"
13092 "fcos"
13093 [(set_attr "type" "fpspc")
13094 (set_attr "mode" "XF")])
13095
13096 (define_insn "*cos_extend<mode>xf2_i387"
13097 [(set (match_operand:XF 0 "register_operand" "=f")
13098 (unspec:XF [(float_extend:XF
13099 (match_operand:MODEF 1 "register_operand" "0"))]
13100 UNSPEC_COS))]
13101 "TARGET_USE_FANCY_MATH_387
13102 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13103 || TARGET_MIX_SSE_I387)
13104 && flag_unsafe_math_optimizations"
13105 "fcos"
13106 [(set_attr "type" "fpspc")
13107 (set_attr "mode" "XF")])
13108
13109 ;; When sincos pattern is defined, sin and cos builtin functions will be
13110 ;; expanded to sincos pattern with one of its outputs left unused.
13111 ;; CSE pass will figure out if two sincos patterns can be combined,
13112 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13113 ;; depending on the unused output.
13114
13115 (define_insn "sincosxf3"
13116 [(set (match_operand:XF 0 "register_operand" "=f")
13117 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13118 UNSPEC_SINCOS_COS))
13119 (set (match_operand:XF 1 "register_operand" "=u")
13120 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13121 "TARGET_USE_FANCY_MATH_387
13122 && flag_unsafe_math_optimizations"
13123 "fsincos"
13124 [(set_attr "type" "fpspc")
13125 (set_attr "mode" "XF")])
13126
13127 (define_split
13128 [(set (match_operand:XF 0 "register_operand" "")
13129 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13130 UNSPEC_SINCOS_COS))
13131 (set (match_operand:XF 1 "register_operand" "")
13132 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13133 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13134 && !(reload_completed || reload_in_progress)"
13135 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13136
13137 (define_split
13138 [(set (match_operand:XF 0 "register_operand" "")
13139 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13140 UNSPEC_SINCOS_COS))
13141 (set (match_operand:XF 1 "register_operand" "")
13142 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13143 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13144 && !(reload_completed || reload_in_progress)"
13145 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13146
13147 (define_insn "sincos_extend<mode>xf3_i387"
13148 [(set (match_operand:XF 0 "register_operand" "=f")
13149 (unspec:XF [(float_extend:XF
13150 (match_operand:MODEF 2 "register_operand" "0"))]
13151 UNSPEC_SINCOS_COS))
13152 (set (match_operand:XF 1 "register_operand" "=u")
13153 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13154 "TARGET_USE_FANCY_MATH_387
13155 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13156 || TARGET_MIX_SSE_I387)
13157 && flag_unsafe_math_optimizations"
13158 "fsincos"
13159 [(set_attr "type" "fpspc")
13160 (set_attr "mode" "XF")])
13161
13162 (define_split
13163 [(set (match_operand:XF 0 "register_operand" "")
13164 (unspec:XF [(float_extend:XF
13165 (match_operand:MODEF 2 "register_operand" ""))]
13166 UNSPEC_SINCOS_COS))
13167 (set (match_operand:XF 1 "register_operand" "")
13168 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13169 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13170 && !(reload_completed || reload_in_progress)"
13171 [(set (match_dup 1)
13172 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13173
13174 (define_split
13175 [(set (match_operand:XF 0 "register_operand" "")
13176 (unspec:XF [(float_extend:XF
13177 (match_operand:MODEF 2 "register_operand" ""))]
13178 UNSPEC_SINCOS_COS))
13179 (set (match_operand:XF 1 "register_operand" "")
13180 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13181 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13182 && !(reload_completed || reload_in_progress)"
13183 [(set (match_dup 0)
13184 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13185
13186 (define_expand "sincos<mode>3"
13187 [(use (match_operand:MODEF 0 "register_operand" ""))
13188 (use (match_operand:MODEF 1 "register_operand" ""))
13189 (use (match_operand:MODEF 2 "register_operand" ""))]
13190 "TARGET_USE_FANCY_MATH_387
13191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13192 || TARGET_MIX_SSE_I387)
13193 && flag_unsafe_math_optimizations"
13194 {
13195 rtx op0 = gen_reg_rtx (XFmode);
13196 rtx op1 = gen_reg_rtx (XFmode);
13197
13198 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13199 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13200 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13201 DONE;
13202 })
13203
13204 (define_insn "fptanxf4_i387"
13205 [(set (match_operand:XF 0 "register_operand" "=f")
13206 (match_operand:XF 3 "const_double_operand" "F"))
13207 (set (match_operand:XF 1 "register_operand" "=u")
13208 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13209 UNSPEC_TAN))]
13210 "TARGET_USE_FANCY_MATH_387
13211 && flag_unsafe_math_optimizations
13212 && standard_80387_constant_p (operands[3]) == 2"
13213 "fptan"
13214 [(set_attr "type" "fpspc")
13215 (set_attr "mode" "XF")])
13216
13217 (define_insn "fptan_extend<mode>xf4_i387"
13218 [(set (match_operand:MODEF 0 "register_operand" "=f")
13219 (match_operand:MODEF 3 "const_double_operand" "F"))
13220 (set (match_operand:XF 1 "register_operand" "=u")
13221 (unspec:XF [(float_extend:XF
13222 (match_operand:MODEF 2 "register_operand" "0"))]
13223 UNSPEC_TAN))]
13224 "TARGET_USE_FANCY_MATH_387
13225 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13226 || TARGET_MIX_SSE_I387)
13227 && flag_unsafe_math_optimizations
13228 && standard_80387_constant_p (operands[3]) == 2"
13229 "fptan"
13230 [(set_attr "type" "fpspc")
13231 (set_attr "mode" "XF")])
13232
13233 (define_expand "tanxf2"
13234 [(use (match_operand:XF 0 "register_operand" ""))
13235 (use (match_operand:XF 1 "register_operand" ""))]
13236 "TARGET_USE_FANCY_MATH_387
13237 && flag_unsafe_math_optimizations"
13238 {
13239 rtx one = gen_reg_rtx (XFmode);
13240 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13241
13242 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13243 DONE;
13244 })
13245
13246 (define_expand "tan<mode>2"
13247 [(use (match_operand:MODEF 0 "register_operand" ""))
13248 (use (match_operand:MODEF 1 "register_operand" ""))]
13249 "TARGET_USE_FANCY_MATH_387
13250 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13251 || TARGET_MIX_SSE_I387)
13252 && flag_unsafe_math_optimizations"
13253 {
13254 rtx op0 = gen_reg_rtx (XFmode);
13255
13256 rtx one = gen_reg_rtx (<MODE>mode);
13257 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13258
13259 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13260 operands[1], op2));
13261 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13262 DONE;
13263 })
13264
13265 (define_insn "*fpatanxf3_i387"
13266 [(set (match_operand:XF 0 "register_operand" "=f")
13267 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13268 (match_operand:XF 2 "register_operand" "u")]
13269 UNSPEC_FPATAN))
13270 (clobber (match_scratch:XF 3 "=2"))]
13271 "TARGET_USE_FANCY_MATH_387
13272 && flag_unsafe_math_optimizations"
13273 "fpatan"
13274 [(set_attr "type" "fpspc")
13275 (set_attr "mode" "XF")])
13276
13277 (define_insn "fpatan_extend<mode>xf3_i387"
13278 [(set (match_operand:XF 0 "register_operand" "=f")
13279 (unspec:XF [(float_extend:XF
13280 (match_operand:MODEF 1 "register_operand" "0"))
13281 (float_extend:XF
13282 (match_operand:MODEF 2 "register_operand" "u"))]
13283 UNSPEC_FPATAN))
13284 (clobber (match_scratch:XF 3 "=2"))]
13285 "TARGET_USE_FANCY_MATH_387
13286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13287 || TARGET_MIX_SSE_I387)
13288 && flag_unsafe_math_optimizations"
13289 "fpatan"
13290 [(set_attr "type" "fpspc")
13291 (set_attr "mode" "XF")])
13292
13293 (define_expand "atan2xf3"
13294 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13295 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13296 (match_operand:XF 1 "register_operand" "")]
13297 UNSPEC_FPATAN))
13298 (clobber (match_scratch:XF 3 ""))])]
13299 "TARGET_USE_FANCY_MATH_387
13300 && flag_unsafe_math_optimizations")
13301
13302 (define_expand "atan2<mode>3"
13303 [(use (match_operand:MODEF 0 "register_operand" ""))
13304 (use (match_operand:MODEF 1 "register_operand" ""))
13305 (use (match_operand:MODEF 2 "register_operand" ""))]
13306 "TARGET_USE_FANCY_MATH_387
13307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13308 || TARGET_MIX_SSE_I387)
13309 && flag_unsafe_math_optimizations"
13310 {
13311 rtx op0 = gen_reg_rtx (XFmode);
13312
13313 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13314 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13315 DONE;
13316 })
13317
13318 (define_expand "atanxf2"
13319 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13320 (unspec:XF [(match_dup 2)
13321 (match_operand:XF 1 "register_operand" "")]
13322 UNSPEC_FPATAN))
13323 (clobber (match_scratch:XF 3 ""))])]
13324 "TARGET_USE_FANCY_MATH_387
13325 && flag_unsafe_math_optimizations"
13326 {
13327 operands[2] = gen_reg_rtx (XFmode);
13328 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13329 })
13330
13331 (define_expand "atan<mode>2"
13332 [(use (match_operand:MODEF 0 "register_operand" ""))
13333 (use (match_operand:MODEF 1 "register_operand" ""))]
13334 "TARGET_USE_FANCY_MATH_387
13335 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13336 || TARGET_MIX_SSE_I387)
13337 && flag_unsafe_math_optimizations"
13338 {
13339 rtx op0 = gen_reg_rtx (XFmode);
13340
13341 rtx op2 = gen_reg_rtx (<MODE>mode);
13342 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13343
13344 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13345 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13346 DONE;
13347 })
13348
13349 (define_expand "asinxf2"
13350 [(set (match_dup 2)
13351 (mult:XF (match_operand:XF 1 "register_operand" "")
13352 (match_dup 1)))
13353 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13354 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13355 (parallel [(set (match_operand:XF 0 "register_operand" "")
13356 (unspec:XF [(match_dup 5) (match_dup 1)]
13357 UNSPEC_FPATAN))
13358 (clobber (match_scratch:XF 6 ""))])]
13359 "TARGET_USE_FANCY_MATH_387
13360 && flag_unsafe_math_optimizations"
13361 {
13362 int i;
13363
13364 if (optimize_insn_for_size_p ())
13365 FAIL;
13366
13367 for (i = 2; i < 6; i++)
13368 operands[i] = gen_reg_rtx (XFmode);
13369
13370 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13371 })
13372
13373 (define_expand "asin<mode>2"
13374 [(use (match_operand:MODEF 0 "register_operand" ""))
13375 (use (match_operand:MODEF 1 "general_operand" ""))]
13376 "TARGET_USE_FANCY_MATH_387
13377 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13378 || TARGET_MIX_SSE_I387)
13379 && flag_unsafe_math_optimizations"
13380 {
13381 rtx op0 = gen_reg_rtx (XFmode);
13382 rtx op1 = gen_reg_rtx (XFmode);
13383
13384 if (optimize_insn_for_size_p ())
13385 FAIL;
13386
13387 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13388 emit_insn (gen_asinxf2 (op0, op1));
13389 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13390 DONE;
13391 })
13392
13393 (define_expand "acosxf2"
13394 [(set (match_dup 2)
13395 (mult:XF (match_operand:XF 1 "register_operand" "")
13396 (match_dup 1)))
13397 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13398 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13399 (parallel [(set (match_operand:XF 0 "register_operand" "")
13400 (unspec:XF [(match_dup 1) (match_dup 5)]
13401 UNSPEC_FPATAN))
13402 (clobber (match_scratch:XF 6 ""))])]
13403 "TARGET_USE_FANCY_MATH_387
13404 && flag_unsafe_math_optimizations"
13405 {
13406 int i;
13407
13408 if (optimize_insn_for_size_p ())
13409 FAIL;
13410
13411 for (i = 2; i < 6; i++)
13412 operands[i] = gen_reg_rtx (XFmode);
13413
13414 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13415 })
13416
13417 (define_expand "acos<mode>2"
13418 [(use (match_operand:MODEF 0 "register_operand" ""))
13419 (use (match_operand:MODEF 1 "general_operand" ""))]
13420 "TARGET_USE_FANCY_MATH_387
13421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13422 || TARGET_MIX_SSE_I387)
13423 && flag_unsafe_math_optimizations"
13424 {
13425 rtx op0 = gen_reg_rtx (XFmode);
13426 rtx op1 = gen_reg_rtx (XFmode);
13427
13428 if (optimize_insn_for_size_p ())
13429 FAIL;
13430
13431 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13432 emit_insn (gen_acosxf2 (op0, op1));
13433 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13434 DONE;
13435 })
13436
13437 (define_insn "fyl2xxf3_i387"
13438 [(set (match_operand:XF 0 "register_operand" "=f")
13439 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13440 (match_operand:XF 2 "register_operand" "u")]
13441 UNSPEC_FYL2X))
13442 (clobber (match_scratch:XF 3 "=2"))]
13443 "TARGET_USE_FANCY_MATH_387
13444 && flag_unsafe_math_optimizations"
13445 "fyl2x"
13446 [(set_attr "type" "fpspc")
13447 (set_attr "mode" "XF")])
13448
13449 (define_insn "fyl2x_extend<mode>xf3_i387"
13450 [(set (match_operand:XF 0 "register_operand" "=f")
13451 (unspec:XF [(float_extend:XF
13452 (match_operand:MODEF 1 "register_operand" "0"))
13453 (match_operand:XF 2 "register_operand" "u")]
13454 UNSPEC_FYL2X))
13455 (clobber (match_scratch:XF 3 "=2"))]
13456 "TARGET_USE_FANCY_MATH_387
13457 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13458 || TARGET_MIX_SSE_I387)
13459 && flag_unsafe_math_optimizations"
13460 "fyl2x"
13461 [(set_attr "type" "fpspc")
13462 (set_attr "mode" "XF")])
13463
13464 (define_expand "logxf2"
13465 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13466 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13467 (match_dup 2)] UNSPEC_FYL2X))
13468 (clobber (match_scratch:XF 3 ""))])]
13469 "TARGET_USE_FANCY_MATH_387
13470 && flag_unsafe_math_optimizations"
13471 {
13472 operands[2] = gen_reg_rtx (XFmode);
13473 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13474 })
13475
13476 (define_expand "log<mode>2"
13477 [(use (match_operand:MODEF 0 "register_operand" ""))
13478 (use (match_operand:MODEF 1 "register_operand" ""))]
13479 "TARGET_USE_FANCY_MATH_387
13480 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13481 || TARGET_MIX_SSE_I387)
13482 && flag_unsafe_math_optimizations"
13483 {
13484 rtx op0 = gen_reg_rtx (XFmode);
13485
13486 rtx op2 = gen_reg_rtx (XFmode);
13487 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13488
13489 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13490 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13491 DONE;
13492 })
13493
13494 (define_expand "log10xf2"
13495 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13496 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13497 (match_dup 2)] UNSPEC_FYL2X))
13498 (clobber (match_scratch:XF 3 ""))])]
13499 "TARGET_USE_FANCY_MATH_387
13500 && flag_unsafe_math_optimizations"
13501 {
13502 operands[2] = gen_reg_rtx (XFmode);
13503 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13504 })
13505
13506 (define_expand "log10<mode>2"
13507 [(use (match_operand:MODEF 0 "register_operand" ""))
13508 (use (match_operand:MODEF 1 "register_operand" ""))]
13509 "TARGET_USE_FANCY_MATH_387
13510 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13511 || TARGET_MIX_SSE_I387)
13512 && flag_unsafe_math_optimizations"
13513 {
13514 rtx op0 = gen_reg_rtx (XFmode);
13515
13516 rtx op2 = gen_reg_rtx (XFmode);
13517 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13518
13519 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13520 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13521 DONE;
13522 })
13523
13524 (define_expand "log2xf2"
13525 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13526 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13527 (match_dup 2)] UNSPEC_FYL2X))
13528 (clobber (match_scratch:XF 3 ""))])]
13529 "TARGET_USE_FANCY_MATH_387
13530 && flag_unsafe_math_optimizations"
13531 {
13532 operands[2] = gen_reg_rtx (XFmode);
13533 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13534 })
13535
13536 (define_expand "log2<mode>2"
13537 [(use (match_operand:MODEF 0 "register_operand" ""))
13538 (use (match_operand:MODEF 1 "register_operand" ""))]
13539 "TARGET_USE_FANCY_MATH_387
13540 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13541 || TARGET_MIX_SSE_I387)
13542 && flag_unsafe_math_optimizations"
13543 {
13544 rtx op0 = gen_reg_rtx (XFmode);
13545
13546 rtx op2 = gen_reg_rtx (XFmode);
13547 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13548
13549 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13550 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13551 DONE;
13552 })
13553
13554 (define_insn "fyl2xp1xf3_i387"
13555 [(set (match_operand:XF 0 "register_operand" "=f")
13556 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13557 (match_operand:XF 2 "register_operand" "u")]
13558 UNSPEC_FYL2XP1))
13559 (clobber (match_scratch:XF 3 "=2"))]
13560 "TARGET_USE_FANCY_MATH_387
13561 && flag_unsafe_math_optimizations"
13562 "fyl2xp1"
13563 [(set_attr "type" "fpspc")
13564 (set_attr "mode" "XF")])
13565
13566 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13567 [(set (match_operand:XF 0 "register_operand" "=f")
13568 (unspec:XF [(float_extend:XF
13569 (match_operand:MODEF 1 "register_operand" "0"))
13570 (match_operand:XF 2 "register_operand" "u")]
13571 UNSPEC_FYL2XP1))
13572 (clobber (match_scratch:XF 3 "=2"))]
13573 "TARGET_USE_FANCY_MATH_387
13574 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13575 || TARGET_MIX_SSE_I387)
13576 && flag_unsafe_math_optimizations"
13577 "fyl2xp1"
13578 [(set_attr "type" "fpspc")
13579 (set_attr "mode" "XF")])
13580
13581 (define_expand "log1pxf2"
13582 [(use (match_operand:XF 0 "register_operand" ""))
13583 (use (match_operand:XF 1 "register_operand" ""))]
13584 "TARGET_USE_FANCY_MATH_387
13585 && flag_unsafe_math_optimizations"
13586 {
13587 if (optimize_insn_for_size_p ())
13588 FAIL;
13589
13590 ix86_emit_i387_log1p (operands[0], operands[1]);
13591 DONE;
13592 })
13593
13594 (define_expand "log1p<mode>2"
13595 [(use (match_operand:MODEF 0 "register_operand" ""))
13596 (use (match_operand:MODEF 1 "register_operand" ""))]
13597 "TARGET_USE_FANCY_MATH_387
13598 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13599 || TARGET_MIX_SSE_I387)
13600 && flag_unsafe_math_optimizations"
13601 {
13602 rtx op0;
13603
13604 if (optimize_insn_for_size_p ())
13605 FAIL;
13606
13607 op0 = gen_reg_rtx (XFmode);
13608
13609 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13610
13611 ix86_emit_i387_log1p (op0, operands[1]);
13612 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13613 DONE;
13614 })
13615
13616 (define_insn "fxtractxf3_i387"
13617 [(set (match_operand:XF 0 "register_operand" "=f")
13618 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13619 UNSPEC_XTRACT_FRACT))
13620 (set (match_operand:XF 1 "register_operand" "=u")
13621 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13622 "TARGET_USE_FANCY_MATH_387
13623 && flag_unsafe_math_optimizations"
13624 "fxtract"
13625 [(set_attr "type" "fpspc")
13626 (set_attr "mode" "XF")])
13627
13628 (define_insn "fxtract_extend<mode>xf3_i387"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(float_extend:XF
13631 (match_operand:MODEF 2 "register_operand" "0"))]
13632 UNSPEC_XTRACT_FRACT))
13633 (set (match_operand:XF 1 "register_operand" "=u")
13634 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13635 "TARGET_USE_FANCY_MATH_387
13636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13637 || TARGET_MIX_SSE_I387)
13638 && flag_unsafe_math_optimizations"
13639 "fxtract"
13640 [(set_attr "type" "fpspc")
13641 (set_attr "mode" "XF")])
13642
13643 (define_expand "logbxf2"
13644 [(parallel [(set (match_dup 2)
13645 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13646 UNSPEC_XTRACT_FRACT))
13647 (set (match_operand:XF 0 "register_operand" "")
13648 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13649 "TARGET_USE_FANCY_MATH_387
13650 && flag_unsafe_math_optimizations"
13651 "operands[2] = gen_reg_rtx (XFmode);")
13652
13653 (define_expand "logb<mode>2"
13654 [(use (match_operand:MODEF 0 "register_operand" ""))
13655 (use (match_operand:MODEF 1 "register_operand" ""))]
13656 "TARGET_USE_FANCY_MATH_387
13657 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13658 || TARGET_MIX_SSE_I387)
13659 && flag_unsafe_math_optimizations"
13660 {
13661 rtx op0 = gen_reg_rtx (XFmode);
13662 rtx op1 = gen_reg_rtx (XFmode);
13663
13664 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13665 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13666 DONE;
13667 })
13668
13669 (define_expand "ilogbxf2"
13670 [(use (match_operand:SI 0 "register_operand" ""))
13671 (use (match_operand:XF 1 "register_operand" ""))]
13672 "TARGET_USE_FANCY_MATH_387
13673 && flag_unsafe_math_optimizations"
13674 {
13675 rtx op0, op1;
13676
13677 if (optimize_insn_for_size_p ())
13678 FAIL;
13679
13680 op0 = gen_reg_rtx (XFmode);
13681 op1 = gen_reg_rtx (XFmode);
13682
13683 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13684 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13685 DONE;
13686 })
13687
13688 (define_expand "ilogb<mode>2"
13689 [(use (match_operand:SI 0 "register_operand" ""))
13690 (use (match_operand:MODEF 1 "register_operand" ""))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13693 || TARGET_MIX_SSE_I387)
13694 && flag_unsafe_math_optimizations"
13695 {
13696 rtx op0, op1;
13697
13698 if (optimize_insn_for_size_p ())
13699 FAIL;
13700
13701 op0 = gen_reg_rtx (XFmode);
13702 op1 = gen_reg_rtx (XFmode);
13703
13704 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13705 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13706 DONE;
13707 })
13708
13709 (define_insn "*f2xm1xf2_i387"
13710 [(set (match_operand:XF 0 "register_operand" "=f")
13711 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13712 UNSPEC_F2XM1))]
13713 "TARGET_USE_FANCY_MATH_387
13714 && flag_unsafe_math_optimizations"
13715 "f2xm1"
13716 [(set_attr "type" "fpspc")
13717 (set_attr "mode" "XF")])
13718
13719 (define_insn "*fscalexf4_i387"
13720 [(set (match_operand:XF 0 "register_operand" "=f")
13721 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13722 (match_operand:XF 3 "register_operand" "1")]
13723 UNSPEC_FSCALE_FRACT))
13724 (set (match_operand:XF 1 "register_operand" "=u")
13725 (unspec:XF [(match_dup 2) (match_dup 3)]
13726 UNSPEC_FSCALE_EXP))]
13727 "TARGET_USE_FANCY_MATH_387
13728 && flag_unsafe_math_optimizations"
13729 "fscale"
13730 [(set_attr "type" "fpspc")
13731 (set_attr "mode" "XF")])
13732
13733 (define_expand "expNcorexf3"
13734 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13735 (match_operand:XF 2 "register_operand" "")))
13736 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13737 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13738 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13739 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13740 (parallel [(set (match_operand:XF 0 "register_operand" "")
13741 (unspec:XF [(match_dup 8) (match_dup 4)]
13742 UNSPEC_FSCALE_FRACT))
13743 (set (match_dup 9)
13744 (unspec:XF [(match_dup 8) (match_dup 4)]
13745 UNSPEC_FSCALE_EXP))])]
13746 "TARGET_USE_FANCY_MATH_387
13747 && flag_unsafe_math_optimizations"
13748 {
13749 int i;
13750
13751 if (optimize_insn_for_size_p ())
13752 FAIL;
13753
13754 for (i = 3; i < 10; i++)
13755 operands[i] = gen_reg_rtx (XFmode);
13756
13757 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13758 })
13759
13760 (define_expand "expxf2"
13761 [(use (match_operand:XF 0 "register_operand" ""))
13762 (use (match_operand:XF 1 "register_operand" ""))]
13763 "TARGET_USE_FANCY_MATH_387
13764 && flag_unsafe_math_optimizations"
13765 {
13766 rtx op2;
13767
13768 if (optimize_insn_for_size_p ())
13769 FAIL;
13770
13771 op2 = gen_reg_rtx (XFmode);
13772 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13773
13774 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13775 DONE;
13776 })
13777
13778 (define_expand "exp<mode>2"
13779 [(use (match_operand:MODEF 0 "register_operand" ""))
13780 (use (match_operand:MODEF 1 "general_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, op1;
13787
13788 if (optimize_insn_for_size_p ())
13789 FAIL;
13790
13791 op0 = gen_reg_rtx (XFmode);
13792 op1 = gen_reg_rtx (XFmode);
13793
13794 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13795 emit_insn (gen_expxf2 (op0, op1));
13796 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13797 DONE;
13798 })
13799
13800 (define_expand "exp10xf2"
13801 [(use (match_operand:XF 0 "register_operand" ""))
13802 (use (match_operand:XF 1 "register_operand" ""))]
13803 "TARGET_USE_FANCY_MATH_387
13804 && flag_unsafe_math_optimizations"
13805 {
13806 rtx op2;
13807
13808 if (optimize_insn_for_size_p ())
13809 FAIL;
13810
13811 op2 = gen_reg_rtx (XFmode);
13812 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13813
13814 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13815 DONE;
13816 })
13817
13818 (define_expand "exp10<mode>2"
13819 [(use (match_operand:MODEF 0 "register_operand" ""))
13820 (use (match_operand:MODEF 1 "general_operand" ""))]
13821 "TARGET_USE_FANCY_MATH_387
13822 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13823 || TARGET_MIX_SSE_I387)
13824 && flag_unsafe_math_optimizations"
13825 {
13826 rtx op0, op1;
13827
13828 if (optimize_insn_for_size_p ())
13829 FAIL;
13830
13831 op0 = gen_reg_rtx (XFmode);
13832 op1 = gen_reg_rtx (XFmode);
13833
13834 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13835 emit_insn (gen_exp10xf2 (op0, op1));
13836 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13837 DONE;
13838 })
13839
13840 (define_expand "exp2xf2"
13841 [(use (match_operand:XF 0 "register_operand" ""))
13842 (use (match_operand:XF 1 "register_operand" ""))]
13843 "TARGET_USE_FANCY_MATH_387
13844 && flag_unsafe_math_optimizations"
13845 {
13846 rtx op2;
13847
13848 if (optimize_insn_for_size_p ())
13849 FAIL;
13850
13851 op2 = gen_reg_rtx (XFmode);
13852 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13853
13854 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13855 DONE;
13856 })
13857
13858 (define_expand "exp2<mode>2"
13859 [(use (match_operand:MODEF 0 "register_operand" ""))
13860 (use (match_operand:MODEF 1 "general_operand" ""))]
13861 "TARGET_USE_FANCY_MATH_387
13862 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13863 || TARGET_MIX_SSE_I387)
13864 && flag_unsafe_math_optimizations"
13865 {
13866 rtx op0, op1;
13867
13868 if (optimize_insn_for_size_p ())
13869 FAIL;
13870
13871 op0 = gen_reg_rtx (XFmode);
13872 op1 = gen_reg_rtx (XFmode);
13873
13874 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13875 emit_insn (gen_exp2xf2 (op0, op1));
13876 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13877 DONE;
13878 })
13879
13880 (define_expand "expm1xf2"
13881 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13882 (match_dup 2)))
13883 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13884 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13885 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13886 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13887 (parallel [(set (match_dup 7)
13888 (unspec:XF [(match_dup 6) (match_dup 4)]
13889 UNSPEC_FSCALE_FRACT))
13890 (set (match_dup 8)
13891 (unspec:XF [(match_dup 6) (match_dup 4)]
13892 UNSPEC_FSCALE_EXP))])
13893 (parallel [(set (match_dup 10)
13894 (unspec:XF [(match_dup 9) (match_dup 8)]
13895 UNSPEC_FSCALE_FRACT))
13896 (set (match_dup 11)
13897 (unspec:XF [(match_dup 9) (match_dup 8)]
13898 UNSPEC_FSCALE_EXP))])
13899 (set (match_dup 12) (minus:XF (match_dup 10)
13900 (float_extend:XF (match_dup 13))))
13901 (set (match_operand:XF 0 "register_operand" "")
13902 (plus:XF (match_dup 12) (match_dup 7)))]
13903 "TARGET_USE_FANCY_MATH_387
13904 && flag_unsafe_math_optimizations"
13905 {
13906 int i;
13907
13908 if (optimize_insn_for_size_p ())
13909 FAIL;
13910
13911 for (i = 2; i < 13; i++)
13912 operands[i] = gen_reg_rtx (XFmode);
13913
13914 operands[13]
13915 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13916
13917 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13918 })
13919
13920 (define_expand "expm1<mode>2"
13921 [(use (match_operand:MODEF 0 "register_operand" ""))
13922 (use (match_operand:MODEF 1 "general_operand" ""))]
13923 "TARGET_USE_FANCY_MATH_387
13924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13925 || TARGET_MIX_SSE_I387)
13926 && flag_unsafe_math_optimizations"
13927 {
13928 rtx op0, op1;
13929
13930 if (optimize_insn_for_size_p ())
13931 FAIL;
13932
13933 op0 = gen_reg_rtx (XFmode);
13934 op1 = gen_reg_rtx (XFmode);
13935
13936 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13937 emit_insn (gen_expm1xf2 (op0, op1));
13938 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13939 DONE;
13940 })
13941
13942 (define_expand "ldexpxf3"
13943 [(set (match_dup 3)
13944 (float:XF (match_operand:SI 2 "register_operand" "")))
13945 (parallel [(set (match_operand:XF 0 " register_operand" "")
13946 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13947 (match_dup 3)]
13948 UNSPEC_FSCALE_FRACT))
13949 (set (match_dup 4)
13950 (unspec:XF [(match_dup 1) (match_dup 3)]
13951 UNSPEC_FSCALE_EXP))])]
13952 "TARGET_USE_FANCY_MATH_387
13953 && flag_unsafe_math_optimizations"
13954 {
13955 if (optimize_insn_for_size_p ())
13956 FAIL;
13957
13958 operands[3] = gen_reg_rtx (XFmode);
13959 operands[4] = gen_reg_rtx (XFmode);
13960 })
13961
13962 (define_expand "ldexp<mode>3"
13963 [(use (match_operand:MODEF 0 "register_operand" ""))
13964 (use (match_operand:MODEF 1 "general_operand" ""))
13965 (use (match_operand:SI 2 "register_operand" ""))]
13966 "TARGET_USE_FANCY_MATH_387
13967 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13968 || TARGET_MIX_SSE_I387)
13969 && flag_unsafe_math_optimizations"
13970 {
13971 rtx op0, op1;
13972
13973 if (optimize_insn_for_size_p ())
13974 FAIL;
13975
13976 op0 = gen_reg_rtx (XFmode);
13977 op1 = gen_reg_rtx (XFmode);
13978
13979 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13980 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13981 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13982 DONE;
13983 })
13984
13985 (define_expand "scalbxf3"
13986 [(parallel [(set (match_operand:XF 0 " register_operand" "")
13987 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13988 (match_operand:XF 2 "register_operand" "")]
13989 UNSPEC_FSCALE_FRACT))
13990 (set (match_dup 3)
13991 (unspec:XF [(match_dup 1) (match_dup 2)]
13992 UNSPEC_FSCALE_EXP))])]
13993 "TARGET_USE_FANCY_MATH_387
13994 && flag_unsafe_math_optimizations"
13995 {
13996 if (optimize_insn_for_size_p ())
13997 FAIL;
13998
13999 operands[3] = gen_reg_rtx (XFmode);
14000 })
14001
14002 (define_expand "scalb<mode>3"
14003 [(use (match_operand:MODEF 0 "register_operand" ""))
14004 (use (match_operand:MODEF 1 "general_operand" ""))
14005 (use (match_operand:MODEF 2 "general_operand" ""))]
14006 "TARGET_USE_FANCY_MATH_387
14007 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14008 || TARGET_MIX_SSE_I387)
14009 && flag_unsafe_math_optimizations"
14010 {
14011 rtx op0, op1, op2;
14012
14013 if (optimize_insn_for_size_p ())
14014 FAIL;
14015
14016 op0 = gen_reg_rtx (XFmode);
14017 op1 = gen_reg_rtx (XFmode);
14018 op2 = gen_reg_rtx (XFmode);
14019
14020 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14021 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14022 emit_insn (gen_scalbxf3 (op0, op1, op2));
14023 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14024 DONE;
14025 })
14026
14027 (define_expand "significandxf2"
14028 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14029 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14030 UNSPEC_XTRACT_FRACT))
14031 (set (match_dup 2)
14032 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14033 "TARGET_USE_FANCY_MATH_387
14034 && flag_unsafe_math_optimizations"
14035 "operands[2] = gen_reg_rtx (XFmode);")
14036
14037 (define_expand "significand<mode>2"
14038 [(use (match_operand:MODEF 0 "register_operand" ""))
14039 (use (match_operand:MODEF 1 "register_operand" ""))]
14040 "TARGET_USE_FANCY_MATH_387
14041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042 || TARGET_MIX_SSE_I387)
14043 && flag_unsafe_math_optimizations"
14044 {
14045 rtx op0 = gen_reg_rtx (XFmode);
14046 rtx op1 = gen_reg_rtx (XFmode);
14047
14048 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14050 DONE;
14051 })
14052 \f
14053
14054 (define_insn "sse4_1_round<mode>2"
14055 [(set (match_operand:MODEF 0 "register_operand" "=x")
14056 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14057 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14058 UNSPEC_ROUND))]
14059 "TARGET_ROUND"
14060 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14061 [(set_attr "type" "ssecvt")
14062 (set_attr "prefix_extra" "1")
14063 (set_attr "prefix" "maybe_vex")
14064 (set_attr "mode" "<MODE>")])
14065
14066 (define_insn "rintxf2"
14067 [(set (match_operand:XF 0 "register_operand" "=f")
14068 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14069 UNSPEC_FRNDINT))]
14070 "TARGET_USE_FANCY_MATH_387
14071 && flag_unsafe_math_optimizations"
14072 "frndint"
14073 [(set_attr "type" "fpspc")
14074 (set_attr "mode" "XF")])
14075
14076 (define_expand "rint<mode>2"
14077 [(use (match_operand:MODEF 0 "register_operand" ""))
14078 (use (match_operand:MODEF 1 "register_operand" ""))]
14079 "(TARGET_USE_FANCY_MATH_387
14080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14081 || TARGET_MIX_SSE_I387)
14082 && flag_unsafe_math_optimizations)
14083 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14084 && !flag_trapping_math)"
14085 {
14086 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14087 && !flag_trapping_math)
14088 {
14089 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14090 FAIL;
14091 if (TARGET_ROUND)
14092 emit_insn (gen_sse4_1_round<mode>2
14093 (operands[0], operands[1], GEN_INT (0x04)));
14094 else
14095 ix86_expand_rint (operand0, operand1);
14096 }
14097 else
14098 {
14099 rtx op0 = gen_reg_rtx (XFmode);
14100 rtx op1 = gen_reg_rtx (XFmode);
14101
14102 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14103 emit_insn (gen_rintxf2 (op0, op1));
14104
14105 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14106 }
14107 DONE;
14108 })
14109
14110 (define_expand "round<mode>2"
14111 [(match_operand:MODEF 0 "register_operand" "")
14112 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14113 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14114 && !flag_trapping_math && !flag_rounding_math"
14115 {
14116 if (optimize_insn_for_size_p ())
14117 FAIL;
14118 if (TARGET_64BIT || (<MODE>mode != DFmode))
14119 ix86_expand_round (operand0, operand1);
14120 else
14121 ix86_expand_rounddf_32 (operand0, operand1);
14122 DONE;
14123 })
14124
14125 (define_insn_and_split "*fistdi2_1"
14126 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14127 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14128 UNSPEC_FIST))]
14129 "TARGET_USE_FANCY_MATH_387
14130 && can_create_pseudo_p ()"
14131 "#"
14132 "&& 1"
14133 [(const_int 0)]
14134 {
14135 if (memory_operand (operands[0], VOIDmode))
14136 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14137 else
14138 {
14139 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14140 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14141 operands[2]));
14142 }
14143 DONE;
14144 }
14145 [(set_attr "type" "fpspc")
14146 (set_attr "mode" "DI")])
14147
14148 (define_insn "fistdi2"
14149 [(set (match_operand:DI 0 "memory_operand" "=m")
14150 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14151 UNSPEC_FIST))
14152 (clobber (match_scratch:XF 2 "=&1f"))]
14153 "TARGET_USE_FANCY_MATH_387"
14154 "* return output_fix_trunc (insn, operands, 0);"
14155 [(set_attr "type" "fpspc")
14156 (set_attr "mode" "DI")])
14157
14158 (define_insn "fistdi2_with_temp"
14159 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14160 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14161 UNSPEC_FIST))
14162 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14163 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14164 "TARGET_USE_FANCY_MATH_387"
14165 "#"
14166 [(set_attr "type" "fpspc")
14167 (set_attr "mode" "DI")])
14168
14169 (define_split
14170 [(set (match_operand:DI 0 "register_operand" "")
14171 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14172 UNSPEC_FIST))
14173 (clobber (match_operand:DI 2 "memory_operand" ""))
14174 (clobber (match_scratch 3 ""))]
14175 "reload_completed"
14176 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14177 (clobber (match_dup 3))])
14178 (set (match_dup 0) (match_dup 2))])
14179
14180 (define_split
14181 [(set (match_operand:DI 0 "memory_operand" "")
14182 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14183 UNSPEC_FIST))
14184 (clobber (match_operand:DI 2 "memory_operand" ""))
14185 (clobber (match_scratch 3 ""))]
14186 "reload_completed"
14187 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14188 (clobber (match_dup 3))])])
14189
14190 (define_insn_and_split "*fist<mode>2_1"
14191 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14192 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14193 UNSPEC_FIST))]
14194 "TARGET_USE_FANCY_MATH_387
14195 && can_create_pseudo_p ()"
14196 "#"
14197 "&& 1"
14198 [(const_int 0)]
14199 {
14200 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14201 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14202 operands[2]));
14203 DONE;
14204 }
14205 [(set_attr "type" "fpspc")
14206 (set_attr "mode" "<MODE>")])
14207
14208 (define_insn "fist<mode>2"
14209 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14210 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14211 UNSPEC_FIST))]
14212 "TARGET_USE_FANCY_MATH_387"
14213 "* return output_fix_trunc (insn, operands, 0);"
14214 [(set_attr "type" "fpspc")
14215 (set_attr "mode" "<MODE>")])
14216
14217 (define_insn "fist<mode>2_with_temp"
14218 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14219 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14220 UNSPEC_FIST))
14221 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14222 "TARGET_USE_FANCY_MATH_387"
14223 "#"
14224 [(set_attr "type" "fpspc")
14225 (set_attr "mode" "<MODE>")])
14226
14227 (define_split
14228 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14229 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14230 UNSPEC_FIST))
14231 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14232 "reload_completed"
14233 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14234 (set (match_dup 0) (match_dup 2))])
14235
14236 (define_split
14237 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14238 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14239 UNSPEC_FIST))
14240 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14241 "reload_completed"
14242 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14243
14244 (define_expand "lrintxf<mode>2"
14245 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14246 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14247 UNSPEC_FIST))]
14248 "TARGET_USE_FANCY_MATH_387")
14249
14250 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14251 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14252 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14253 UNSPEC_FIX_NOTRUNC))]
14254 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14255 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14256
14257 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14258 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14259 (match_operand:MODEF 1 "register_operand" "")]
14260 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14261 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14262 && !flag_trapping_math && !flag_rounding_math"
14263 {
14264 if (optimize_insn_for_size_p ())
14265 FAIL;
14266 ix86_expand_lround (operand0, operand1);
14267 DONE;
14268 })
14269
14270 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14271 (define_insn_and_split "frndintxf2_floor"
14272 [(set (match_operand:XF 0 "register_operand" "")
14273 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14274 UNSPEC_FRNDINT_FLOOR))
14275 (clobber (reg:CC FLAGS_REG))]
14276 "TARGET_USE_FANCY_MATH_387
14277 && flag_unsafe_math_optimizations
14278 && can_create_pseudo_p ()"
14279 "#"
14280 "&& 1"
14281 [(const_int 0)]
14282 {
14283 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14284
14285 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14286 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14287
14288 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14289 operands[2], operands[3]));
14290 DONE;
14291 }
14292 [(set_attr "type" "frndint")
14293 (set_attr "i387_cw" "floor")
14294 (set_attr "mode" "XF")])
14295
14296 (define_insn "frndintxf2_floor_i387"
14297 [(set (match_operand:XF 0 "register_operand" "=f")
14298 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14299 UNSPEC_FRNDINT_FLOOR))
14300 (use (match_operand:HI 2 "memory_operand" "m"))
14301 (use (match_operand:HI 3 "memory_operand" "m"))]
14302 "TARGET_USE_FANCY_MATH_387
14303 && flag_unsafe_math_optimizations"
14304 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14305 [(set_attr "type" "frndint")
14306 (set_attr "i387_cw" "floor")
14307 (set_attr "mode" "XF")])
14308
14309 (define_expand "floorxf2"
14310 [(use (match_operand:XF 0 "register_operand" ""))
14311 (use (match_operand:XF 1 "register_operand" ""))]
14312 "TARGET_USE_FANCY_MATH_387
14313 && flag_unsafe_math_optimizations"
14314 {
14315 if (optimize_insn_for_size_p ())
14316 FAIL;
14317 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14318 DONE;
14319 })
14320
14321 (define_expand "floor<mode>2"
14322 [(use (match_operand:MODEF 0 "register_operand" ""))
14323 (use (match_operand:MODEF 1 "register_operand" ""))]
14324 "(TARGET_USE_FANCY_MATH_387
14325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326 || TARGET_MIX_SSE_I387)
14327 && flag_unsafe_math_optimizations)
14328 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14329 && !flag_trapping_math)"
14330 {
14331 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14332 && !flag_trapping_math
14333 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14334 {
14335 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14336 FAIL;
14337 if (TARGET_ROUND)
14338 emit_insn (gen_sse4_1_round<mode>2
14339 (operands[0], operands[1], GEN_INT (0x01)));
14340 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14341 ix86_expand_floorceil (operand0, operand1, true);
14342 else
14343 ix86_expand_floorceildf_32 (operand0, operand1, true);
14344 }
14345 else
14346 {
14347 rtx op0, op1;
14348
14349 if (optimize_insn_for_size_p ())
14350 FAIL;
14351
14352 op0 = gen_reg_rtx (XFmode);
14353 op1 = gen_reg_rtx (XFmode);
14354 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14355 emit_insn (gen_frndintxf2_floor (op0, op1));
14356
14357 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14358 }
14359 DONE;
14360 })
14361
14362 (define_insn_and_split "*fist<mode>2_floor_1"
14363 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14364 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14365 UNSPEC_FIST_FLOOR))
14366 (clobber (reg:CC FLAGS_REG))]
14367 "TARGET_USE_FANCY_MATH_387
14368 && flag_unsafe_math_optimizations
14369 && can_create_pseudo_p ()"
14370 "#"
14371 "&& 1"
14372 [(const_int 0)]
14373 {
14374 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14375
14376 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14377 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14378 if (memory_operand (operands[0], VOIDmode))
14379 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14380 operands[2], operands[3]));
14381 else
14382 {
14383 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14384 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14385 operands[2], operands[3],
14386 operands[4]));
14387 }
14388 DONE;
14389 }
14390 [(set_attr "type" "fistp")
14391 (set_attr "i387_cw" "floor")
14392 (set_attr "mode" "<MODE>")])
14393
14394 (define_insn "fistdi2_floor"
14395 [(set (match_operand:DI 0 "memory_operand" "=m")
14396 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14397 UNSPEC_FIST_FLOOR))
14398 (use (match_operand:HI 2 "memory_operand" "m"))
14399 (use (match_operand:HI 3 "memory_operand" "m"))
14400 (clobber (match_scratch:XF 4 "=&1f"))]
14401 "TARGET_USE_FANCY_MATH_387
14402 && flag_unsafe_math_optimizations"
14403 "* return output_fix_trunc (insn, operands, 0);"
14404 [(set_attr "type" "fistp")
14405 (set_attr "i387_cw" "floor")
14406 (set_attr "mode" "DI")])
14407
14408 (define_insn "fistdi2_floor_with_temp"
14409 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14410 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14411 UNSPEC_FIST_FLOOR))
14412 (use (match_operand:HI 2 "memory_operand" "m,m"))
14413 (use (match_operand:HI 3 "memory_operand" "m,m"))
14414 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14415 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14416 "TARGET_USE_FANCY_MATH_387
14417 && flag_unsafe_math_optimizations"
14418 "#"
14419 [(set_attr "type" "fistp")
14420 (set_attr "i387_cw" "floor")
14421 (set_attr "mode" "DI")])
14422
14423 (define_split
14424 [(set (match_operand:DI 0 "register_operand" "")
14425 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14426 UNSPEC_FIST_FLOOR))
14427 (use (match_operand:HI 2 "memory_operand" ""))
14428 (use (match_operand:HI 3 "memory_operand" ""))
14429 (clobber (match_operand:DI 4 "memory_operand" ""))
14430 (clobber (match_scratch 5 ""))]
14431 "reload_completed"
14432 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14433 (use (match_dup 2))
14434 (use (match_dup 3))
14435 (clobber (match_dup 5))])
14436 (set (match_dup 0) (match_dup 4))])
14437
14438 (define_split
14439 [(set (match_operand:DI 0 "memory_operand" "")
14440 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14441 UNSPEC_FIST_FLOOR))
14442 (use (match_operand:HI 2 "memory_operand" ""))
14443 (use (match_operand:HI 3 "memory_operand" ""))
14444 (clobber (match_operand:DI 4 "memory_operand" ""))
14445 (clobber (match_scratch 5 ""))]
14446 "reload_completed"
14447 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14448 (use (match_dup 2))
14449 (use (match_dup 3))
14450 (clobber (match_dup 5))])])
14451
14452 (define_insn "fist<mode>2_floor"
14453 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14454 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14455 UNSPEC_FIST_FLOOR))
14456 (use (match_operand:HI 2 "memory_operand" "m"))
14457 (use (match_operand:HI 3 "memory_operand" "m"))]
14458 "TARGET_USE_FANCY_MATH_387
14459 && flag_unsafe_math_optimizations"
14460 "* return output_fix_trunc (insn, operands, 0);"
14461 [(set_attr "type" "fistp")
14462 (set_attr "i387_cw" "floor")
14463 (set_attr "mode" "<MODE>")])
14464
14465 (define_insn "fist<mode>2_floor_with_temp"
14466 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14467 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14468 UNSPEC_FIST_FLOOR))
14469 (use (match_operand:HI 2 "memory_operand" "m,m"))
14470 (use (match_operand:HI 3 "memory_operand" "m,m"))
14471 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14472 "TARGET_USE_FANCY_MATH_387
14473 && flag_unsafe_math_optimizations"
14474 "#"
14475 [(set_attr "type" "fistp")
14476 (set_attr "i387_cw" "floor")
14477 (set_attr "mode" "<MODE>")])
14478
14479 (define_split
14480 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14481 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14482 UNSPEC_FIST_FLOOR))
14483 (use (match_operand:HI 2 "memory_operand" ""))
14484 (use (match_operand:HI 3 "memory_operand" ""))
14485 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14486 "reload_completed"
14487 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14488 UNSPEC_FIST_FLOOR))
14489 (use (match_dup 2))
14490 (use (match_dup 3))])
14491 (set (match_dup 0) (match_dup 4))])
14492
14493 (define_split
14494 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14495 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14496 UNSPEC_FIST_FLOOR))
14497 (use (match_operand:HI 2 "memory_operand" ""))
14498 (use (match_operand:HI 3 "memory_operand" ""))
14499 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14500 "reload_completed"
14501 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14502 UNSPEC_FIST_FLOOR))
14503 (use (match_dup 2))
14504 (use (match_dup 3))])])
14505
14506 (define_expand "lfloorxf<mode>2"
14507 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14508 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14509 UNSPEC_FIST_FLOOR))
14510 (clobber (reg:CC FLAGS_REG))])]
14511 "TARGET_USE_FANCY_MATH_387
14512 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14513 && flag_unsafe_math_optimizations")
14514
14515 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14516 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14517 (match_operand:MODEF 1 "register_operand" "")]
14518 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14519 && !flag_trapping_math"
14520 {
14521 if (TARGET_64BIT && optimize_insn_for_size_p ())
14522 FAIL;
14523 ix86_expand_lfloorceil (operand0, operand1, true);
14524 DONE;
14525 })
14526
14527 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14528 (define_insn_and_split "frndintxf2_ceil"
14529 [(set (match_operand:XF 0 "register_operand" "")
14530 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14531 UNSPEC_FRNDINT_CEIL))
14532 (clobber (reg:CC FLAGS_REG))]
14533 "TARGET_USE_FANCY_MATH_387
14534 && flag_unsafe_math_optimizations
14535 && can_create_pseudo_p ()"
14536 "#"
14537 "&& 1"
14538 [(const_int 0)]
14539 {
14540 ix86_optimize_mode_switching[I387_CEIL] = 1;
14541
14542 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14543 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14544
14545 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14546 operands[2], operands[3]));
14547 DONE;
14548 }
14549 [(set_attr "type" "frndint")
14550 (set_attr "i387_cw" "ceil")
14551 (set_attr "mode" "XF")])
14552
14553 (define_insn "frndintxf2_ceil_i387"
14554 [(set (match_operand:XF 0 "register_operand" "=f")
14555 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14556 UNSPEC_FRNDINT_CEIL))
14557 (use (match_operand:HI 2 "memory_operand" "m"))
14558 (use (match_operand:HI 3 "memory_operand" "m"))]
14559 "TARGET_USE_FANCY_MATH_387
14560 && flag_unsafe_math_optimizations"
14561 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14562 [(set_attr "type" "frndint")
14563 (set_attr "i387_cw" "ceil")
14564 (set_attr "mode" "XF")])
14565
14566 (define_expand "ceilxf2"
14567 [(use (match_operand:XF 0 "register_operand" ""))
14568 (use (match_operand:XF 1 "register_operand" ""))]
14569 "TARGET_USE_FANCY_MATH_387
14570 && flag_unsafe_math_optimizations"
14571 {
14572 if (optimize_insn_for_size_p ())
14573 FAIL;
14574 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14575 DONE;
14576 })
14577
14578 (define_expand "ceil<mode>2"
14579 [(use (match_operand:MODEF 0 "register_operand" ""))
14580 (use (match_operand:MODEF 1 "register_operand" ""))]
14581 "(TARGET_USE_FANCY_MATH_387
14582 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14583 || TARGET_MIX_SSE_I387)
14584 && flag_unsafe_math_optimizations)
14585 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14586 && !flag_trapping_math)"
14587 {
14588 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14589 && !flag_trapping_math
14590 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14591 {
14592 if (TARGET_ROUND)
14593 emit_insn (gen_sse4_1_round<mode>2
14594 (operands[0], operands[1], GEN_INT (0x02)));
14595 else if (optimize_insn_for_size_p ())
14596 FAIL;
14597 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14598 ix86_expand_floorceil (operand0, operand1, false);
14599 else
14600 ix86_expand_floorceildf_32 (operand0, operand1, false);
14601 }
14602 else
14603 {
14604 rtx op0, op1;
14605
14606 if (optimize_insn_for_size_p ())
14607 FAIL;
14608
14609 op0 = gen_reg_rtx (XFmode);
14610 op1 = gen_reg_rtx (XFmode);
14611 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14612 emit_insn (gen_frndintxf2_ceil (op0, op1));
14613
14614 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14615 }
14616 DONE;
14617 })
14618
14619 (define_insn_and_split "*fist<mode>2_ceil_1"
14620 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14621 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14622 UNSPEC_FIST_CEIL))
14623 (clobber (reg:CC FLAGS_REG))]
14624 "TARGET_USE_FANCY_MATH_387
14625 && flag_unsafe_math_optimizations
14626 && can_create_pseudo_p ()"
14627 "#"
14628 "&& 1"
14629 [(const_int 0)]
14630 {
14631 ix86_optimize_mode_switching[I387_CEIL] = 1;
14632
14633 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14634 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14635 if (memory_operand (operands[0], VOIDmode))
14636 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14637 operands[2], operands[3]));
14638 else
14639 {
14640 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14641 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14642 operands[2], operands[3],
14643 operands[4]));
14644 }
14645 DONE;
14646 }
14647 [(set_attr "type" "fistp")
14648 (set_attr "i387_cw" "ceil")
14649 (set_attr "mode" "<MODE>")])
14650
14651 (define_insn "fistdi2_ceil"
14652 [(set (match_operand:DI 0 "memory_operand" "=m")
14653 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14654 UNSPEC_FIST_CEIL))
14655 (use (match_operand:HI 2 "memory_operand" "m"))
14656 (use (match_operand:HI 3 "memory_operand" "m"))
14657 (clobber (match_scratch:XF 4 "=&1f"))]
14658 "TARGET_USE_FANCY_MATH_387
14659 && flag_unsafe_math_optimizations"
14660 "* return output_fix_trunc (insn, operands, 0);"
14661 [(set_attr "type" "fistp")
14662 (set_attr "i387_cw" "ceil")
14663 (set_attr "mode" "DI")])
14664
14665 (define_insn "fistdi2_ceil_with_temp"
14666 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14667 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14668 UNSPEC_FIST_CEIL))
14669 (use (match_operand:HI 2 "memory_operand" "m,m"))
14670 (use (match_operand:HI 3 "memory_operand" "m,m"))
14671 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14672 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14673 "TARGET_USE_FANCY_MATH_387
14674 && flag_unsafe_math_optimizations"
14675 "#"
14676 [(set_attr "type" "fistp")
14677 (set_attr "i387_cw" "ceil")
14678 (set_attr "mode" "DI")])
14679
14680 (define_split
14681 [(set (match_operand:DI 0 "register_operand" "")
14682 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14683 UNSPEC_FIST_CEIL))
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 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14690 (use (match_dup 2))
14691 (use (match_dup 3))
14692 (clobber (match_dup 5))])
14693 (set (match_dup 0) (match_dup 4))])
14694
14695 (define_split
14696 [(set (match_operand:DI 0 "memory_operand" "")
14697 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14698 UNSPEC_FIST_CEIL))
14699 (use (match_operand:HI 2 "memory_operand" ""))
14700 (use (match_operand:HI 3 "memory_operand" ""))
14701 (clobber (match_operand:DI 4 "memory_operand" ""))
14702 (clobber (match_scratch 5 ""))]
14703 "reload_completed"
14704 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14705 (use (match_dup 2))
14706 (use (match_dup 3))
14707 (clobber (match_dup 5))])])
14708
14709 (define_insn "fist<mode>2_ceil"
14710 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14711 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14712 UNSPEC_FIST_CEIL))
14713 (use (match_operand:HI 2 "memory_operand" "m"))
14714 (use (match_operand:HI 3 "memory_operand" "m"))]
14715 "TARGET_USE_FANCY_MATH_387
14716 && flag_unsafe_math_optimizations"
14717 "* return output_fix_trunc (insn, operands, 0);"
14718 [(set_attr "type" "fistp")
14719 (set_attr "i387_cw" "ceil")
14720 (set_attr "mode" "<MODE>")])
14721
14722 (define_insn "fist<mode>2_ceil_with_temp"
14723 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14724 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14725 UNSPEC_FIST_CEIL))
14726 (use (match_operand:HI 2 "memory_operand" "m,m"))
14727 (use (match_operand:HI 3 "memory_operand" "m,m"))
14728 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14729 "TARGET_USE_FANCY_MATH_387
14730 && flag_unsafe_math_optimizations"
14731 "#"
14732 [(set_attr "type" "fistp")
14733 (set_attr "i387_cw" "ceil")
14734 (set_attr "mode" "<MODE>")])
14735
14736 (define_split
14737 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14738 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14739 UNSPEC_FIST_CEIL))
14740 (use (match_operand:HI 2 "memory_operand" ""))
14741 (use (match_operand:HI 3 "memory_operand" ""))
14742 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14743 "reload_completed"
14744 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14745 UNSPEC_FIST_CEIL))
14746 (use (match_dup 2))
14747 (use (match_dup 3))])
14748 (set (match_dup 0) (match_dup 4))])
14749
14750 (define_split
14751 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14752 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14753 UNSPEC_FIST_CEIL))
14754 (use (match_operand:HI 2 "memory_operand" ""))
14755 (use (match_operand:HI 3 "memory_operand" ""))
14756 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14757 "reload_completed"
14758 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14759 UNSPEC_FIST_CEIL))
14760 (use (match_dup 2))
14761 (use (match_dup 3))])])
14762
14763 (define_expand "lceilxf<mode>2"
14764 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14765 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14766 UNSPEC_FIST_CEIL))
14767 (clobber (reg:CC FLAGS_REG))])]
14768 "TARGET_USE_FANCY_MATH_387
14769 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14770 && flag_unsafe_math_optimizations")
14771
14772 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14773 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14774 (match_operand:MODEF 1 "register_operand" "")]
14775 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14776 && !flag_trapping_math"
14777 {
14778 ix86_expand_lfloorceil (operand0, operand1, false);
14779 DONE;
14780 })
14781
14782 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14783 (define_insn_and_split "frndintxf2_trunc"
14784 [(set (match_operand:XF 0 "register_operand" "")
14785 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14786 UNSPEC_FRNDINT_TRUNC))
14787 (clobber (reg:CC FLAGS_REG))]
14788 "TARGET_USE_FANCY_MATH_387
14789 && flag_unsafe_math_optimizations
14790 && can_create_pseudo_p ()"
14791 "#"
14792 "&& 1"
14793 [(const_int 0)]
14794 {
14795 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14796
14797 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14798 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14799
14800 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14801 operands[2], operands[3]));
14802 DONE;
14803 }
14804 [(set_attr "type" "frndint")
14805 (set_attr "i387_cw" "trunc")
14806 (set_attr "mode" "XF")])
14807
14808 (define_insn "frndintxf2_trunc_i387"
14809 [(set (match_operand:XF 0 "register_operand" "=f")
14810 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14811 UNSPEC_FRNDINT_TRUNC))
14812 (use (match_operand:HI 2 "memory_operand" "m"))
14813 (use (match_operand:HI 3 "memory_operand" "m"))]
14814 "TARGET_USE_FANCY_MATH_387
14815 && flag_unsafe_math_optimizations"
14816 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14817 [(set_attr "type" "frndint")
14818 (set_attr "i387_cw" "trunc")
14819 (set_attr "mode" "XF")])
14820
14821 (define_expand "btruncxf2"
14822 [(use (match_operand:XF 0 "register_operand" ""))
14823 (use (match_operand:XF 1 "register_operand" ""))]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations"
14826 {
14827 if (optimize_insn_for_size_p ())
14828 FAIL;
14829 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14830 DONE;
14831 })
14832
14833 (define_expand "btrunc<mode>2"
14834 [(use (match_operand:MODEF 0 "register_operand" ""))
14835 (use (match_operand:MODEF 1 "register_operand" ""))]
14836 "(TARGET_USE_FANCY_MATH_387
14837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14838 || TARGET_MIX_SSE_I387)
14839 && flag_unsafe_math_optimizations)
14840 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14841 && !flag_trapping_math)"
14842 {
14843 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844 && !flag_trapping_math
14845 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14846 {
14847 if (TARGET_ROUND)
14848 emit_insn (gen_sse4_1_round<mode>2
14849 (operands[0], operands[1], GEN_INT (0x03)));
14850 else if (optimize_insn_for_size_p ())
14851 FAIL;
14852 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14853 ix86_expand_trunc (operand0, operand1);
14854 else
14855 ix86_expand_truncdf_32 (operand0, operand1);
14856 }
14857 else
14858 {
14859 rtx op0, op1;
14860
14861 if (optimize_insn_for_size_p ())
14862 FAIL;
14863
14864 op0 = gen_reg_rtx (XFmode);
14865 op1 = gen_reg_rtx (XFmode);
14866 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14867 emit_insn (gen_frndintxf2_trunc (op0, op1));
14868
14869 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14870 }
14871 DONE;
14872 })
14873
14874 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14875 (define_insn_and_split "frndintxf2_mask_pm"
14876 [(set (match_operand:XF 0 "register_operand" "")
14877 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14878 UNSPEC_FRNDINT_MASK_PM))
14879 (clobber (reg:CC FLAGS_REG))]
14880 "TARGET_USE_FANCY_MATH_387
14881 && flag_unsafe_math_optimizations
14882 && can_create_pseudo_p ()"
14883 "#"
14884 "&& 1"
14885 [(const_int 0)]
14886 {
14887 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14888
14889 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14890 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14891
14892 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14893 operands[2], operands[3]));
14894 DONE;
14895 }
14896 [(set_attr "type" "frndint")
14897 (set_attr "i387_cw" "mask_pm")
14898 (set_attr "mode" "XF")])
14899
14900 (define_insn "frndintxf2_mask_pm_i387"
14901 [(set (match_operand:XF 0 "register_operand" "=f")
14902 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14903 UNSPEC_FRNDINT_MASK_PM))
14904 (use (match_operand:HI 2 "memory_operand" "m"))
14905 (use (match_operand:HI 3 "memory_operand" "m"))]
14906 "TARGET_USE_FANCY_MATH_387
14907 && flag_unsafe_math_optimizations"
14908 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14909 [(set_attr "type" "frndint")
14910 (set_attr "i387_cw" "mask_pm")
14911 (set_attr "mode" "XF")])
14912
14913 (define_expand "nearbyintxf2"
14914 [(use (match_operand:XF 0 "register_operand" ""))
14915 (use (match_operand:XF 1 "register_operand" ""))]
14916 "TARGET_USE_FANCY_MATH_387
14917 && flag_unsafe_math_optimizations"
14918 {
14919 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14920 DONE;
14921 })
14922
14923 (define_expand "nearbyint<mode>2"
14924 [(use (match_operand:MODEF 0 "register_operand" ""))
14925 (use (match_operand:MODEF 1 "register_operand" ""))]
14926 "TARGET_USE_FANCY_MATH_387
14927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14928 || TARGET_MIX_SSE_I387)
14929 && flag_unsafe_math_optimizations"
14930 {
14931 rtx op0 = gen_reg_rtx (XFmode);
14932 rtx op1 = gen_reg_rtx (XFmode);
14933
14934 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14935 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14936
14937 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14938 DONE;
14939 })
14940
14941 (define_insn "fxam<mode>2_i387"
14942 [(set (match_operand:HI 0 "register_operand" "=a")
14943 (unspec:HI
14944 [(match_operand:X87MODEF 1 "register_operand" "f")]
14945 UNSPEC_FXAM))]
14946 "TARGET_USE_FANCY_MATH_387"
14947 "fxam\n\tfnstsw\t%0"
14948 [(set_attr "type" "multi")
14949 (set_attr "length" "4")
14950 (set_attr "unit" "i387")
14951 (set_attr "mode" "<MODE>")])
14952
14953 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14954 [(set (match_operand:HI 0 "register_operand" "")
14955 (unspec:HI
14956 [(match_operand:MODEF 1 "memory_operand" "")]
14957 UNSPEC_FXAM_MEM))]
14958 "TARGET_USE_FANCY_MATH_387
14959 && can_create_pseudo_p ()"
14960 "#"
14961 "&& 1"
14962 [(set (match_dup 2)(match_dup 1))
14963 (set (match_dup 0)
14964 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14965 {
14966 operands[2] = gen_reg_rtx (<MODE>mode);
14967
14968 MEM_VOLATILE_P (operands[1]) = 1;
14969 }
14970 [(set_attr "type" "multi")
14971 (set_attr "unit" "i387")
14972 (set_attr "mode" "<MODE>")])
14973
14974 (define_expand "isinfxf2"
14975 [(use (match_operand:SI 0 "register_operand" ""))
14976 (use (match_operand:XF 1 "register_operand" ""))]
14977 "TARGET_USE_FANCY_MATH_387
14978 && TARGET_C99_FUNCTIONS"
14979 {
14980 rtx mask = GEN_INT (0x45);
14981 rtx val = GEN_INT (0x05);
14982
14983 rtx cond;
14984
14985 rtx scratch = gen_reg_rtx (HImode);
14986 rtx res = gen_reg_rtx (QImode);
14987
14988 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14989
14990 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14991 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14992 cond = gen_rtx_fmt_ee (EQ, QImode,
14993 gen_rtx_REG (CCmode, FLAGS_REG),
14994 const0_rtx);
14995 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14996 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14997 DONE;
14998 })
14999
15000 (define_expand "isinf<mode>2"
15001 [(use (match_operand:SI 0 "register_operand" ""))
15002 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15003 "TARGET_USE_FANCY_MATH_387
15004 && TARGET_C99_FUNCTIONS
15005 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15006 {
15007 rtx mask = GEN_INT (0x45);
15008 rtx val = GEN_INT (0x05);
15009
15010 rtx cond;
15011
15012 rtx scratch = gen_reg_rtx (HImode);
15013 rtx res = gen_reg_rtx (QImode);
15014
15015 /* Remove excess precision by forcing value through memory. */
15016 if (memory_operand (operands[1], VOIDmode))
15017 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15018 else
15019 {
15020 enum ix86_stack_slot slot = (virtuals_instantiated
15021 ? SLOT_TEMP
15022 : SLOT_VIRTUAL);
15023 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15024
15025 emit_move_insn (temp, operands[1]);
15026 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15027 }
15028
15029 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15030 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15031 cond = gen_rtx_fmt_ee (EQ, QImode,
15032 gen_rtx_REG (CCmode, FLAGS_REG),
15033 const0_rtx);
15034 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15035 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15036 DONE;
15037 })
15038
15039 (define_expand "signbitxf2"
15040 [(use (match_operand:SI 0 "register_operand" ""))
15041 (use (match_operand:XF 1 "register_operand" ""))]
15042 "TARGET_USE_FANCY_MATH_387"
15043 {
15044 rtx scratch = gen_reg_rtx (HImode);
15045
15046 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15047 emit_insn (gen_andsi3 (operands[0],
15048 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15049 DONE;
15050 })
15051
15052 (define_insn "movmsk_df"
15053 [(set (match_operand:SI 0 "register_operand" "=r")
15054 (unspec:SI
15055 [(match_operand:DF 1 "register_operand" "x")]
15056 UNSPEC_MOVMSK))]
15057 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15058 "%vmovmskpd\t{%1, %0|%0, %1}"
15059 [(set_attr "type" "ssemov")
15060 (set_attr "prefix" "maybe_vex")
15061 (set_attr "mode" "DF")])
15062
15063 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15064 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15065 (define_expand "signbitdf2"
15066 [(use (match_operand:SI 0 "register_operand" ""))
15067 (use (match_operand:DF 1 "register_operand" ""))]
15068 "TARGET_USE_FANCY_MATH_387
15069 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15070 {
15071 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15072 {
15073 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15074 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15075 }
15076 else
15077 {
15078 rtx scratch = gen_reg_rtx (HImode);
15079
15080 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15081 emit_insn (gen_andsi3 (operands[0],
15082 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15083 }
15084 DONE;
15085 })
15086
15087 (define_expand "signbitsf2"
15088 [(use (match_operand:SI 0 "register_operand" ""))
15089 (use (match_operand:SF 1 "register_operand" ""))]
15090 "TARGET_USE_FANCY_MATH_387
15091 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15092 {
15093 rtx scratch = gen_reg_rtx (HImode);
15094
15095 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15096 emit_insn (gen_andsi3 (operands[0],
15097 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15098 DONE;
15099 })
15100 \f
15101 ;; Block operation instructions
15102
15103 (define_insn "cld"
15104 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15105 ""
15106 "cld"
15107 [(set_attr "length" "1")
15108 (set_attr "length_immediate" "0")
15109 (set_attr "modrm" "0")])
15110
15111 (define_expand "movmemsi"
15112 [(use (match_operand:BLK 0 "memory_operand" ""))
15113 (use (match_operand:BLK 1 "memory_operand" ""))
15114 (use (match_operand:SI 2 "nonmemory_operand" ""))
15115 (use (match_operand:SI 3 "const_int_operand" ""))
15116 (use (match_operand:SI 4 "const_int_operand" ""))
15117 (use (match_operand:SI 5 "const_int_operand" ""))]
15118 ""
15119 {
15120 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15121 operands[4], operands[5]))
15122 DONE;
15123 else
15124 FAIL;
15125 })
15126
15127 (define_expand "movmemdi"
15128 [(use (match_operand:BLK 0 "memory_operand" ""))
15129 (use (match_operand:BLK 1 "memory_operand" ""))
15130 (use (match_operand:DI 2 "nonmemory_operand" ""))
15131 (use (match_operand:DI 3 "const_int_operand" ""))
15132 (use (match_operand:SI 4 "const_int_operand" ""))
15133 (use (match_operand:SI 5 "const_int_operand" ""))]
15134 "TARGET_64BIT"
15135 {
15136 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15137 operands[4], operands[5]))
15138 DONE;
15139 else
15140 FAIL;
15141 })
15142
15143 ;; Most CPUs don't like single string operations
15144 ;; Handle this case here to simplify previous expander.
15145
15146 (define_expand "strmov"
15147 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15148 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15149 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15150 (clobber (reg:CC FLAGS_REG))])
15151 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15152 (clobber (reg:CC FLAGS_REG))])]
15153 ""
15154 {
15155 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15156
15157 /* If .md ever supports :P for Pmode, these can be directly
15158 in the pattern above. */
15159 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15160 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15161
15162 /* Can't use this if the user has appropriated esi or edi. */
15163 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15164 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15165 {
15166 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15167 operands[2], operands[3],
15168 operands[5], operands[6]));
15169 DONE;
15170 }
15171
15172 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15173 })
15174
15175 (define_expand "strmov_singleop"
15176 [(parallel [(set (match_operand 1 "memory_operand" "")
15177 (match_operand 3 "memory_operand" ""))
15178 (set (match_operand 0 "register_operand" "")
15179 (match_operand 4 "" ""))
15180 (set (match_operand 2 "register_operand" "")
15181 (match_operand 5 "" ""))])]
15182 ""
15183 "ix86_current_function_needs_cld = 1;")
15184
15185 (define_insn "*strmovdi_rex_1"
15186 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15187 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15188 (set (match_operand:DI 0 "register_operand" "=D")
15189 (plus:DI (match_dup 2)
15190 (const_int 8)))
15191 (set (match_operand:DI 1 "register_operand" "=S")
15192 (plus:DI (match_dup 3)
15193 (const_int 8)))]
15194 "TARGET_64BIT"
15195 "movsq"
15196 [(set_attr "type" "str")
15197 (set_attr "mode" "DI")
15198 (set_attr "memory" "both")])
15199
15200 (define_insn "*strmovsi_1"
15201 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15202 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15203 (set (match_operand:SI 0 "register_operand" "=D")
15204 (plus:SI (match_dup 2)
15205 (const_int 4)))
15206 (set (match_operand:SI 1 "register_operand" "=S")
15207 (plus:SI (match_dup 3)
15208 (const_int 4)))]
15209 "!TARGET_64BIT"
15210 "movs{l|d}"
15211 [(set_attr "type" "str")
15212 (set_attr "mode" "SI")
15213 (set_attr "memory" "both")])
15214
15215 (define_insn "*strmovsi_rex_1"
15216 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15217 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15218 (set (match_operand:DI 0 "register_operand" "=D")
15219 (plus:DI (match_dup 2)
15220 (const_int 4)))
15221 (set (match_operand:DI 1 "register_operand" "=S")
15222 (plus:DI (match_dup 3)
15223 (const_int 4)))]
15224 "TARGET_64BIT"
15225 "movs{l|d}"
15226 [(set_attr "type" "str")
15227 (set_attr "mode" "SI")
15228 (set_attr "memory" "both")])
15229
15230 (define_insn "*strmovhi_1"
15231 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15232 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15233 (set (match_operand:SI 0 "register_operand" "=D")
15234 (plus:SI (match_dup 2)
15235 (const_int 2)))
15236 (set (match_operand:SI 1 "register_operand" "=S")
15237 (plus:SI (match_dup 3)
15238 (const_int 2)))]
15239 "!TARGET_64BIT"
15240 "movsw"
15241 [(set_attr "type" "str")
15242 (set_attr "memory" "both")
15243 (set_attr "mode" "HI")])
15244
15245 (define_insn "*strmovhi_rex_1"
15246 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15247 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15248 (set (match_operand:DI 0 "register_operand" "=D")
15249 (plus:DI (match_dup 2)
15250 (const_int 2)))
15251 (set (match_operand:DI 1 "register_operand" "=S")
15252 (plus:DI (match_dup 3)
15253 (const_int 2)))]
15254 "TARGET_64BIT"
15255 "movsw"
15256 [(set_attr "type" "str")
15257 (set_attr "memory" "both")
15258 (set_attr "mode" "HI")])
15259
15260 (define_insn "*strmovqi_1"
15261 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15262 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15263 (set (match_operand:SI 0 "register_operand" "=D")
15264 (plus:SI (match_dup 2)
15265 (const_int 1)))
15266 (set (match_operand:SI 1 "register_operand" "=S")
15267 (plus:SI (match_dup 3)
15268 (const_int 1)))]
15269 "!TARGET_64BIT"
15270 "movsb"
15271 [(set_attr "type" "str")
15272 (set_attr "memory" "both")
15273 (set_attr "mode" "QI")])
15274
15275 (define_insn "*strmovqi_rex_1"
15276 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15277 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15278 (set (match_operand:DI 0 "register_operand" "=D")
15279 (plus:DI (match_dup 2)
15280 (const_int 1)))
15281 (set (match_operand:DI 1 "register_operand" "=S")
15282 (plus:DI (match_dup 3)
15283 (const_int 1)))]
15284 "TARGET_64BIT"
15285 "movsb"
15286 [(set_attr "type" "str")
15287 (set_attr "memory" "both")
15288 (set_attr "prefix_rex" "0")
15289 (set_attr "mode" "QI")])
15290
15291 (define_expand "rep_mov"
15292 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15293 (set (match_operand 0 "register_operand" "")
15294 (match_operand 5 "" ""))
15295 (set (match_operand 2 "register_operand" "")
15296 (match_operand 6 "" ""))
15297 (set (match_operand 1 "memory_operand" "")
15298 (match_operand 3 "memory_operand" ""))
15299 (use (match_dup 4))])]
15300 ""
15301 "ix86_current_function_needs_cld = 1;")
15302
15303 (define_insn "*rep_movdi_rex64"
15304 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15305 (set (match_operand:DI 0 "register_operand" "=D")
15306 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15307 (const_int 3))
15308 (match_operand:DI 3 "register_operand" "0")))
15309 (set (match_operand:DI 1 "register_operand" "=S")
15310 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15311 (match_operand:DI 4 "register_operand" "1")))
15312 (set (mem:BLK (match_dup 3))
15313 (mem:BLK (match_dup 4)))
15314 (use (match_dup 5))]
15315 "TARGET_64BIT"
15316 "rep{%;} movsq"
15317 [(set_attr "type" "str")
15318 (set_attr "prefix_rep" "1")
15319 (set_attr "memory" "both")
15320 (set_attr "mode" "DI")])
15321
15322 (define_insn "*rep_movsi"
15323 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15324 (set (match_operand:SI 0 "register_operand" "=D")
15325 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15326 (const_int 2))
15327 (match_operand:SI 3 "register_operand" "0")))
15328 (set (match_operand:SI 1 "register_operand" "=S")
15329 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15330 (match_operand:SI 4 "register_operand" "1")))
15331 (set (mem:BLK (match_dup 3))
15332 (mem:BLK (match_dup 4)))
15333 (use (match_dup 5))]
15334 "!TARGET_64BIT"
15335 "rep{%;} movs{l|d}"
15336 [(set_attr "type" "str")
15337 (set_attr "prefix_rep" "1")
15338 (set_attr "memory" "both")
15339 (set_attr "mode" "SI")])
15340
15341 (define_insn "*rep_movsi_rex64"
15342 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15343 (set (match_operand:DI 0 "register_operand" "=D")
15344 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15345 (const_int 2))
15346 (match_operand:DI 3 "register_operand" "0")))
15347 (set (match_operand:DI 1 "register_operand" "=S")
15348 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15349 (match_operand:DI 4 "register_operand" "1")))
15350 (set (mem:BLK (match_dup 3))
15351 (mem:BLK (match_dup 4)))
15352 (use (match_dup 5))]
15353 "TARGET_64BIT"
15354 "rep{%;} movs{l|d}"
15355 [(set_attr "type" "str")
15356 (set_attr "prefix_rep" "1")
15357 (set_attr "memory" "both")
15358 (set_attr "mode" "SI")])
15359
15360 (define_insn "*rep_movqi"
15361 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15362 (set (match_operand:SI 0 "register_operand" "=D")
15363 (plus:SI (match_operand:SI 3 "register_operand" "0")
15364 (match_operand:SI 5 "register_operand" "2")))
15365 (set (match_operand:SI 1 "register_operand" "=S")
15366 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15367 (set (mem:BLK (match_dup 3))
15368 (mem:BLK (match_dup 4)))
15369 (use (match_dup 5))]
15370 "!TARGET_64BIT"
15371 "rep{%;} movsb"
15372 [(set_attr "type" "str")
15373 (set_attr "prefix_rep" "1")
15374 (set_attr "memory" "both")
15375 (set_attr "mode" "SI")])
15376
15377 (define_insn "*rep_movqi_rex64"
15378 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15379 (set (match_operand:DI 0 "register_operand" "=D")
15380 (plus:DI (match_operand:DI 3 "register_operand" "0")
15381 (match_operand:DI 5 "register_operand" "2")))
15382 (set (match_operand:DI 1 "register_operand" "=S")
15383 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15384 (set (mem:BLK (match_dup 3))
15385 (mem:BLK (match_dup 4)))
15386 (use (match_dup 5))]
15387 "TARGET_64BIT"
15388 "rep{%;} movsb"
15389 [(set_attr "type" "str")
15390 (set_attr "prefix_rep" "1")
15391 (set_attr "memory" "both")
15392 (set_attr "mode" "SI")])
15393
15394 (define_expand "setmemsi"
15395 [(use (match_operand:BLK 0 "memory_operand" ""))
15396 (use (match_operand:SI 1 "nonmemory_operand" ""))
15397 (use (match_operand 2 "const_int_operand" ""))
15398 (use (match_operand 3 "const_int_operand" ""))
15399 (use (match_operand:SI 4 "const_int_operand" ""))
15400 (use (match_operand:SI 5 "const_int_operand" ""))]
15401 ""
15402 {
15403 if (ix86_expand_setmem (operands[0], operands[1],
15404 operands[2], operands[3],
15405 operands[4], operands[5]))
15406 DONE;
15407 else
15408 FAIL;
15409 })
15410
15411 (define_expand "setmemdi"
15412 [(use (match_operand:BLK 0 "memory_operand" ""))
15413 (use (match_operand:DI 1 "nonmemory_operand" ""))
15414 (use (match_operand 2 "const_int_operand" ""))
15415 (use (match_operand 3 "const_int_operand" ""))
15416 (use (match_operand 4 "const_int_operand" ""))
15417 (use (match_operand 5 "const_int_operand" ""))]
15418 "TARGET_64BIT"
15419 {
15420 if (ix86_expand_setmem (operands[0], operands[1],
15421 operands[2], operands[3],
15422 operands[4], operands[5]))
15423 DONE;
15424 else
15425 FAIL;
15426 })
15427
15428 ;; Most CPUs don't like single string operations
15429 ;; Handle this case here to simplify previous expander.
15430
15431 (define_expand "strset"
15432 [(set (match_operand 1 "memory_operand" "")
15433 (match_operand 2 "register_operand" ""))
15434 (parallel [(set (match_operand 0 "register_operand" "")
15435 (match_dup 3))
15436 (clobber (reg:CC FLAGS_REG))])]
15437 ""
15438 {
15439 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15440 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15441
15442 /* If .md ever supports :P for Pmode, this can be directly
15443 in the pattern above. */
15444 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15445 GEN_INT (GET_MODE_SIZE (GET_MODE
15446 (operands[2]))));
15447 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15448 {
15449 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15450 operands[3]));
15451 DONE;
15452 }
15453 })
15454
15455 (define_expand "strset_singleop"
15456 [(parallel [(set (match_operand 1 "memory_operand" "")
15457 (match_operand 2 "register_operand" ""))
15458 (set (match_operand 0 "register_operand" "")
15459 (match_operand 3 "" ""))])]
15460 ""
15461 "ix86_current_function_needs_cld = 1;")
15462
15463 (define_insn "*strsetdi_rex_1"
15464 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15465 (match_operand:DI 2 "register_operand" "a"))
15466 (set (match_operand:DI 0 "register_operand" "=D")
15467 (plus:DI (match_dup 1)
15468 (const_int 8)))]
15469 "TARGET_64BIT"
15470 "stosq"
15471 [(set_attr "type" "str")
15472 (set_attr "memory" "store")
15473 (set_attr "mode" "DI")])
15474
15475 (define_insn "*strsetsi_1"
15476 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15477 (match_operand:SI 2 "register_operand" "a"))
15478 (set (match_operand:SI 0 "register_operand" "=D")
15479 (plus:SI (match_dup 1)
15480 (const_int 4)))]
15481 "!TARGET_64BIT"
15482 "stos{l|d}"
15483 [(set_attr "type" "str")
15484 (set_attr "memory" "store")
15485 (set_attr "mode" "SI")])
15486
15487 (define_insn "*strsetsi_rex_1"
15488 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15489 (match_operand:SI 2 "register_operand" "a"))
15490 (set (match_operand:DI 0 "register_operand" "=D")
15491 (plus:DI (match_dup 1)
15492 (const_int 4)))]
15493 "TARGET_64BIT"
15494 "stos{l|d}"
15495 [(set_attr "type" "str")
15496 (set_attr "memory" "store")
15497 (set_attr "mode" "SI")])
15498
15499 (define_insn "*strsethi_1"
15500 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15501 (match_operand:HI 2 "register_operand" "a"))
15502 (set (match_operand:SI 0 "register_operand" "=D")
15503 (plus:SI (match_dup 1)
15504 (const_int 2)))]
15505 "!TARGET_64BIT"
15506 "stosw"
15507 [(set_attr "type" "str")
15508 (set_attr "memory" "store")
15509 (set_attr "mode" "HI")])
15510
15511 (define_insn "*strsethi_rex_1"
15512 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15513 (match_operand:HI 2 "register_operand" "a"))
15514 (set (match_operand:DI 0 "register_operand" "=D")
15515 (plus:DI (match_dup 1)
15516 (const_int 2)))]
15517 "TARGET_64BIT"
15518 "stosw"
15519 [(set_attr "type" "str")
15520 (set_attr "memory" "store")
15521 (set_attr "mode" "HI")])
15522
15523 (define_insn "*strsetqi_1"
15524 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15525 (match_operand:QI 2 "register_operand" "a"))
15526 (set (match_operand:SI 0 "register_operand" "=D")
15527 (plus:SI (match_dup 1)
15528 (const_int 1)))]
15529 "!TARGET_64BIT"
15530 "stosb"
15531 [(set_attr "type" "str")
15532 (set_attr "memory" "store")
15533 (set_attr "mode" "QI")])
15534
15535 (define_insn "*strsetqi_rex_1"
15536 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15537 (match_operand:QI 2 "register_operand" "a"))
15538 (set (match_operand:DI 0 "register_operand" "=D")
15539 (plus:DI (match_dup 1)
15540 (const_int 1)))]
15541 "TARGET_64BIT"
15542 "stosb"
15543 [(set_attr "type" "str")
15544 (set_attr "memory" "store")
15545 (set_attr "prefix_rex" "0")
15546 (set_attr "mode" "QI")])
15547
15548 (define_expand "rep_stos"
15549 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15550 (set (match_operand 0 "register_operand" "")
15551 (match_operand 4 "" ""))
15552 (set (match_operand 2 "memory_operand" "") (const_int 0))
15553 (use (match_operand 3 "register_operand" ""))
15554 (use (match_dup 1))])]
15555 ""
15556 "ix86_current_function_needs_cld = 1;")
15557
15558 (define_insn "*rep_stosdi_rex64"
15559 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15560 (set (match_operand:DI 0 "register_operand" "=D")
15561 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15562 (const_int 3))
15563 (match_operand:DI 3 "register_operand" "0")))
15564 (set (mem:BLK (match_dup 3))
15565 (const_int 0))
15566 (use (match_operand:DI 2 "register_operand" "a"))
15567 (use (match_dup 4))]
15568 "TARGET_64BIT"
15569 "rep{%;} stosq"
15570 [(set_attr "type" "str")
15571 (set_attr "prefix_rep" "1")
15572 (set_attr "memory" "store")
15573 (set_attr "mode" "DI")])
15574
15575 (define_insn "*rep_stossi"
15576 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15577 (set (match_operand:SI 0 "register_operand" "=D")
15578 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15579 (const_int 2))
15580 (match_operand:SI 3 "register_operand" "0")))
15581 (set (mem:BLK (match_dup 3))
15582 (const_int 0))
15583 (use (match_operand:SI 2 "register_operand" "a"))
15584 (use (match_dup 4))]
15585 "!TARGET_64BIT"
15586 "rep{%;} stos{l|d}"
15587 [(set_attr "type" "str")
15588 (set_attr "prefix_rep" "1")
15589 (set_attr "memory" "store")
15590 (set_attr "mode" "SI")])
15591
15592 (define_insn "*rep_stossi_rex64"
15593 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15594 (set (match_operand:DI 0 "register_operand" "=D")
15595 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15596 (const_int 2))
15597 (match_operand:DI 3 "register_operand" "0")))
15598 (set (mem:BLK (match_dup 3))
15599 (const_int 0))
15600 (use (match_operand:SI 2 "register_operand" "a"))
15601 (use (match_dup 4))]
15602 "TARGET_64BIT"
15603 "rep{%;} stos{l|d}"
15604 [(set_attr "type" "str")
15605 (set_attr "prefix_rep" "1")
15606 (set_attr "memory" "store")
15607 (set_attr "mode" "SI")])
15608
15609 (define_insn "*rep_stosqi"
15610 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15611 (set (match_operand:SI 0 "register_operand" "=D")
15612 (plus:SI (match_operand:SI 3 "register_operand" "0")
15613 (match_operand:SI 4 "register_operand" "1")))
15614 (set (mem:BLK (match_dup 3))
15615 (const_int 0))
15616 (use (match_operand:QI 2 "register_operand" "a"))
15617 (use (match_dup 4))]
15618 "!TARGET_64BIT"
15619 "rep{%;} stosb"
15620 [(set_attr "type" "str")
15621 (set_attr "prefix_rep" "1")
15622 (set_attr "memory" "store")
15623 (set_attr "mode" "QI")])
15624
15625 (define_insn "*rep_stosqi_rex64"
15626 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15627 (set (match_operand:DI 0 "register_operand" "=D")
15628 (plus:DI (match_operand:DI 3 "register_operand" "0")
15629 (match_operand:DI 4 "register_operand" "1")))
15630 (set (mem:BLK (match_dup 3))
15631 (const_int 0))
15632 (use (match_operand:QI 2 "register_operand" "a"))
15633 (use (match_dup 4))]
15634 "TARGET_64BIT"
15635 "rep{%;} stosb"
15636 [(set_attr "type" "str")
15637 (set_attr "prefix_rep" "1")
15638 (set_attr "memory" "store")
15639 (set_attr "prefix_rex" "0")
15640 (set_attr "mode" "QI")])
15641
15642 (define_expand "cmpstrnsi"
15643 [(set (match_operand:SI 0 "register_operand" "")
15644 (compare:SI (match_operand:BLK 1 "general_operand" "")
15645 (match_operand:BLK 2 "general_operand" "")))
15646 (use (match_operand 3 "general_operand" ""))
15647 (use (match_operand 4 "immediate_operand" ""))]
15648 ""
15649 {
15650 rtx addr1, addr2, out, outlow, count, countreg, align;
15651
15652 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15653 FAIL;
15654
15655 /* Can't use this if the user has appropriated esi or edi. */
15656 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15657 FAIL;
15658
15659 out = operands[0];
15660 if (!REG_P (out))
15661 out = gen_reg_rtx (SImode);
15662
15663 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15664 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15665 if (addr1 != XEXP (operands[1], 0))
15666 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15667 if (addr2 != XEXP (operands[2], 0))
15668 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15669
15670 count = operands[3];
15671 countreg = ix86_zero_extend_to_Pmode (count);
15672
15673 /* %%% Iff we are testing strict equality, we can use known alignment
15674 to good advantage. This may be possible with combine, particularly
15675 once cc0 is dead. */
15676 align = operands[4];
15677
15678 if (CONST_INT_P (count))
15679 {
15680 if (INTVAL (count) == 0)
15681 {
15682 emit_move_insn (operands[0], const0_rtx);
15683 DONE;
15684 }
15685 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15686 operands[1], operands[2]));
15687 }
15688 else
15689 {
15690 rtx (*gen_cmp) (rtx, rtx);
15691
15692 gen_cmp = (TARGET_64BIT
15693 ? gen_cmpdi_1 : gen_cmpsi_1);
15694
15695 emit_insn (gen_cmp (countreg, countreg));
15696 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15697 operands[1], operands[2]));
15698 }
15699
15700 outlow = gen_lowpart (QImode, out);
15701 emit_insn (gen_cmpintqi (outlow));
15702 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15703
15704 if (operands[0] != out)
15705 emit_move_insn (operands[0], out);
15706
15707 DONE;
15708 })
15709
15710 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15711
15712 (define_expand "cmpintqi"
15713 [(set (match_dup 1)
15714 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15715 (set (match_dup 2)
15716 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15717 (parallel [(set (match_operand:QI 0 "register_operand" "")
15718 (minus:QI (match_dup 1)
15719 (match_dup 2)))
15720 (clobber (reg:CC FLAGS_REG))])]
15721 ""
15722 "operands[1] = gen_reg_rtx (QImode);
15723 operands[2] = gen_reg_rtx (QImode);")
15724
15725 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15726 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15727
15728 (define_expand "cmpstrnqi_nz_1"
15729 [(parallel [(set (reg:CC FLAGS_REG)
15730 (compare:CC (match_operand 4 "memory_operand" "")
15731 (match_operand 5 "memory_operand" "")))
15732 (use (match_operand 2 "register_operand" ""))
15733 (use (match_operand:SI 3 "immediate_operand" ""))
15734 (clobber (match_operand 0 "register_operand" ""))
15735 (clobber (match_operand 1 "register_operand" ""))
15736 (clobber (match_dup 2))])]
15737 ""
15738 "ix86_current_function_needs_cld = 1;")
15739
15740 (define_insn "*cmpstrnqi_nz_1"
15741 [(set (reg:CC FLAGS_REG)
15742 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15743 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15744 (use (match_operand:SI 6 "register_operand" "2"))
15745 (use (match_operand:SI 3 "immediate_operand" "i"))
15746 (clobber (match_operand:SI 0 "register_operand" "=S"))
15747 (clobber (match_operand:SI 1 "register_operand" "=D"))
15748 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15749 "!TARGET_64BIT"
15750 "repz{%;} cmpsb"
15751 [(set_attr "type" "str")
15752 (set_attr "mode" "QI")
15753 (set_attr "prefix_rep" "1")])
15754
15755 (define_insn "*cmpstrnqi_nz_rex_1"
15756 [(set (reg:CC FLAGS_REG)
15757 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15758 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15759 (use (match_operand:DI 6 "register_operand" "2"))
15760 (use (match_operand:SI 3 "immediate_operand" "i"))
15761 (clobber (match_operand:DI 0 "register_operand" "=S"))
15762 (clobber (match_operand:DI 1 "register_operand" "=D"))
15763 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15764 "TARGET_64BIT"
15765 "repz{%;} cmpsb"
15766 [(set_attr "type" "str")
15767 (set_attr "mode" "QI")
15768 (set_attr "prefix_rex" "0")
15769 (set_attr "prefix_rep" "1")])
15770
15771 ;; The same, but the count is not known to not be zero.
15772
15773 (define_expand "cmpstrnqi_1"
15774 [(parallel [(set (reg:CC FLAGS_REG)
15775 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15776 (const_int 0))
15777 (compare:CC (match_operand 4 "memory_operand" "")
15778 (match_operand 5 "memory_operand" ""))
15779 (const_int 0)))
15780 (use (match_operand:SI 3 "immediate_operand" ""))
15781 (use (reg:CC FLAGS_REG))
15782 (clobber (match_operand 0 "register_operand" ""))
15783 (clobber (match_operand 1 "register_operand" ""))
15784 (clobber (match_dup 2))])]
15785 ""
15786 "ix86_current_function_needs_cld = 1;")
15787
15788 (define_insn "*cmpstrnqi_1"
15789 [(set (reg:CC FLAGS_REG)
15790 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15791 (const_int 0))
15792 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15793 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15794 (const_int 0)))
15795 (use (match_operand:SI 3 "immediate_operand" "i"))
15796 (use (reg:CC FLAGS_REG))
15797 (clobber (match_operand:SI 0 "register_operand" "=S"))
15798 (clobber (match_operand:SI 1 "register_operand" "=D"))
15799 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15800 "!TARGET_64BIT"
15801 "repz{%;} cmpsb"
15802 [(set_attr "type" "str")
15803 (set_attr "mode" "QI")
15804 (set_attr "prefix_rep" "1")])
15805
15806 (define_insn "*cmpstrnqi_rex_1"
15807 [(set (reg:CC FLAGS_REG)
15808 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15809 (const_int 0))
15810 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15811 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15812 (const_int 0)))
15813 (use (match_operand:SI 3 "immediate_operand" "i"))
15814 (use (reg:CC FLAGS_REG))
15815 (clobber (match_operand:DI 0 "register_operand" "=S"))
15816 (clobber (match_operand:DI 1 "register_operand" "=D"))
15817 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15818 "TARGET_64BIT"
15819 "repz{%;} cmpsb"
15820 [(set_attr "type" "str")
15821 (set_attr "mode" "QI")
15822 (set_attr "prefix_rex" "0")
15823 (set_attr "prefix_rep" "1")])
15824
15825 (define_expand "strlensi"
15826 [(set (match_operand:SI 0 "register_operand" "")
15827 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15828 (match_operand:QI 2 "immediate_operand" "")
15829 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15830 ""
15831 {
15832 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15833 DONE;
15834 else
15835 FAIL;
15836 })
15837
15838 (define_expand "strlendi"
15839 [(set (match_operand:DI 0 "register_operand" "")
15840 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15841 (match_operand:QI 2 "immediate_operand" "")
15842 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15843 ""
15844 {
15845 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15846 DONE;
15847 else
15848 FAIL;
15849 })
15850
15851 (define_expand "strlenqi_1"
15852 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15853 (clobber (match_operand 1 "register_operand" ""))
15854 (clobber (reg:CC FLAGS_REG))])]
15855 ""
15856 "ix86_current_function_needs_cld = 1;")
15857
15858 (define_insn "*strlenqi_1"
15859 [(set (match_operand:SI 0 "register_operand" "=&c")
15860 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15861 (match_operand:QI 2 "register_operand" "a")
15862 (match_operand:SI 3 "immediate_operand" "i")
15863 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15864 (clobber (match_operand:SI 1 "register_operand" "=D"))
15865 (clobber (reg:CC FLAGS_REG))]
15866 "!TARGET_64BIT"
15867 "repnz{%;} scasb"
15868 [(set_attr "type" "str")
15869 (set_attr "mode" "QI")
15870 (set_attr "prefix_rep" "1")])
15871
15872 (define_insn "*strlenqi_rex_1"
15873 [(set (match_operand:DI 0 "register_operand" "=&c")
15874 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15875 (match_operand:QI 2 "register_operand" "a")
15876 (match_operand:DI 3 "immediate_operand" "i")
15877 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15878 (clobber (match_operand:DI 1 "register_operand" "=D"))
15879 (clobber (reg:CC FLAGS_REG))]
15880 "TARGET_64BIT"
15881 "repnz{%;} scasb"
15882 [(set_attr "type" "str")
15883 (set_attr "mode" "QI")
15884 (set_attr "prefix_rex" "0")
15885 (set_attr "prefix_rep" "1")])
15886
15887 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15888 ;; handled in combine, but it is not currently up to the task.
15889 ;; When used for their truth value, the cmpstrn* expanders generate
15890 ;; code like this:
15891 ;;
15892 ;; repz cmpsb
15893 ;; seta %al
15894 ;; setb %dl
15895 ;; cmpb %al, %dl
15896 ;; jcc label
15897 ;;
15898 ;; The intermediate three instructions are unnecessary.
15899
15900 ;; This one handles cmpstrn*_nz_1...
15901 (define_peephole2
15902 [(parallel[
15903 (set (reg:CC FLAGS_REG)
15904 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15905 (mem:BLK (match_operand 5 "register_operand" ""))))
15906 (use (match_operand 6 "register_operand" ""))
15907 (use (match_operand:SI 3 "immediate_operand" ""))
15908 (clobber (match_operand 0 "register_operand" ""))
15909 (clobber (match_operand 1 "register_operand" ""))
15910 (clobber (match_operand 2 "register_operand" ""))])
15911 (set (match_operand:QI 7 "register_operand" "")
15912 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15913 (set (match_operand:QI 8 "register_operand" "")
15914 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15915 (set (reg FLAGS_REG)
15916 (compare (match_dup 7) (match_dup 8)))
15917 ]
15918 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15919 [(parallel[
15920 (set (reg:CC FLAGS_REG)
15921 (compare:CC (mem:BLK (match_dup 4))
15922 (mem:BLK (match_dup 5))))
15923 (use (match_dup 6))
15924 (use (match_dup 3))
15925 (clobber (match_dup 0))
15926 (clobber (match_dup 1))
15927 (clobber (match_dup 2))])])
15928
15929 ;; ...and this one handles cmpstrn*_1.
15930 (define_peephole2
15931 [(parallel[
15932 (set (reg:CC FLAGS_REG)
15933 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15934 (const_int 0))
15935 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15936 (mem:BLK (match_operand 5 "register_operand" "")))
15937 (const_int 0)))
15938 (use (match_operand:SI 3 "immediate_operand" ""))
15939 (use (reg:CC FLAGS_REG))
15940 (clobber (match_operand 0 "register_operand" ""))
15941 (clobber (match_operand 1 "register_operand" ""))
15942 (clobber (match_operand 2 "register_operand" ""))])
15943 (set (match_operand:QI 7 "register_operand" "")
15944 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15945 (set (match_operand:QI 8 "register_operand" "")
15946 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15947 (set (reg FLAGS_REG)
15948 (compare (match_dup 7) (match_dup 8)))
15949 ]
15950 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15951 [(parallel[
15952 (set (reg:CC FLAGS_REG)
15953 (if_then_else:CC (ne (match_dup 6)
15954 (const_int 0))
15955 (compare:CC (mem:BLK (match_dup 4))
15956 (mem:BLK (match_dup 5)))
15957 (const_int 0)))
15958 (use (match_dup 3))
15959 (use (reg:CC FLAGS_REG))
15960 (clobber (match_dup 0))
15961 (clobber (match_dup 1))
15962 (clobber (match_dup 2))])])
15963 \f
15964 ;; Conditional move instructions.
15965
15966 (define_expand "mov<mode>cc"
15967 [(set (match_operand:SWIM 0 "register_operand" "")
15968 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15969 (match_operand:SWIM 2 "general_operand" "")
15970 (match_operand:SWIM 3 "general_operand" "")))]
15971 ""
15972 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15973
15974 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15975 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15976 ;; So just document what we're doing explicitly.
15977
15978 (define_expand "x86_mov<mode>cc_0_m1"
15979 [(parallel
15980 [(set (match_operand:SWI48 0 "register_operand" "")
15981 (if_then_else:SWI48
15982 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15983 [(match_operand 1 "flags_reg_operand" "")
15984 (const_int 0)])
15985 (const_int -1)
15986 (const_int 0)))
15987 (clobber (reg:CC FLAGS_REG))])])
15988
15989 (define_insn "*x86_mov<mode>cc_0_m1"
15990 [(set (match_operand:SWI48 0 "register_operand" "=r")
15991 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15992 [(reg FLAGS_REG) (const_int 0)])
15993 (const_int -1)
15994 (const_int 0)))
15995 (clobber (reg:CC FLAGS_REG))]
15996 ""
15997 "sbb{<imodesuffix>}\t%0, %0"
15998 ; Since we don't have the proper number of operands for an alu insn,
15999 ; fill in all the blanks.
16000 [(set_attr "type" "alu")
16001 (set_attr "use_carry" "1")
16002 (set_attr "pent_pair" "pu")
16003 (set_attr "memory" "none")
16004 (set_attr "imm_disp" "false")
16005 (set_attr "mode" "<MODE>")
16006 (set_attr "length_immediate" "0")])
16007
16008 (define_insn "*x86_mov<mode>cc_0_m1_se"
16009 [(set (match_operand:SWI48 0 "register_operand" "=r")
16010 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16011 [(reg FLAGS_REG) (const_int 0)])
16012 (const_int 1)
16013 (const_int 0)))
16014 (clobber (reg:CC FLAGS_REG))]
16015 ""
16016 "sbb{<imodesuffix>}\t%0, %0"
16017 [(set_attr "type" "alu")
16018 (set_attr "use_carry" "1")
16019 (set_attr "pent_pair" "pu")
16020 (set_attr "memory" "none")
16021 (set_attr "imm_disp" "false")
16022 (set_attr "mode" "<MODE>")
16023 (set_attr "length_immediate" "0")])
16024
16025 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16026 [(set (match_operand:SWI48 0 "register_operand" "=r")
16027 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16028 [(reg FLAGS_REG) (const_int 0)])))]
16029 ""
16030 "sbb{<imodesuffix>}\t%0, %0"
16031 [(set_attr "type" "alu")
16032 (set_attr "use_carry" "1")
16033 (set_attr "pent_pair" "pu")
16034 (set_attr "memory" "none")
16035 (set_attr "imm_disp" "false")
16036 (set_attr "mode" "<MODE>")
16037 (set_attr "length_immediate" "0")])
16038
16039 (define_insn "*mov<mode>cc_noc"
16040 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16041 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16042 [(reg FLAGS_REG) (const_int 0)])
16043 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16044 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16045 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16046 "@
16047 cmov%O2%C1\t{%2, %0|%0, %2}
16048 cmov%O2%c1\t{%3, %0|%0, %3}"
16049 [(set_attr "type" "icmov")
16050 (set_attr "mode" "<MODE>")])
16051
16052 (define_insn_and_split "*movqicc_noc"
16053 [(set (match_operand:QI 0 "register_operand" "=r,r")
16054 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16055 [(match_operand 4 "flags_reg_operand" "")
16056 (const_int 0)])
16057 (match_operand:QI 2 "register_operand" "r,0")
16058 (match_operand:QI 3 "register_operand" "0,r")))]
16059 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16060 "#"
16061 "&& reload_completed"
16062 [(set (match_dup 0)
16063 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16064 (match_dup 2)
16065 (match_dup 3)))]
16066 "operands[0] = gen_lowpart (SImode, operands[0]);
16067 operands[2] = gen_lowpart (SImode, operands[2]);
16068 operands[3] = gen_lowpart (SImode, operands[3]);"
16069 [(set_attr "type" "icmov")
16070 (set_attr "mode" "SI")])
16071
16072 (define_expand "mov<mode>cc"
16073 [(set (match_operand:X87MODEF 0 "register_operand" "")
16074 (if_then_else:X87MODEF
16075 (match_operand 1 "ix86_fp_comparison_operator" "")
16076 (match_operand:X87MODEF 2 "register_operand" "")
16077 (match_operand:X87MODEF 3 "register_operand" "")))]
16078 "(TARGET_80387 && TARGET_CMOVE)
16079 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16080 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16081
16082 (define_insn "*movsfcc_1_387"
16083 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16084 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16085 [(reg FLAGS_REG) (const_int 0)])
16086 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16087 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16088 "TARGET_80387 && TARGET_CMOVE
16089 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16090 "@
16091 fcmov%F1\t{%2, %0|%0, %2}
16092 fcmov%f1\t{%3, %0|%0, %3}
16093 cmov%O2%C1\t{%2, %0|%0, %2}
16094 cmov%O2%c1\t{%3, %0|%0, %3}"
16095 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16096 (set_attr "mode" "SF,SF,SI,SI")])
16097
16098 (define_insn "*movdfcc_1"
16099 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16100 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16101 [(reg FLAGS_REG) (const_int 0)])
16102 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16103 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16104 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16105 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16106 "@
16107 fcmov%F1\t{%2, %0|%0, %2}
16108 fcmov%f1\t{%3, %0|%0, %3}
16109 #
16110 #"
16111 [(set_attr "type" "fcmov,fcmov,multi,multi")
16112 (set_attr "mode" "DF")])
16113
16114 (define_insn "*movdfcc_1_rex64"
16115 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16116 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16117 [(reg FLAGS_REG) (const_int 0)])
16118 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16119 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16120 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16121 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16122 "@
16123 fcmov%F1\t{%2, %0|%0, %2}
16124 fcmov%f1\t{%3, %0|%0, %3}
16125 cmov%O2%C1\t{%2, %0|%0, %2}
16126 cmov%O2%c1\t{%3, %0|%0, %3}"
16127 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16128 (set_attr "mode" "DF")])
16129
16130 (define_split
16131 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16132 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16133 [(match_operand 4 "flags_reg_operand" "")
16134 (const_int 0)])
16135 (match_operand:DF 2 "nonimmediate_operand" "")
16136 (match_operand:DF 3 "nonimmediate_operand" "")))]
16137 "!TARGET_64BIT && reload_completed"
16138 [(set (match_dup 2)
16139 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16140 (match_dup 5)
16141 (match_dup 6)))
16142 (set (match_dup 3)
16143 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16144 (match_dup 7)
16145 (match_dup 8)))]
16146 {
16147 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16148 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16149 })
16150
16151 (define_insn "*movxfcc_1"
16152 [(set (match_operand:XF 0 "register_operand" "=f,f")
16153 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16154 [(reg FLAGS_REG) (const_int 0)])
16155 (match_operand:XF 2 "register_operand" "f,0")
16156 (match_operand:XF 3 "register_operand" "0,f")))]
16157 "TARGET_80387 && TARGET_CMOVE"
16158 "@
16159 fcmov%F1\t{%2, %0|%0, %2}
16160 fcmov%f1\t{%3, %0|%0, %3}"
16161 [(set_attr "type" "fcmov")
16162 (set_attr "mode" "XF")])
16163
16164 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16165 ;; the scalar versions to have only XMM registers as operands.
16166
16167 ;; XOP conditional move
16168 (define_insn "*xop_pcmov_<mode>"
16169 [(set (match_operand:MODEF 0 "register_operand" "=x")
16170 (if_then_else:MODEF
16171 (match_operand:MODEF 1 "register_operand" "x")
16172 (match_operand:MODEF 2 "register_operand" "x")
16173 (match_operand:MODEF 3 "register_operand" "x")))]
16174 "TARGET_XOP"
16175 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16176 [(set_attr "type" "sse4arg")])
16177
16178 ;; These versions of the min/max patterns are intentionally ignorant of
16179 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16180 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16181 ;; are undefined in this condition, we're certain this is correct.
16182
16183 (define_insn "*avx_<code><mode>3"
16184 [(set (match_operand:MODEF 0 "register_operand" "=x")
16185 (smaxmin:MODEF
16186 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16187 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16188 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16189 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16190 [(set_attr "type" "sseadd")
16191 (set_attr "prefix" "vex")
16192 (set_attr "mode" "<MODE>")])
16193
16194 (define_insn "<code><mode>3"
16195 [(set (match_operand:MODEF 0 "register_operand" "=x")
16196 (smaxmin:MODEF
16197 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16198 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16199 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16200 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16201 [(set_attr "type" "sseadd")
16202 (set_attr "mode" "<MODE>")])
16203
16204 ;; These versions of the min/max patterns implement exactly the operations
16205 ;; min = (op1 < op2 ? op1 : op2)
16206 ;; max = (!(op1 < op2) ? op1 : op2)
16207 ;; Their operands are not commutative, and thus they may be used in the
16208 ;; presence of -0.0 and NaN.
16209
16210 (define_insn "*avx_ieee_smin<mode>3"
16211 [(set (match_operand:MODEF 0 "register_operand" "=x")
16212 (unspec:MODEF
16213 [(match_operand:MODEF 1 "register_operand" "x")
16214 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16215 UNSPEC_IEEE_MIN))]
16216 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16217 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16218 [(set_attr "type" "sseadd")
16219 (set_attr "prefix" "vex")
16220 (set_attr "mode" "<MODE>")])
16221
16222 (define_insn "*ieee_smin<mode>3"
16223 [(set (match_operand:MODEF 0 "register_operand" "=x")
16224 (unspec:MODEF
16225 [(match_operand:MODEF 1 "register_operand" "0")
16226 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16227 UNSPEC_IEEE_MIN))]
16228 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16229 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16230 [(set_attr "type" "sseadd")
16231 (set_attr "mode" "<MODE>")])
16232
16233 (define_insn "*avx_ieee_smax<mode>3"
16234 [(set (match_operand:MODEF 0 "register_operand" "=x")
16235 (unspec:MODEF
16236 [(match_operand:MODEF 1 "register_operand" "0")
16237 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16238 UNSPEC_IEEE_MAX))]
16239 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16240 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16241 [(set_attr "type" "sseadd")
16242 (set_attr "prefix" "vex")
16243 (set_attr "mode" "<MODE>")])
16244
16245 (define_insn "*ieee_smax<mode>3"
16246 [(set (match_operand:MODEF 0 "register_operand" "=x")
16247 (unspec:MODEF
16248 [(match_operand:MODEF 1 "register_operand" "0")
16249 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16250 UNSPEC_IEEE_MAX))]
16251 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16252 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16253 [(set_attr "type" "sseadd")
16254 (set_attr "mode" "<MODE>")])
16255
16256 ;; Make two stack loads independent:
16257 ;; fld aa fld aa
16258 ;; fld %st(0) -> fld bb
16259 ;; fmul bb fmul %st(1), %st
16260 ;;
16261 ;; Actually we only match the last two instructions for simplicity.
16262 (define_peephole2
16263 [(set (match_operand 0 "fp_register_operand" "")
16264 (match_operand 1 "fp_register_operand" ""))
16265 (set (match_dup 0)
16266 (match_operator 2 "binary_fp_operator"
16267 [(match_dup 0)
16268 (match_operand 3 "memory_operand" "")]))]
16269 "REGNO (operands[0]) != REGNO (operands[1])"
16270 [(set (match_dup 0) (match_dup 3))
16271 (set (match_dup 0) (match_dup 4))]
16272
16273 ;; The % modifier is not operational anymore in peephole2's, so we have to
16274 ;; swap the operands manually in the case of addition and multiplication.
16275 "if (COMMUTATIVE_ARITH_P (operands[2]))
16276 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16277 GET_MODE (operands[2]),
16278 operands[0], operands[1]);
16279 else
16280 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16281 GET_MODE (operands[2]),
16282 operands[1], operands[0]);")
16283
16284 ;; Conditional addition patterns
16285 (define_expand "add<mode>cc"
16286 [(match_operand:SWI 0 "register_operand" "")
16287 (match_operand 1 "ordered_comparison_operator" "")
16288 (match_operand:SWI 2 "register_operand" "")
16289 (match_operand:SWI 3 "const_int_operand" "")]
16290 ""
16291 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16292 \f
16293 ;; Misc patterns (?)
16294
16295 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16296 ;; Otherwise there will be nothing to keep
16297 ;;
16298 ;; [(set (reg ebp) (reg esp))]
16299 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16300 ;; (clobber (eflags)]
16301 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16302 ;;
16303 ;; in proper program order.
16304
16305 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16306 [(set (match_operand:P 0 "register_operand" "=r,r")
16307 (plus:P (match_operand:P 1 "register_operand" "0,r")
16308 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16309 (clobber (reg:CC FLAGS_REG))
16310 (clobber (mem:BLK (scratch)))]
16311 ""
16312 {
16313 switch (get_attr_type (insn))
16314 {
16315 case TYPE_IMOV:
16316 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16317
16318 case TYPE_ALU:
16319 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16320 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16321 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16322
16323 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16324
16325 default:
16326 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16327 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16328 }
16329 }
16330 [(set (attr "type")
16331 (cond [(and (eq_attr "alternative" "0")
16332 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16333 (const_string "alu")
16334 (match_operand:<MODE> 2 "const0_operand" "")
16335 (const_string "imov")
16336 ]
16337 (const_string "lea")))
16338 (set (attr "length_immediate")
16339 (cond [(eq_attr "type" "imov")
16340 (const_string "0")
16341 (and (eq_attr "type" "alu")
16342 (match_operand 2 "const128_operand" ""))
16343 (const_string "1")
16344 ]
16345 (const_string "*")))
16346 (set_attr "mode" "<MODE>")])
16347
16348 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16349 [(set (match_operand:P 0 "register_operand" "=r")
16350 (minus:P (match_operand:P 1 "register_operand" "0")
16351 (match_operand:P 2 "register_operand" "r")))
16352 (clobber (reg:CC FLAGS_REG))
16353 (clobber (mem:BLK (scratch)))]
16354 ""
16355 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16356 [(set_attr "type" "alu")
16357 (set_attr "mode" "<MODE>")])
16358
16359 (define_insn "allocate_stack_worker_probe_<mode>"
16360 [(set (match_operand:P 0 "register_operand" "=a")
16361 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16362 UNSPECV_STACK_PROBE))
16363 (clobber (reg:CC FLAGS_REG))]
16364 "ix86_target_stack_probe ()"
16365 "call\t___chkstk_ms"
16366 [(set_attr "type" "multi")
16367 (set_attr "length" "5")])
16368
16369 (define_expand "allocate_stack"
16370 [(match_operand 0 "register_operand" "")
16371 (match_operand 1 "general_operand" "")]
16372 "ix86_target_stack_probe ()"
16373 {
16374 rtx x;
16375
16376 #ifndef CHECK_STACK_LIMIT
16377 #define CHECK_STACK_LIMIT 0
16378 #endif
16379
16380 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16381 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16382 {
16383 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16384 stack_pointer_rtx, 0, OPTAB_DIRECT);
16385 if (x != stack_pointer_rtx)
16386 emit_move_insn (stack_pointer_rtx, x);
16387 }
16388 else
16389 {
16390 x = copy_to_mode_reg (Pmode, operands[1]);
16391 if (TARGET_64BIT)
16392 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16393 else
16394 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16395 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16396 stack_pointer_rtx, 0, OPTAB_DIRECT);
16397 if (x != stack_pointer_rtx)
16398 emit_move_insn (stack_pointer_rtx, x);
16399 }
16400
16401 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16402 DONE;
16403 })
16404
16405 ;; Use IOR for stack probes, this is shorter.
16406 (define_expand "probe_stack"
16407 [(match_operand 0 "memory_operand" "")]
16408 ""
16409 {
16410 rtx (*gen_ior3) (rtx, rtx, rtx);
16411
16412 gen_ior3 = (GET_MODE (operands[0]) == DImode
16413 ? gen_iordi3 : gen_iorsi3);
16414
16415 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16416 DONE;
16417 })
16418
16419 (define_insn "adjust_stack_and_probe<mode>"
16420 [(set (match_operand:P 0 "register_operand" "=r")
16421 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16422 UNSPECV_PROBE_STACK_RANGE))
16423 (set (reg:P SP_REG)
16424 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16425 (clobber (reg:CC FLAGS_REG))
16426 (clobber (mem:BLK (scratch)))]
16427 ""
16428 "* return output_adjust_stack_and_probe (operands[0]);"
16429 [(set_attr "type" "multi")])
16430
16431 (define_insn "probe_stack_range<mode>"
16432 [(set (match_operand:P 0 "register_operand" "=r")
16433 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16434 (match_operand:P 2 "const_int_operand" "n")]
16435 UNSPECV_PROBE_STACK_RANGE))
16436 (clobber (reg:CC FLAGS_REG))]
16437 ""
16438 "* return output_probe_stack_range (operands[0], operands[2]);"
16439 [(set_attr "type" "multi")])
16440
16441 (define_expand "builtin_setjmp_receiver"
16442 [(label_ref (match_operand 0 "" ""))]
16443 "!TARGET_64BIT && flag_pic"
16444 {
16445 #if TARGET_MACHO
16446 if (TARGET_MACHO)
16447 {
16448 rtx xops[3];
16449 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16450 rtx label_rtx = gen_label_rtx ();
16451 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16452 xops[0] = xops[1] = picreg;
16453 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16454 ix86_expand_binary_operator (MINUS, SImode, xops);
16455 }
16456 else
16457 #endif
16458 emit_insn (gen_set_got (pic_offset_table_rtx));
16459 DONE;
16460 })
16461 \f
16462 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16463
16464 (define_split
16465 [(set (match_operand 0 "register_operand" "")
16466 (match_operator 3 "promotable_binary_operator"
16467 [(match_operand 1 "register_operand" "")
16468 (match_operand 2 "aligned_operand" "")]))
16469 (clobber (reg:CC FLAGS_REG))]
16470 "! TARGET_PARTIAL_REG_STALL && reload_completed
16471 && ((GET_MODE (operands[0]) == HImode
16472 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16473 /* ??? next two lines just !satisfies_constraint_K (...) */
16474 || !CONST_INT_P (operands[2])
16475 || satisfies_constraint_K (operands[2])))
16476 || (GET_MODE (operands[0]) == QImode
16477 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16478 [(parallel [(set (match_dup 0)
16479 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16480 (clobber (reg:CC FLAGS_REG))])]
16481 "operands[0] = gen_lowpart (SImode, operands[0]);
16482 operands[1] = gen_lowpart (SImode, operands[1]);
16483 if (GET_CODE (operands[3]) != ASHIFT)
16484 operands[2] = gen_lowpart (SImode, operands[2]);
16485 PUT_MODE (operands[3], SImode);")
16486
16487 ; Promote the QImode tests, as i386 has encoding of the AND
16488 ; instruction with 32-bit sign-extended immediate and thus the
16489 ; instruction size is unchanged, except in the %eax case for
16490 ; which it is increased by one byte, hence the ! optimize_size.
16491 (define_split
16492 [(set (match_operand 0 "flags_reg_operand" "")
16493 (match_operator 2 "compare_operator"
16494 [(and (match_operand 3 "aligned_operand" "")
16495 (match_operand 4 "const_int_operand" ""))
16496 (const_int 0)]))
16497 (set (match_operand 1 "register_operand" "")
16498 (and (match_dup 3) (match_dup 4)))]
16499 "! TARGET_PARTIAL_REG_STALL && reload_completed
16500 && optimize_insn_for_speed_p ()
16501 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16502 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16503 /* Ensure that the operand will remain sign-extended immediate. */
16504 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16505 [(parallel [(set (match_dup 0)
16506 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16507 (const_int 0)]))
16508 (set (match_dup 1)
16509 (and:SI (match_dup 3) (match_dup 4)))])]
16510 {
16511 operands[4]
16512 = gen_int_mode (INTVAL (operands[4])
16513 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16514 operands[1] = gen_lowpart (SImode, operands[1]);
16515 operands[3] = gen_lowpart (SImode, operands[3]);
16516 })
16517
16518 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16519 ; the TEST instruction with 32-bit sign-extended immediate and thus
16520 ; the instruction size would at least double, which is not what we
16521 ; want even with ! optimize_size.
16522 (define_split
16523 [(set (match_operand 0 "flags_reg_operand" "")
16524 (match_operator 1 "compare_operator"
16525 [(and (match_operand:HI 2 "aligned_operand" "")
16526 (match_operand:HI 3 "const_int_operand" ""))
16527 (const_int 0)]))]
16528 "! TARGET_PARTIAL_REG_STALL && reload_completed
16529 && ! TARGET_FAST_PREFIX
16530 && optimize_insn_for_speed_p ()
16531 /* Ensure that the operand will remain sign-extended immediate. */
16532 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16533 [(set (match_dup 0)
16534 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16535 (const_int 0)]))]
16536 {
16537 operands[3]
16538 = gen_int_mode (INTVAL (operands[3])
16539 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16540 operands[2] = gen_lowpart (SImode, operands[2]);
16541 })
16542
16543 (define_split
16544 [(set (match_operand 0 "register_operand" "")
16545 (neg (match_operand 1 "register_operand" "")))
16546 (clobber (reg:CC FLAGS_REG))]
16547 "! TARGET_PARTIAL_REG_STALL && reload_completed
16548 && (GET_MODE (operands[0]) == HImode
16549 || (GET_MODE (operands[0]) == QImode
16550 && (TARGET_PROMOTE_QImode
16551 || optimize_insn_for_size_p ())))"
16552 [(parallel [(set (match_dup 0)
16553 (neg:SI (match_dup 1)))
16554 (clobber (reg:CC FLAGS_REG))])]
16555 "operands[0] = gen_lowpart (SImode, operands[0]);
16556 operands[1] = gen_lowpart (SImode, operands[1]);")
16557
16558 (define_split
16559 [(set (match_operand 0 "register_operand" "")
16560 (not (match_operand 1 "register_operand" "")))]
16561 "! TARGET_PARTIAL_REG_STALL && reload_completed
16562 && (GET_MODE (operands[0]) == HImode
16563 || (GET_MODE (operands[0]) == QImode
16564 && (TARGET_PROMOTE_QImode
16565 || optimize_insn_for_size_p ())))"
16566 [(set (match_dup 0)
16567 (not:SI (match_dup 1)))]
16568 "operands[0] = gen_lowpart (SImode, operands[0]);
16569 operands[1] = gen_lowpart (SImode, operands[1]);")
16570
16571 (define_split
16572 [(set (match_operand 0 "register_operand" "")
16573 (if_then_else (match_operator 1 "ordered_comparison_operator"
16574 [(reg FLAGS_REG) (const_int 0)])
16575 (match_operand 2 "register_operand" "")
16576 (match_operand 3 "register_operand" "")))]
16577 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16578 && (GET_MODE (operands[0]) == HImode
16579 || (GET_MODE (operands[0]) == QImode
16580 && (TARGET_PROMOTE_QImode
16581 || optimize_insn_for_size_p ())))"
16582 [(set (match_dup 0)
16583 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16584 "operands[0] = gen_lowpart (SImode, operands[0]);
16585 operands[2] = gen_lowpart (SImode, operands[2]);
16586 operands[3] = gen_lowpart (SImode, operands[3]);")
16587 \f
16588 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16589 ;; transform a complex memory operation into two memory to register operations.
16590
16591 ;; Don't push memory operands
16592 (define_peephole2
16593 [(set (match_operand:SWI 0 "push_operand" "")
16594 (match_operand:SWI 1 "memory_operand" ""))
16595 (match_scratch:SWI 2 "<r>")]
16596 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16597 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16598 [(set (match_dup 2) (match_dup 1))
16599 (set (match_dup 0) (match_dup 2))])
16600
16601 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16602 ;; SImode pushes.
16603 (define_peephole2
16604 [(set (match_operand:SF 0 "push_operand" "")
16605 (match_operand:SF 1 "memory_operand" ""))
16606 (match_scratch:SF 2 "r")]
16607 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16608 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16609 [(set (match_dup 2) (match_dup 1))
16610 (set (match_dup 0) (match_dup 2))])
16611
16612 ;; Don't move an immediate directly to memory when the instruction
16613 ;; gets too big.
16614 (define_peephole2
16615 [(match_scratch:SWI124 1 "<r>")
16616 (set (match_operand:SWI124 0 "memory_operand" "")
16617 (const_int 0))]
16618 "optimize_insn_for_speed_p ()
16619 && !TARGET_USE_MOV0
16620 && TARGET_SPLIT_LONG_MOVES
16621 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16622 && peep2_regno_dead_p (0, FLAGS_REG)"
16623 [(parallel [(set (match_dup 2) (const_int 0))
16624 (clobber (reg:CC FLAGS_REG))])
16625 (set (match_dup 0) (match_dup 1))]
16626 "operands[2] = gen_lowpart (SImode, operands[1]);")
16627
16628 (define_peephole2
16629 [(match_scratch:SWI124 2 "<r>")
16630 (set (match_operand:SWI124 0 "memory_operand" "")
16631 (match_operand:SWI124 1 "immediate_operand" ""))]
16632 "optimize_insn_for_speed_p ()
16633 && TARGET_SPLIT_LONG_MOVES
16634 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16635 [(set (match_dup 2) (match_dup 1))
16636 (set (match_dup 0) (match_dup 2))])
16637
16638 ;; Don't compare memory with zero, load and use a test instead.
16639 (define_peephole2
16640 [(set (match_operand 0 "flags_reg_operand" "")
16641 (match_operator 1 "compare_operator"
16642 [(match_operand:SI 2 "memory_operand" "")
16643 (const_int 0)]))
16644 (match_scratch:SI 3 "r")]
16645 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16646 [(set (match_dup 3) (match_dup 2))
16647 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16648
16649 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16650 ;; Don't split NOTs with a displacement operand, because resulting XOR
16651 ;; will not be pairable anyway.
16652 ;;
16653 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16654 ;; represented using a modRM byte. The XOR replacement is long decoded,
16655 ;; so this split helps here as well.
16656 ;;
16657 ;; Note: Can't do this as a regular split because we can't get proper
16658 ;; lifetime information then.
16659
16660 (define_peephole2
16661 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16662 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16663 "optimize_insn_for_speed_p ()
16664 && ((TARGET_NOT_UNPAIRABLE
16665 && (!MEM_P (operands[0])
16666 || !memory_displacement_operand (operands[0], <MODE>mode)))
16667 || (TARGET_NOT_VECTORMODE
16668 && long_memory_operand (operands[0], <MODE>mode)))
16669 && peep2_regno_dead_p (0, FLAGS_REG)"
16670 [(parallel [(set (match_dup 0)
16671 (xor:SWI124 (match_dup 1) (const_int -1)))
16672 (clobber (reg:CC FLAGS_REG))])])
16673
16674 ;; Non pairable "test imm, reg" instructions can be translated to
16675 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16676 ;; byte opcode instead of two, have a short form for byte operands),
16677 ;; so do it for other CPUs as well. Given that the value was dead,
16678 ;; this should not create any new dependencies. Pass on the sub-word
16679 ;; versions if we're concerned about partial register stalls.
16680
16681 (define_peephole2
16682 [(set (match_operand 0 "flags_reg_operand" "")
16683 (match_operator 1 "compare_operator"
16684 [(and:SI (match_operand:SI 2 "register_operand" "")
16685 (match_operand:SI 3 "immediate_operand" ""))
16686 (const_int 0)]))]
16687 "ix86_match_ccmode (insn, CCNOmode)
16688 && (true_regnum (operands[2]) != AX_REG
16689 || satisfies_constraint_K (operands[3]))
16690 && peep2_reg_dead_p (1, operands[2])"
16691 [(parallel
16692 [(set (match_dup 0)
16693 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16694 (const_int 0)]))
16695 (set (match_dup 2)
16696 (and:SI (match_dup 2) (match_dup 3)))])])
16697
16698 ;; We don't need to handle HImode case, because it will be promoted to SImode
16699 ;; on ! TARGET_PARTIAL_REG_STALL
16700
16701 (define_peephole2
16702 [(set (match_operand 0 "flags_reg_operand" "")
16703 (match_operator 1 "compare_operator"
16704 [(and:QI (match_operand:QI 2 "register_operand" "")
16705 (match_operand:QI 3 "immediate_operand" ""))
16706 (const_int 0)]))]
16707 "! TARGET_PARTIAL_REG_STALL
16708 && ix86_match_ccmode (insn, CCNOmode)
16709 && true_regnum (operands[2]) != AX_REG
16710 && peep2_reg_dead_p (1, operands[2])"
16711 [(parallel
16712 [(set (match_dup 0)
16713 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16714 (const_int 0)]))
16715 (set (match_dup 2)
16716 (and:QI (match_dup 2) (match_dup 3)))])])
16717
16718 (define_peephole2
16719 [(set (match_operand 0 "flags_reg_operand" "")
16720 (match_operator 1 "compare_operator"
16721 [(and:SI
16722 (zero_extract:SI
16723 (match_operand 2 "ext_register_operand" "")
16724 (const_int 8)
16725 (const_int 8))
16726 (match_operand 3 "const_int_operand" ""))
16727 (const_int 0)]))]
16728 "! TARGET_PARTIAL_REG_STALL
16729 && ix86_match_ccmode (insn, CCNOmode)
16730 && true_regnum (operands[2]) != AX_REG
16731 && peep2_reg_dead_p (1, operands[2])"
16732 [(parallel [(set (match_dup 0)
16733 (match_op_dup 1
16734 [(and:SI
16735 (zero_extract:SI
16736 (match_dup 2)
16737 (const_int 8)
16738 (const_int 8))
16739 (match_dup 3))
16740 (const_int 0)]))
16741 (set (zero_extract:SI (match_dup 2)
16742 (const_int 8)
16743 (const_int 8))
16744 (and:SI
16745 (zero_extract:SI
16746 (match_dup 2)
16747 (const_int 8)
16748 (const_int 8))
16749 (match_dup 3)))])])
16750
16751 ;; Don't do logical operations with memory inputs.
16752 (define_peephole2
16753 [(match_scratch:SI 2 "r")
16754 (parallel [(set (match_operand:SI 0 "register_operand" "")
16755 (match_operator:SI 3 "arith_or_logical_operator"
16756 [(match_dup 0)
16757 (match_operand:SI 1 "memory_operand" "")]))
16758 (clobber (reg:CC FLAGS_REG))])]
16759 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16760 [(set (match_dup 2) (match_dup 1))
16761 (parallel [(set (match_dup 0)
16762 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16763 (clobber (reg:CC FLAGS_REG))])])
16764
16765 (define_peephole2
16766 [(match_scratch:SI 2 "r")
16767 (parallel [(set (match_operand:SI 0 "register_operand" "")
16768 (match_operator:SI 3 "arith_or_logical_operator"
16769 [(match_operand:SI 1 "memory_operand" "")
16770 (match_dup 0)]))
16771 (clobber (reg:CC FLAGS_REG))])]
16772 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16773 [(set (match_dup 2) (match_dup 1))
16774 (parallel [(set (match_dup 0)
16775 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16776 (clobber (reg:CC FLAGS_REG))])])
16777
16778 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16779 ;; refers to the destination of the load!
16780
16781 (define_peephole2
16782 [(set (match_operand:SI 0 "register_operand" "")
16783 (match_operand:SI 1 "register_operand" ""))
16784 (parallel [(set (match_dup 0)
16785 (match_operator:SI 3 "commutative_operator"
16786 [(match_dup 0)
16787 (match_operand:SI 2 "memory_operand" "")]))
16788 (clobber (reg:CC FLAGS_REG))])]
16789 "REGNO (operands[0]) != REGNO (operands[1])
16790 && GENERAL_REGNO_P (REGNO (operands[0]))
16791 && GENERAL_REGNO_P (REGNO (operands[1]))"
16792 [(set (match_dup 0) (match_dup 4))
16793 (parallel [(set (match_dup 0)
16794 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16795 (clobber (reg:CC FLAGS_REG))])]
16796 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16797
16798 (define_peephole2
16799 [(set (match_operand 0 "register_operand" "")
16800 (match_operand 1 "register_operand" ""))
16801 (set (match_dup 0)
16802 (match_operator 3 "commutative_operator"
16803 [(match_dup 0)
16804 (match_operand 2 "memory_operand" "")]))]
16805 "REGNO (operands[0]) != REGNO (operands[1])
16806 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16807 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16808 [(set (match_dup 0) (match_dup 2))
16809 (set (match_dup 0)
16810 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16811
16812 ; Don't do logical operations with memory outputs
16813 ;
16814 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16815 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16816 ; the same decoder scheduling characteristics as the original.
16817
16818 (define_peephole2
16819 [(match_scratch:SI 2 "r")
16820 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16821 (match_operator:SI 3 "arith_or_logical_operator"
16822 [(match_dup 0)
16823 (match_operand:SI 1 "nonmemory_operand" "")]))
16824 (clobber (reg:CC FLAGS_REG))])]
16825 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16826 /* Do not split stack checking probes. */
16827 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16828 [(set (match_dup 2) (match_dup 0))
16829 (parallel [(set (match_dup 2)
16830 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16831 (clobber (reg:CC FLAGS_REG))])
16832 (set (match_dup 0) (match_dup 2))])
16833
16834 (define_peephole2
16835 [(match_scratch:SI 2 "r")
16836 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16837 (match_operator:SI 3 "arith_or_logical_operator"
16838 [(match_operand:SI 1 "nonmemory_operand" "")
16839 (match_dup 0)]))
16840 (clobber (reg:CC FLAGS_REG))])]
16841 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16842 /* Do not split stack checking probes. */
16843 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16844 [(set (match_dup 2) (match_dup 0))
16845 (parallel [(set (match_dup 2)
16846 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16847 (clobber (reg:CC FLAGS_REG))])
16848 (set (match_dup 0) (match_dup 2))])
16849
16850 ;; Attempt to always use XOR for zeroing registers.
16851 (define_peephole2
16852 [(set (match_operand 0 "register_operand" "")
16853 (match_operand 1 "const0_operand" ""))]
16854 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16855 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16856 && GENERAL_REG_P (operands[0])
16857 && peep2_regno_dead_p (0, FLAGS_REG)"
16858 [(parallel [(set (match_dup 0) (const_int 0))
16859 (clobber (reg:CC FLAGS_REG))])]
16860 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16861
16862 (define_peephole2
16863 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16864 (const_int 0))]
16865 "(GET_MODE (operands[0]) == QImode
16866 || GET_MODE (operands[0]) == HImode)
16867 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16868 && peep2_regno_dead_p (0, FLAGS_REG)"
16869 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16870 (clobber (reg:CC FLAGS_REG))])])
16871
16872 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16873 (define_peephole2
16874 [(set (match_operand:SWI248 0 "register_operand" "")
16875 (const_int -1))]
16876 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16877 && peep2_regno_dead_p (0, FLAGS_REG)"
16878 [(parallel [(set (match_dup 0) (const_int -1))
16879 (clobber (reg:CC FLAGS_REG))])]
16880 {
16881 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16882 operands[0] = gen_lowpart (SImode, operands[0]);
16883 })
16884
16885 ;; Attempt to convert simple lea to add/shift.
16886 ;; These can be created by move expanders.
16887
16888 (define_peephole2
16889 [(set (match_operand:SWI48 0 "register_operand" "")
16890 (plus:SWI48 (match_dup 0)
16891 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16892 "peep2_regno_dead_p (0, FLAGS_REG)"
16893 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16894 (clobber (reg:CC FLAGS_REG))])])
16895
16896 (define_peephole2
16897 [(set (match_operand:SI 0 "register_operand" "")
16898 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16899 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16900 "TARGET_64BIT
16901 && peep2_regno_dead_p (0, FLAGS_REG)
16902 && REGNO (operands[0]) == REGNO (operands[1])"
16903 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16904 (clobber (reg:CC FLAGS_REG))])]
16905 "operands[2] = gen_lowpart (SImode, operands[2]);")
16906
16907 (define_peephole2
16908 [(set (match_operand:SWI48 0 "register_operand" "")
16909 (mult:SWI48 (match_dup 0)
16910 (match_operand:SWI48 1 "const_int_operand" "")))]
16911 "exact_log2 (INTVAL (operands[1])) >= 0
16912 && peep2_regno_dead_p (0, FLAGS_REG)"
16913 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16914 (clobber (reg:CC FLAGS_REG))])]
16915 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16916
16917 (define_peephole2
16918 [(set (match_operand:SI 0 "register_operand" "")
16919 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16920 (match_operand:DI 2 "const_int_operand" "")) 0))]
16921 "TARGET_64BIT
16922 && exact_log2 (INTVAL (operands[2])) >= 0
16923 && REGNO (operands[0]) == REGNO (operands[1])
16924 && peep2_regno_dead_p (0, FLAGS_REG)"
16925 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16926 (clobber (reg:CC FLAGS_REG))])]
16927 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16928
16929 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16930 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16931 ;; On many CPUs it is also faster, since special hardware to avoid esp
16932 ;; dependencies is present.
16933
16934 ;; While some of these conversions may be done using splitters, we use
16935 ;; peepholes in order to allow combine_stack_adjustments pass to see
16936 ;; nonobfuscated RTL.
16937
16938 ;; Convert prologue esp subtractions to push.
16939 ;; We need register to push. In order to keep verify_flow_info happy we have
16940 ;; two choices
16941 ;; - use scratch and clobber it in order to avoid dependencies
16942 ;; - use already live register
16943 ;; We can't use the second way right now, since there is no reliable way how to
16944 ;; verify that given register is live. First choice will also most likely in
16945 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16946 ;; call clobbered registers are dead. We may want to use base pointer as an
16947 ;; alternative when no register is available later.
16948
16949 (define_peephole2
16950 [(match_scratch:P 1 "r")
16951 (parallel [(set (reg:P SP_REG)
16952 (plus:P (reg:P SP_REG)
16953 (match_operand:P 0 "const_int_operand" "")))
16954 (clobber (reg:CC FLAGS_REG))
16955 (clobber (mem:BLK (scratch)))])]
16956 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16957 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16958 [(clobber (match_dup 1))
16959 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16960 (clobber (mem:BLK (scratch)))])])
16961
16962 (define_peephole2
16963 [(match_scratch:P 1 "r")
16964 (parallel [(set (reg:P SP_REG)
16965 (plus:P (reg:P SP_REG)
16966 (match_operand:P 0 "const_int_operand" "")))
16967 (clobber (reg:CC FLAGS_REG))
16968 (clobber (mem:BLK (scratch)))])]
16969 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16970 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16971 [(clobber (match_dup 1))
16972 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16973 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16974 (clobber (mem:BLK (scratch)))])])
16975
16976 ;; Convert esp subtractions to push.
16977 (define_peephole2
16978 [(match_scratch:P 1 "r")
16979 (parallel [(set (reg:P SP_REG)
16980 (plus:P (reg:P SP_REG)
16981 (match_operand:P 0 "const_int_operand" "")))
16982 (clobber (reg:CC FLAGS_REG))])]
16983 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16984 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16985 [(clobber (match_dup 1))
16986 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16987
16988 (define_peephole2
16989 [(match_scratch:P 1 "r")
16990 (parallel [(set (reg:P SP_REG)
16991 (plus:P (reg:P SP_REG)
16992 (match_operand:P 0 "const_int_operand" "")))
16993 (clobber (reg:CC FLAGS_REG))])]
16994 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16995 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16996 [(clobber (match_dup 1))
16997 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16998 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16999
17000 ;; Convert epilogue deallocator to pop.
17001 (define_peephole2
17002 [(match_scratch:P 1 "r")
17003 (parallel [(set (reg:P SP_REG)
17004 (plus:P (reg:P SP_REG)
17005 (match_operand:P 0 "const_int_operand" "")))
17006 (clobber (reg:CC FLAGS_REG))
17007 (clobber (mem:BLK (scratch)))])]
17008 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17009 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17010 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17011 (clobber (mem:BLK (scratch)))])])
17012
17013 ;; Two pops case is tricky, since pop causes dependency
17014 ;; on destination register. We use two registers if available.
17015 (define_peephole2
17016 [(match_scratch:P 1 "r")
17017 (match_scratch:P 2 "r")
17018 (parallel [(set (reg:P SP_REG)
17019 (plus:P (reg:P SP_REG)
17020 (match_operand:P 0 "const_int_operand" "")))
17021 (clobber (reg:CC FLAGS_REG))
17022 (clobber (mem:BLK (scratch)))])]
17023 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17024 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17025 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17026 (clobber (mem:BLK (scratch)))])
17027 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17028
17029 (define_peephole2
17030 [(match_scratch:P 1 "r")
17031 (parallel [(set (reg:P SP_REG)
17032 (plus:P (reg:P SP_REG)
17033 (match_operand:P 0 "const_int_operand" "")))
17034 (clobber (reg:CC FLAGS_REG))
17035 (clobber (mem:BLK (scratch)))])]
17036 "optimize_insn_for_size_p ()
17037 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17038 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17039 (clobber (mem:BLK (scratch)))])
17040 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17041
17042 ;; Convert esp additions to pop.
17043 (define_peephole2
17044 [(match_scratch:P 1 "r")
17045 (parallel [(set (reg:P SP_REG)
17046 (plus:P (reg:P SP_REG)
17047 (match_operand:P 0 "const_int_operand" "")))
17048 (clobber (reg:CC FLAGS_REG))])]
17049 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17050 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17051
17052 ;; Two pops case is tricky, since pop causes dependency
17053 ;; on destination register. We use two registers if available.
17054 (define_peephole2
17055 [(match_scratch:P 1 "r")
17056 (match_scratch:P 2 "r")
17057 (parallel [(set (reg:P SP_REG)
17058 (plus:P (reg:P SP_REG)
17059 (match_operand:P 0 "const_int_operand" "")))
17060 (clobber (reg:CC FLAGS_REG))])]
17061 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17062 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17063 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17064
17065 (define_peephole2
17066 [(match_scratch:P 1 "r")
17067 (parallel [(set (reg:P SP_REG)
17068 (plus:P (reg:P SP_REG)
17069 (match_operand:P 0 "const_int_operand" "")))
17070 (clobber (reg:CC FLAGS_REG))])]
17071 "optimize_insn_for_size_p ()
17072 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17073 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17074 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17075 \f
17076 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17077 ;; required and register dies. Similarly for 128 to -128.
17078 (define_peephole2
17079 [(set (match_operand 0 "flags_reg_operand" "")
17080 (match_operator 1 "compare_operator"
17081 [(match_operand 2 "register_operand" "")
17082 (match_operand 3 "const_int_operand" "")]))]
17083 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17084 && incdec_operand (operands[3], GET_MODE (operands[3])))
17085 || (!TARGET_FUSE_CMP_AND_BRANCH
17086 && INTVAL (operands[3]) == 128))
17087 && ix86_match_ccmode (insn, CCGCmode)
17088 && peep2_reg_dead_p (1, operands[2])"
17089 [(parallel [(set (match_dup 0)
17090 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17091 (clobber (match_dup 2))])])
17092 \f
17093 ;; Convert imul by three, five and nine into lea
17094 (define_peephole2
17095 [(parallel
17096 [(set (match_operand:SWI48 0 "register_operand" "")
17097 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17098 (match_operand:SWI48 2 "const_int_operand" "")))
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "INTVAL (operands[2]) == 3
17101 || INTVAL (operands[2]) == 5
17102 || INTVAL (operands[2]) == 9"
17103 [(set (match_dup 0)
17104 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17105 (match_dup 1)))]
17106 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17107
17108 (define_peephole2
17109 [(parallel
17110 [(set (match_operand:SWI48 0 "register_operand" "")
17111 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17112 (match_operand:SWI48 2 "const_int_operand" "")))
17113 (clobber (reg:CC FLAGS_REG))])]
17114 "optimize_insn_for_speed_p ()
17115 && (INTVAL (operands[2]) == 3
17116 || INTVAL (operands[2]) == 5
17117 || INTVAL (operands[2]) == 9)"
17118 [(set (match_dup 0) (match_dup 1))
17119 (set (match_dup 0)
17120 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17121 (match_dup 0)))]
17122 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17123
17124 ;; imul $32bit_imm, mem, reg is vector decoded, while
17125 ;; imul $32bit_imm, reg, reg is direct decoded.
17126 (define_peephole2
17127 [(match_scratch:SWI48 3 "r")
17128 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17129 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17130 (match_operand:SWI48 2 "immediate_operand" "")))
17131 (clobber (reg:CC FLAGS_REG))])]
17132 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17133 && !satisfies_constraint_K (operands[2])"
17134 [(set (match_dup 3) (match_dup 1))
17135 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17136 (clobber (reg:CC FLAGS_REG))])])
17137
17138 (define_peephole2
17139 [(match_scratch:SI 3 "r")
17140 (parallel [(set (match_operand:DI 0 "register_operand" "")
17141 (zero_extend:DI
17142 (mult:SI (match_operand:SI 1 "memory_operand" "")
17143 (match_operand:SI 2 "immediate_operand" ""))))
17144 (clobber (reg:CC FLAGS_REG))])]
17145 "TARGET_64BIT
17146 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17147 && !satisfies_constraint_K (operands[2])"
17148 [(set (match_dup 3) (match_dup 1))
17149 (parallel [(set (match_dup 0)
17150 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17151 (clobber (reg:CC FLAGS_REG))])])
17152
17153 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17154 ;; Convert it into imul reg, reg
17155 ;; It would be better to force assembler to encode instruction using long
17156 ;; immediate, but there is apparently no way to do so.
17157 (define_peephole2
17158 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17159 (mult:SWI248
17160 (match_operand:SWI248 1 "nonimmediate_operand" "")
17161 (match_operand:SWI248 2 "const_int_operand" "")))
17162 (clobber (reg:CC FLAGS_REG))])
17163 (match_scratch:SWI248 3 "r")]
17164 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17165 && satisfies_constraint_K (operands[2])"
17166 [(set (match_dup 3) (match_dup 2))
17167 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17168 (clobber (reg:CC FLAGS_REG))])]
17169 {
17170 if (!rtx_equal_p (operands[0], operands[1]))
17171 emit_move_insn (operands[0], operands[1]);
17172 })
17173
17174 ;; After splitting up read-modify operations, array accesses with memory
17175 ;; operands might end up in form:
17176 ;; sall $2, %eax
17177 ;; movl 4(%esp), %edx
17178 ;; addl %edx, %eax
17179 ;; instead of pre-splitting:
17180 ;; sall $2, %eax
17181 ;; addl 4(%esp), %eax
17182 ;; Turn it into:
17183 ;; movl 4(%esp), %edx
17184 ;; leal (%edx,%eax,4), %eax
17185
17186 (define_peephole2
17187 [(match_scratch:P 5 "r")
17188 (parallel [(set (match_operand 0 "register_operand" "")
17189 (ashift (match_operand 1 "register_operand" "")
17190 (match_operand 2 "const_int_operand" "")))
17191 (clobber (reg:CC FLAGS_REG))])
17192 (parallel [(set (match_operand 3 "register_operand" "")
17193 (plus (match_dup 0)
17194 (match_operand 4 "x86_64_general_operand" "")))
17195 (clobber (reg:CC FLAGS_REG))])]
17196 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17197 /* Validate MODE for lea. */
17198 && ((!TARGET_PARTIAL_REG_STALL
17199 && (GET_MODE (operands[0]) == QImode
17200 || GET_MODE (operands[0]) == HImode))
17201 || GET_MODE (operands[0]) == SImode
17202 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17203 && (rtx_equal_p (operands[0], operands[3])
17204 || peep2_reg_dead_p (2, operands[0]))
17205 /* We reorder load and the shift. */
17206 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17207 [(set (match_dup 5) (match_dup 4))
17208 (set (match_dup 0) (match_dup 1))]
17209 {
17210 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17211 int scale = 1 << INTVAL (operands[2]);
17212 rtx index = gen_lowpart (Pmode, operands[1]);
17213 rtx base = gen_lowpart (Pmode, operands[5]);
17214 rtx dest = gen_lowpart (mode, operands[3]);
17215
17216 operands[1] = gen_rtx_PLUS (Pmode, base,
17217 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17218 operands[5] = base;
17219 if (mode != Pmode)
17220 {
17221 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17222 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17223 }
17224 operands[0] = dest;
17225 })
17226 \f
17227 ;; Call-value patterns last so that the wildcard operand does not
17228 ;; disrupt insn-recog's switch tables.
17229
17230 (define_insn "*call_value_pop_0"
17231 [(set (match_operand 0 "" "")
17232 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17233 (match_operand:SI 2 "" "")))
17234 (set (reg:SI SP_REG)
17235 (plus:SI (reg:SI SP_REG)
17236 (match_operand:SI 3 "immediate_operand" "")))]
17237 "!TARGET_64BIT"
17238 {
17239 if (SIBLING_CALL_P (insn))
17240 return "jmp\t%P1";
17241 else
17242 return "call\t%P1";
17243 }
17244 [(set_attr "type" "callv")])
17245
17246 (define_insn "*call_value_pop_1"
17247 [(set (match_operand 0 "" "")
17248 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17249 (match_operand:SI 2 "" "")))
17250 (set (reg:SI SP_REG)
17251 (plus:SI (reg:SI SP_REG)
17252 (match_operand:SI 3 "immediate_operand" "i")))]
17253 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17254 {
17255 if (constant_call_address_operand (operands[1], Pmode))
17256 return "call\t%P1";
17257 return "call\t%A1";
17258 }
17259 [(set_attr "type" "callv")])
17260
17261 (define_insn "*sibcall_value_pop_1"
17262 [(set (match_operand 0 "" "")
17263 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17264 (match_operand:SI 2 "" "")))
17265 (set (reg:SI SP_REG)
17266 (plus:SI (reg:SI SP_REG)
17267 (match_operand:SI 3 "immediate_operand" "i,i")))]
17268 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17269 "@
17270 jmp\t%P1
17271 jmp\t%A1"
17272 [(set_attr "type" "callv")])
17273
17274 (define_insn "*call_value_0"
17275 [(set (match_operand 0 "" "")
17276 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17277 (match_operand:SI 2 "" "")))]
17278 "!TARGET_64BIT"
17279 {
17280 if (SIBLING_CALL_P (insn))
17281 return "jmp\t%P1";
17282 else
17283 return "call\t%P1";
17284 }
17285 [(set_attr "type" "callv")])
17286
17287 (define_insn "*call_value_0_rex64"
17288 [(set (match_operand 0 "" "")
17289 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17290 (match_operand:DI 2 "const_int_operand" "")))]
17291 "TARGET_64BIT"
17292 {
17293 if (SIBLING_CALL_P (insn))
17294 return "jmp\t%P1";
17295 else
17296 return "call\t%P1";
17297 }
17298 [(set_attr "type" "callv")])
17299
17300 (define_insn "*call_value_0_rex64_ms_sysv"
17301 [(set (match_operand 0 "" "")
17302 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17303 (match_operand:DI 2 "const_int_operand" "")))
17304 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17305 (clobber (reg:TI XMM6_REG))
17306 (clobber (reg:TI XMM7_REG))
17307 (clobber (reg:TI XMM8_REG))
17308 (clobber (reg:TI XMM9_REG))
17309 (clobber (reg:TI XMM10_REG))
17310 (clobber (reg:TI XMM11_REG))
17311 (clobber (reg:TI XMM12_REG))
17312 (clobber (reg:TI XMM13_REG))
17313 (clobber (reg:TI XMM14_REG))
17314 (clobber (reg:TI XMM15_REG))
17315 (clobber (reg:DI SI_REG))
17316 (clobber (reg:DI DI_REG))]
17317 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17318 {
17319 if (SIBLING_CALL_P (insn))
17320 return "jmp\t%P1";
17321 else
17322 return "call\t%P1";
17323 }
17324 [(set_attr "type" "callv")])
17325
17326 (define_insn "*call_value_1"
17327 [(set (match_operand 0 "" "")
17328 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17329 (match_operand:SI 2 "" "")))]
17330 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17331 {
17332 if (constant_call_address_operand (operands[1], Pmode))
17333 return "call\t%P1";
17334 return "call\t%A1";
17335 }
17336 [(set_attr "type" "callv")])
17337
17338 (define_insn "*sibcall_value_1"
17339 [(set (match_operand 0 "" "")
17340 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17341 (match_operand:SI 2 "" "")))]
17342 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17343 "@
17344 jmp\t%P1
17345 jmp\t%A1"
17346 [(set_attr "type" "callv")])
17347
17348 (define_insn "*call_value_1_rex64"
17349 [(set (match_operand 0 "" "")
17350 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17351 (match_operand:DI 2 "" "")))]
17352 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17353 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17354 {
17355 if (constant_call_address_operand (operands[1], Pmode))
17356 return "call\t%P1";
17357 return "call\t%A1";
17358 }
17359 [(set_attr "type" "callv")])
17360
17361 (define_insn "*call_value_1_rex64_ms_sysv"
17362 [(set (match_operand 0 "" "")
17363 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17364 (match_operand:DI 2 "" "")))
17365 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17366 (clobber (reg:TI XMM6_REG))
17367 (clobber (reg:TI XMM7_REG))
17368 (clobber (reg:TI XMM8_REG))
17369 (clobber (reg:TI XMM9_REG))
17370 (clobber (reg:TI XMM10_REG))
17371 (clobber (reg:TI XMM11_REG))
17372 (clobber (reg:TI XMM12_REG))
17373 (clobber (reg:TI XMM13_REG))
17374 (clobber (reg:TI XMM14_REG))
17375 (clobber (reg:TI XMM15_REG))
17376 (clobber (reg:DI SI_REG))
17377 (clobber (reg:DI DI_REG))]
17378 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17379 {
17380 if (constant_call_address_operand (operands[1], Pmode))
17381 return "call\t%P1";
17382 return "call\t%A1";
17383 }
17384 [(set_attr "type" "callv")])
17385
17386 (define_insn "*call_value_1_rex64_large"
17387 [(set (match_operand 0 "" "")
17388 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17389 (match_operand:DI 2 "" "")))]
17390 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17391 "call\t%A1"
17392 [(set_attr "type" "callv")])
17393
17394 (define_insn "*sibcall_value_1_rex64"
17395 [(set (match_operand 0 "" "")
17396 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17397 (match_operand:DI 2 "" "")))]
17398 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17399 "@
17400 jmp\t%P1
17401 jmp\t%A1"
17402 [(set_attr "type" "callv")])
17403 \f
17404 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17405 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17406 ;; caught for use by garbage collectors and the like. Using an insn that
17407 ;; maps to SIGILL makes it more likely the program will rightfully die.
17408 ;; Keeping with tradition, "6" is in honor of #UD.
17409 (define_insn "trap"
17410 [(trap_if (const_int 1) (const_int 6))]
17411 ""
17412 { return ASM_SHORT "0x0b0f"; }
17413 [(set_attr "length" "2")])
17414
17415 (define_expand "prefetch"
17416 [(prefetch (match_operand 0 "address_operand" "")
17417 (match_operand:SI 1 "const_int_operand" "")
17418 (match_operand:SI 2 "const_int_operand" ""))]
17419 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17420 {
17421 int rw = INTVAL (operands[1]);
17422 int locality = INTVAL (operands[2]);
17423
17424 gcc_assert (rw == 0 || rw == 1);
17425 gcc_assert (locality >= 0 && locality <= 3);
17426 gcc_assert (GET_MODE (operands[0]) == Pmode
17427 || GET_MODE (operands[0]) == VOIDmode);
17428
17429 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17430 supported by SSE counterpart or the SSE prefetch is not available
17431 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17432 of locality. */
17433 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17434 operands[2] = GEN_INT (3);
17435 else
17436 operands[1] = const0_rtx;
17437 })
17438
17439 (define_insn "*prefetch_sse_<mode>"
17440 [(prefetch (match_operand:P 0 "address_operand" "p")
17441 (const_int 0)
17442 (match_operand:SI 1 "const_int_operand" ""))]
17443 "TARGET_PREFETCH_SSE"
17444 {
17445 static const char * const patterns[4] = {
17446 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17447 };
17448
17449 int locality = INTVAL (operands[1]);
17450 gcc_assert (locality >= 0 && locality <= 3);
17451
17452 return patterns[locality];
17453 }
17454 [(set_attr "type" "sse")
17455 (set_attr "atom_sse_attr" "prefetch")
17456 (set (attr "length_address")
17457 (symbol_ref "memory_address_length (operands[0])"))
17458 (set_attr "memory" "none")])
17459
17460 (define_insn "*prefetch_3dnow_<mode>"
17461 [(prefetch (match_operand:P 0 "address_operand" "p")
17462 (match_operand:SI 1 "const_int_operand" "n")
17463 (const_int 3))]
17464 "TARGET_3DNOW"
17465 {
17466 if (INTVAL (operands[1]) == 0)
17467 return "prefetch\t%a0";
17468 else
17469 return "prefetchw\t%a0";
17470 }
17471 [(set_attr "type" "mmx")
17472 (set (attr "length_address")
17473 (symbol_ref "memory_address_length (operands[0])"))
17474 (set_attr "memory" "none")])
17475
17476 (define_expand "stack_protect_set"
17477 [(match_operand 0 "memory_operand" "")
17478 (match_operand 1 "memory_operand" "")]
17479 ""
17480 {
17481 rtx (*insn)(rtx, rtx);
17482
17483 #ifdef TARGET_THREAD_SSP_OFFSET
17484 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17485 insn = (TARGET_64BIT
17486 ? gen_stack_tls_protect_set_di
17487 : gen_stack_tls_protect_set_si);
17488 #else
17489 insn = (TARGET_64BIT
17490 ? gen_stack_protect_set_di
17491 : gen_stack_protect_set_si);
17492 #endif
17493
17494 emit_insn (insn (operands[0], operands[1]));
17495 DONE;
17496 })
17497
17498 (define_insn "stack_protect_set_<mode>"
17499 [(set (match_operand:P 0 "memory_operand" "=m")
17500 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17501 (set (match_scratch:P 2 "=&r") (const_int 0))
17502 (clobber (reg:CC FLAGS_REG))]
17503 ""
17504 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17505 [(set_attr "type" "multi")])
17506
17507 (define_insn "stack_tls_protect_set_<mode>"
17508 [(set (match_operand:P 0 "memory_operand" "=m")
17509 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17510 UNSPEC_SP_TLS_SET))
17511 (set (match_scratch:P 2 "=&r") (const_int 0))
17512 (clobber (reg:CC FLAGS_REG))]
17513 ""
17514 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17515 [(set_attr "type" "multi")])
17516
17517 (define_expand "stack_protect_test"
17518 [(match_operand 0 "memory_operand" "")
17519 (match_operand 1 "memory_operand" "")
17520 (match_operand 2 "" "")]
17521 ""
17522 {
17523 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17524
17525 rtx (*insn)(rtx, rtx, rtx);
17526
17527 #ifdef TARGET_THREAD_SSP_OFFSET
17528 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17529 insn = (TARGET_64BIT
17530 ? gen_stack_tls_protect_test_di
17531 : gen_stack_tls_protect_test_si);
17532 #else
17533 insn = (TARGET_64BIT
17534 ? gen_stack_protect_test_di
17535 : gen_stack_protect_test_si);
17536 #endif
17537
17538 emit_insn (insn (flags, operands[0], operands[1]));
17539
17540 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17541 flags, const0_rtx, operands[2]));
17542 DONE;
17543 })
17544
17545 (define_insn "stack_protect_test_<mode>"
17546 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17547 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17548 (match_operand:P 2 "memory_operand" "m")]
17549 UNSPEC_SP_TEST))
17550 (clobber (match_scratch:P 3 "=&r"))]
17551 ""
17552 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17553 [(set_attr "type" "multi")])
17554
17555 (define_insn "stack_tls_protect_test_<mode>"
17556 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17557 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17558 (match_operand:P 2 "const_int_operand" "i")]
17559 UNSPEC_SP_TLS_TEST))
17560 (clobber (match_scratch:P 3 "=r"))]
17561 ""
17562 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17563 [(set_attr "type" "multi")])
17564
17565 (define_insn "sse4_2_crc32<mode>"
17566 [(set (match_operand:SI 0 "register_operand" "=r")
17567 (unspec:SI
17568 [(match_operand:SI 1 "register_operand" "0")
17569 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17570 UNSPEC_CRC32))]
17571 "TARGET_SSE4_2 || TARGET_CRC32"
17572 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17573 [(set_attr "type" "sselog1")
17574 (set_attr "prefix_rep" "1")
17575 (set_attr "prefix_extra" "1")
17576 (set (attr "prefix_data16")
17577 (if_then_else (match_operand:HI 2 "" "")
17578 (const_string "1")
17579 (const_string "*")))
17580 (set (attr "prefix_rex")
17581 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17582 (const_string "1")
17583 (const_string "*")))
17584 (set_attr "mode" "SI")])
17585
17586 (define_insn "sse4_2_crc32di"
17587 [(set (match_operand:DI 0 "register_operand" "=r")
17588 (unspec:DI
17589 [(match_operand:DI 1 "register_operand" "0")
17590 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17591 UNSPEC_CRC32))]
17592 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17593 "crc32{q}\t{%2, %0|%0, %2}"
17594 [(set_attr "type" "sselog1")
17595 (set_attr "prefix_rep" "1")
17596 (set_attr "prefix_extra" "1")
17597 (set_attr "mode" "DI")])
17598
17599 (define_expand "rdpmc"
17600 [(match_operand:DI 0 "register_operand" "")
17601 (match_operand:SI 1 "register_operand" "")]
17602 ""
17603 {
17604 rtx reg = gen_reg_rtx (DImode);
17605 rtx si;
17606
17607 /* Force operand 1 into ECX. */
17608 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17609 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17610 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17611 UNSPECV_RDPMC);
17612
17613 if (TARGET_64BIT)
17614 {
17615 rtvec vec = rtvec_alloc (2);
17616 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17617 rtx upper = gen_reg_rtx (DImode);
17618 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17619 gen_rtvec (1, const0_rtx),
17620 UNSPECV_RDPMC);
17621 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17622 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17623 emit_insn (load);
17624 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17625 NULL, 1, OPTAB_DIRECT);
17626 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17627 OPTAB_DIRECT);
17628 }
17629 else
17630 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17631 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17632 DONE;
17633 })
17634
17635 (define_insn "*rdpmc"
17636 [(set (match_operand:DI 0 "register_operand" "=A")
17637 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17638 UNSPECV_RDPMC))]
17639 "!TARGET_64BIT"
17640 "rdpmc"
17641 [(set_attr "type" "other")
17642 (set_attr "length" "2")])
17643
17644 (define_insn "*rdpmc_rex64"
17645 [(set (match_operand:DI 0 "register_operand" "=a")
17646 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17647 UNSPECV_RDPMC))
17648 (set (match_operand:DI 1 "register_operand" "=d")
17649 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17650 "TARGET_64BIT"
17651 "rdpmc"
17652 [(set_attr "type" "other")
17653 (set_attr "length" "2")])
17654
17655 (define_expand "rdtsc"
17656 [(set (match_operand:DI 0 "register_operand" "")
17657 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17658 ""
17659 {
17660 if (TARGET_64BIT)
17661 {
17662 rtvec vec = rtvec_alloc (2);
17663 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17664 rtx upper = gen_reg_rtx (DImode);
17665 rtx lower = gen_reg_rtx (DImode);
17666 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17667 gen_rtvec (1, const0_rtx),
17668 UNSPECV_RDTSC);
17669 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17670 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17671 emit_insn (load);
17672 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17673 NULL, 1, OPTAB_DIRECT);
17674 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17675 OPTAB_DIRECT);
17676 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17677 DONE;
17678 }
17679 })
17680
17681 (define_insn "*rdtsc"
17682 [(set (match_operand:DI 0 "register_operand" "=A")
17683 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17684 "!TARGET_64BIT"
17685 "rdtsc"
17686 [(set_attr "type" "other")
17687 (set_attr "length" "2")])
17688
17689 (define_insn "*rdtsc_rex64"
17690 [(set (match_operand:DI 0 "register_operand" "=a")
17691 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17692 (set (match_operand:DI 1 "register_operand" "=d")
17693 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17694 "TARGET_64BIT"
17695 "rdtsc"
17696 [(set_attr "type" "other")
17697 (set_attr "length" "2")])
17698
17699 (define_expand "rdtscp"
17700 [(match_operand:DI 0 "register_operand" "")
17701 (match_operand:SI 1 "memory_operand" "")]
17702 ""
17703 {
17704 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17705 gen_rtvec (1, const0_rtx),
17706 UNSPECV_RDTSCP);
17707 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17708 gen_rtvec (1, const0_rtx),
17709 UNSPECV_RDTSCP);
17710 rtx reg = gen_reg_rtx (DImode);
17711 rtx tmp = gen_reg_rtx (SImode);
17712
17713 if (TARGET_64BIT)
17714 {
17715 rtvec vec = rtvec_alloc (3);
17716 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17717 rtx upper = gen_reg_rtx (DImode);
17718 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17719 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17720 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17721 emit_insn (load);
17722 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17723 NULL, 1, OPTAB_DIRECT);
17724 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17725 OPTAB_DIRECT);
17726 }
17727 else
17728 {
17729 rtvec vec = rtvec_alloc (2);
17730 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17731 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17732 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17733 emit_insn (load);
17734 }
17735 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17736 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17737 DONE;
17738 })
17739
17740 (define_insn "*rdtscp"
17741 [(set (match_operand:DI 0 "register_operand" "=A")
17742 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17743 (set (match_operand:SI 1 "register_operand" "=c")
17744 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17745 "!TARGET_64BIT"
17746 "rdtscp"
17747 [(set_attr "type" "other")
17748 (set_attr "length" "3")])
17749
17750 (define_insn "*rdtscp_rex64"
17751 [(set (match_operand:DI 0 "register_operand" "=a")
17752 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17753 (set (match_operand:DI 1 "register_operand" "=d")
17754 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17755 (set (match_operand:SI 2 "register_operand" "=c")
17756 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17757 "TARGET_64BIT"
17758 "rdtscp"
17759 [(set_attr "type" "other")
17760 (set_attr "length" "3")])
17761
17762 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17763 ;;
17764 ;; LWP instructions
17765 ;;
17766 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17767
17768 (define_expand "lwp_llwpcb"
17769 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17770 UNSPECV_LLWP_INTRINSIC)]
17771 "TARGET_LWP")
17772
17773 (define_insn "*lwp_llwpcb<mode>1"
17774 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17775 UNSPECV_LLWP_INTRINSIC)]
17776 "TARGET_LWP"
17777 "llwpcb\t%0"
17778 [(set_attr "type" "lwp")
17779 (set_attr "mode" "<MODE>")
17780 (set_attr "length" "5")])
17781
17782 (define_expand "lwp_slwpcb"
17783 [(set (match_operand 0 "register_operand" "=r")
17784 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17785 "TARGET_LWP"
17786 {
17787 if (TARGET_64BIT)
17788 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17789 else
17790 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17791 DONE;
17792 })
17793
17794 (define_insn "lwp_slwpcb<mode>"
17795 [(set (match_operand:P 0 "register_operand" "=r")
17796 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17797 "TARGET_LWP"
17798 "slwpcb\t%0"
17799 [(set_attr "type" "lwp")
17800 (set_attr "mode" "<MODE>")
17801 (set_attr "length" "5")])
17802
17803 (define_expand "lwp_lwpval<mode>3"
17804 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17805 (match_operand:SI 2 "nonimmediate_operand" "rm")
17806 (match_operand:SI 3 "const_int_operand" "i")]
17807 UNSPECV_LWPVAL_INTRINSIC)]
17808 "TARGET_LWP"
17809 "/* Avoid unused variable warning. */
17810 (void) operand0;")
17811
17812 (define_insn "*lwp_lwpval<mode>3_1"
17813 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17814 (match_operand:SI 1 "nonimmediate_operand" "rm")
17815 (match_operand:SI 2 "const_int_operand" "i")]
17816 UNSPECV_LWPVAL_INTRINSIC)]
17817 "TARGET_LWP"
17818 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17819 [(set_attr "type" "lwp")
17820 (set_attr "mode" "<MODE>")
17821 (set (attr "length")
17822 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17823
17824 (define_expand "lwp_lwpins<mode>3"
17825 [(set (reg:CCC FLAGS_REG)
17826 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17827 (match_operand:SI 2 "nonimmediate_operand" "rm")
17828 (match_operand:SI 3 "const_int_operand" "i")]
17829 UNSPECV_LWPINS_INTRINSIC))
17830 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17831 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17832 "TARGET_LWP")
17833
17834 (define_insn "*lwp_lwpins<mode>3_1"
17835 [(set (reg:CCC FLAGS_REG)
17836 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17837 (match_operand:SI 1 "nonimmediate_operand" "rm")
17838 (match_operand:SI 2 "const_int_operand" "i")]
17839 UNSPECV_LWPINS_INTRINSIC))]
17840 "TARGET_LWP"
17841 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17842 [(set_attr "type" "lwp")
17843 (set_attr "mode" "<MODE>")
17844 (set (attr "length")
17845 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17846
17847 (define_insn "rdfsbase<mode>"
17848 [(set (match_operand:SWI48 0 "register_operand" "=r")
17849 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17850 "TARGET_64BIT && TARGET_FSGSBASE"
17851 "rdfsbase %0"
17852 [(set_attr "type" "other")
17853 (set_attr "prefix_extra" "2")])
17854
17855 (define_insn "rdgsbase<mode>"
17856 [(set (match_operand:SWI48 0 "register_operand" "=r")
17857 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17858 "TARGET_64BIT && TARGET_FSGSBASE"
17859 "rdgsbase %0"
17860 [(set_attr "type" "other")
17861 (set_attr "prefix_extra" "2")])
17862
17863 (define_insn "wrfsbase<mode>"
17864 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17865 UNSPECV_WRFSBASE)]
17866 "TARGET_64BIT && TARGET_FSGSBASE"
17867 "wrfsbase %0"
17868 [(set_attr "type" "other")
17869 (set_attr "prefix_extra" "2")])
17870
17871 (define_insn "wrgsbase<mode>"
17872 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17873 UNSPECV_WRGSBASE)]
17874 "TARGET_64BIT && TARGET_FSGSBASE"
17875 "wrgsbase %0"
17876 [(set_attr "type" "other")
17877 (set_attr "prefix_extra" "2")])
17878
17879 (define_expand "rdrand<mode>"
17880 [(set (match_operand:SWI248 0 "register_operand" "=r")
17881 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17882 "TARGET_RDRND"
17883 {
17884 rtx retry_label, insn, ccc;
17885
17886 retry_label = gen_label_rtx ();
17887
17888 emit_label (retry_label);
17889
17890 /* Generate rdrand. */
17891 emit_insn (gen_rdrand<mode>_1 (operands[0]));
17892
17893 /* Retry if the carry flag isn't valid. */
17894 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17895 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17896 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17897 gen_rtx_LABEL_REF (VOIDmode, retry_label));
17898 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17899 JUMP_LABEL (insn) = retry_label;
17900
17901 DONE;
17902 })
17903
17904 (define_insn "rdrand<mode>_1"
17905 [(set (match_operand:SWI248 0 "register_operand" "=r")
17906 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17907 "TARGET_RDRND"
17908 "rdrand %0"
17909 [(set_attr "type" "other")
17910 (set_attr "prefix_extra" "1")])
17911
17912 (include "mmx.md")
17913 (include "sse.md")
17914 (include "sync.md")