]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/i386/i386.md
common.opt (fsplit-stack): New option.
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
CommitLineData
d2836273 1;; GCC machine description for IA-32 and x86-64.
36210500 2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
d2af65b9 3;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4592bdcb 4;; Free Software Foundation, Inc.
886c62d1 5;; Mostly by William Schelter.
d2836273 6;; x86_64 support added by Jan Hubicka
e075ae69 7;;
188fc5b5 8;; This file is part of GCC.
e075ae69 9;;
188fc5b5 10;; GCC is free software; you can redistribute it and/or modify
886c62d1 11;; it under the terms of the GNU General Public License as published by
2f83c7d6 12;; the Free Software Foundation; either version 3, or (at your option)
886c62d1 13;; any later version.
e075ae69 14;;
188fc5b5 15;; GCC is distributed in the hope that it will be useful,
886c62d1
JVA
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.
e075ae69 19;;
886c62d1 20;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
21;; along with GCC; see the file COPYING3. If not see
22;; <http://www.gnu.org/licenses/>. */
e075ae69 23;;
4af3895e
JVA
24;; The original PO technology requires these to be ordered by speed,
25;; so that assigner will pick the fastest.
e075ae69 26;;
4af3895e 27;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
e075ae69 28;;
e075ae69 29;; The special asm out single letter directives following a '%' are:
a3a5e3d1
UB
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
a3a5e3d1
UB
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.
b91322f2 38;; Z -- likewise, with special suffixes for x87 instructions.
a3a5e3d1
UB
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
43a8b705 59;; Y -- print condition for XOP pcom* instruction.
a3a5e3d1
UB
60;; + -- print a branch hint as 'cs' or 'ds' prefix
61;; ; -- print a semicolon (after prefixes due to bug in older gas).
d1e74401 62;; @ -- print a segment register of thread base pointer load
8ee41eaf 63
4af3895e 64;; UNSPEC usage:
8ee41eaf 65
ed9955f9
UB
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
f996902d 79
ed9955f9
UB
80 ;; Prologue support
81 UNSPEC_STACK_ALLOC
82 UNSPEC_SET_GOT
ed9955f9
UB
83 UNSPEC_REG_SAVE
84 UNSPEC_DEF_CFA
85 UNSPEC_SET_RIP
86 UNSPEC_SET_GOT_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
7458026b 88 UNSPEC_STACK_CHECK
f996902d 89
ed9955f9
UB
90 ;; TLS support
91 UNSPEC_TP
92 UNSPEC_TLS_GD
93 UNSPEC_TLS_LD_BASE
94 UNSPEC_TLSDESC
f996902d 95
ed9955f9
UB
96 ;; Other random patterns
97 UNSPEC_SCAS
98 UNSPEC_FNSTSW
99 UNSPEC_SAHF
b79a08f6 100 UNSPEC_PARITY
ed9955f9
UB
101 UNSPEC_FSTCW
102 UNSPEC_ADD_CARRY
103 UNSPEC_FLDCW
104 UNSPEC_REP
105 UNSPEC_LD_MPIC ; load_macho_picbase
106 UNSPEC_TRUNC_NOOP
26ec9308 107 UNSPEC_DIV_ALREADY_SPLIT
8ee41eaf 108
ed9955f9
UB
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
d7b4b07a 128
ed9955f9
UB
129 ;; Generic math support
130 UNSPEC_COPYSIGN
131 UNSPEC_IEEE_MIN ; not commutative
132 UNSPEC_IEEE_MAX ; not commutative
1fb54135 133
ed9955f9
UB
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
d7b4b07a 145
ed9955f9
UB
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
253c7a00 153
ed9955f9
UB
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
77008252 165
ed9955f9
UB
166 UNSPEC_C2_FLAG
167 UNSPEC_FXAM_MEM
79cd820a 168
ed9955f9
UB
169 ;; SSP patterns
170 UNSPEC_SP_SET
171 UNSPEC_SP_TEST
172 UNSPEC_SP_TLS_SET
173 UNSPEC_SP_TLS_TEST
b1875f52 174
ed9955f9
UB
175 ;; SSSE3
176 UNSPEC_PSHUFB
177 UNSPEC_PSIGN
178 UNSPEC_PALIGNR
21efb4d4 179
ed9955f9
UB
180 ;; For SSE4A support
181 UNSPEC_EXTRQI
182 UNSPEC_EXTRQ
183 UNSPEC_INSERTQI
184 UNSPEC_INSERTQ
9a5cee02 185
ed9955f9
UB
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
3b8dd071 195
ed9955f9
UB
196 ;; For SSE4.2 support
197 UNSPEC_CRC32
198 UNSPEC_PCMPESTR
199 UNSPEC_PCMPISTR
04e1d06b 200
ed9955f9
UB
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
43a8b705 209
ed9955f9
UB
210 ;; For AES support
211 UNSPEC_AESENC
212 UNSPEC_AESENCLAST
213 UNSPEC_AESDEC
214 UNSPEC_AESDECLAST
215 UNSPEC_AESIMC
216 UNSPEC_AESKEYGENASSIST
8b96a312 217
ed9955f9
UB
218 ;; For PCLMUL support
219 UNSPEC_PCLMUL
95879c72 220
ed9955f9
UB
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
4ee89d5f
L
230 UNSPEC_VCVTPH2PS
231 UNSPEC_VCVTPS2PH
ed9955f9 232])
8ee41eaf 233
ed9955f9
UB
234(define_c_enum "unspecv" [
235 UNSPECV_BLOCKAGE
236 UNSPECV_STACK_PROBE
2de710b9 237 UNSPECV_PROBE_STACK_RANGE
ed9955f9
UB
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
17eba947 251 UNSPECV_NOPS
ed9955f9
UB
252 UNSPECV_VZEROALL
253 UNSPECV_VZEROUPPER
254 UNSPECV_RDTSC
255 UNSPECV_RDTSCP
256 UNSPECV_RDPMC
ed9955f9
UB
257 UNSPECV_LLWP_INTRINSIC
258 UNSPECV_SLWP_INTRINSIC
259 UNSPECV_LWPVAL_INTRINSIC
260 UNSPECV_LWPINS_INTRINSIC
4ee89d5f
L
261 UNSPECV_RDFSBASE
262 UNSPECV_RDGSBASE
263 UNSPECV_WRFSBASE
264 UNSPECV_WRGSBASE
265 UNSPECV_RDRAND
ed9955f9 266])
915119a5 267
84fbffb2 268;; Constants to represent pcomtrue/pcomfalse variants
04e1d06b
MM
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
43a8b705
HJ
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
8bc527af
SB
292;; Registers by name.
293(define_constants
29b74761
UB
294 [(AX_REG 0)
295 (DX_REG 1)
296 (CX_REG 2)
2e3f842f 297 (BX_REG 3)
8ec12e35
NF
298 (SI_REG 4)
299 (DI_REG 5)
29b74761 300 (BP_REG 6)
8bc527af 301 (SP_REG 7)
78168632
UB
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)
8bc527af
SB
310 (FLAGS_REG 17)
311 (FPSR_REG 18)
03c259ad 312 (FPCR_REG 19)
95879c72
L
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)
78168632
UB
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)
6c6094f1
UB
329 (R8_REG 37)
330 (R9_REG 38)
b0d95de8
UB
331 (R10_REG 39)
332 (R11_REG 40)
a952487c 333 (R12_REG 41)
2e3f842f 334 (R13_REG 42)
95879c72
L
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)
8bc527af
SB
343 ])
344
6343a50e
ZW
345;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
346;; from i386.c.
347
1b0c37d7
ZW
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
2ae0f82c 353\f
7ab91c5f 354;; Processor type.
b6837b94 355(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
1133125e 356 generic64,amdfam10,bdver1"
7ab91c5f 357 (const (symbol_ref "ix86_schedule")))
2ae0f82c 358
e075ae69
RH
359;; A basic instruction type. Refinements due to arguments to be
360;; provided in other attributes.
a269a03c 361(define_attr "type"
9a5834ae
ZW
362 "other,multi,
363 alu,alu1,negnot,imov,imovx,lea,
1b245ade 364 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
9a5834ae 365 icmp,test,ibr,setcc,icmov,
4977bab6 366 push,pop,call,callv,leave,
21efb4d4 367 str,bitmanip,
9199f050 368 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
c1b157a6 369 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
04e1d06b 370 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
3e901069 371 ssemuladd,sse4arg,lwp,
9a5834ae 372 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
e075ae69
RH
373 (const_string "other"))
374
6ef67412 375;; Main data type used by the insn
9a5834ae 376(define_attr "mode"
95879c72 377 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
6ef67412
JH
378 (const_string "unknown"))
379
3d34cd91
JH
380;; The CPU unit operations uses.
381(define_attr "unit" "integer,i387,sse,mmx,unknown"
9199f050 382 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
3d34cd91 383 (const_string "i387")
153b6955 384 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
04e1d06b
MM
385 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
386 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
3d34cd91 387 (const_string "sse")
9a5834ae 388 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
4c9c9a3d
JH
389 (const_string "mmx")
390 (eq_attr "type" "other")
391 (const_string "unknown")]
3d34cd91 392 (const_string "integer")))
6ef67412
JH
393
394;; The (bounding maximum) length of an instruction immediate.
395(define_attr "length_immediate" ""
21efb4d4
HJ
396 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
397 bitmanip")
6ef67412 398 (const_int 0)
3d34cd91 399 (eq_attr "unit" "i387,sse,mmx")
6ef67412 400 (const_int 0)
1b245ade
JH
401 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
402 imul,icmp,push,pop")
6ef67412
JH
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))
efcc7037
JH
414 ;; We don't know the size before shorten_branches. Expect
415 ;; the instruction to fit for better scheduling.
6ef67412 416 (eq_attr "type" "ibr")
efcc7037 417 (const_int 1)
6ef67412 418 ]
9a5834ae 419 (symbol_ref "/* Update immediate_length and other attributes! */
7637e42c 420 gcc_unreachable (),1")))
e075ae69 421
6ef67412
JH
422;; The (bounding maximum) length of an instruction address.
423(define_attr "length_address" ""
90c56b45 424 (cond [(eq_attr "type" "str,other,multi,fxch")
6ef67412
JH
425 (const_int 0)
426 (and (eq_attr "type" "call")
c7375e61 427 (match_operand 0 "constant_call_address_operand" ""))
6ef67412
JH
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" ""
725fd454
JJ
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)))
6ef67412
JH
445
446;; Set when string REP prefix is used.
6300f037 447(define_attr "prefix_rep" ""
725fd454
JJ
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)))
6ef67412
JH
454
455;; Set when 0f opcode prefix is used.
456(define_attr "prefix_0f" ""
6300f037 457 (if_then_else
21efb4d4 458 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
cb297538 459 (eq_attr "unit" "sse,mmx"))
6ef67412
JH
460 (const_int 1)
461 (const_int 0)))
462
56bab446 463;; Set when REX opcode prefix is used.
4977bab6 464(define_attr "prefix_rex" ""
a952487c
JJ
465 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
466 (const_int 0)
467 (and (eq_attr "mode" "DI")
725fd454
JJ
468 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
469 (eq_attr "unit" "!mmx")))
4977bab6
ZW
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)
a952487c
JJ
478 (and (eq_attr "type" "imovx")
479 (match_operand:QI 1 "ext_QIreg_operand" ""))
480 (const_int 1)
4977bab6
ZW
481 ]
482 (const_int 0)))
483
5c1a2bb1 484;; There are also additional prefixes in 3DNOW, SSSE3.
725fd454
JJ
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)))
10e4d956 495
95879c72
L
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
95879c72
L
502;; VEX W bit is used.
503(define_attr "prefix_vex_w" "" (const_int 0))
504
505;; The length of VEX prefix
725fd454
JJ
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.
95879c72 509(define_attr "length_vex" ""
725fd454
JJ
510 (if_then_else (and (eq_attr "prefix_0f" "1")
511 (eq_attr "prefix_extra" "0"))
95879c72
L
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
6ef67412
JH
519;; Set when modrm byte is used.
520(define_attr "modrm" ""
90c56b45 521 (cond [(eq_attr "type" "str,leave")
6ef67412 522 (const_int 0)
3d34cd91 523 (eq_attr "unit" "i387")
6ef67412 524 (const_int 0)
e075ae69 525 (and (eq_attr "type" "incdec")
725fd454
JJ
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" ""))))
6ef67412 529 (const_int 0)
e075ae69
RH
530 (and (eq_attr "type" "push")
531 (not (match_operand 1 "memory_operand" "")))
6ef67412 532 (const_int 0)
e075ae69
RH
533 (and (eq_attr "type" "pop")
534 (not (match_operand 0 "memory_operand" "")))
6ef67412 535 (const_int 0)
e075ae69 536 (and (eq_attr "type" "imov")
a952487c
JJ
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" ""))))))
6ef67412 544 (const_int 0)
c7375e61
EB
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)
a952487c
JJ
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))")
e075ae69 554 ]
6ef67412
JH
555 (const_int 1)))
556
557;; The (bounding maximum) length of an instruction in bytes.
edeacc14
UB
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.
6ef67412 561(define_attr "length" ""
edeacc14 562 (cond [(eq_attr "type" "other,multi,fistp,frndint")
6ef67412 563 (const_int 16)
a3033f34
EB
564 (eq_attr "type" "fcmp")
565 (const_int 4)
3d34cd91
JH
566 (eq_attr "unit" "i387")
567 (plus (const_int 2)
568 (plus (attr "prefix_data16")
95879c72
L
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")
725fd454 574 (plus (attr "length_immediate")
95879c72
L
575 (plus (attr "modrm")
576 (attr "length_address"))))]
6ef67412
JH
577 (plus (plus (attr "modrm")
578 (plus (attr "prefix_0f")
4977bab6 579 (plus (attr "prefix_rex")
10e4d956
L
580 (plus (attr "prefix_extra")
581 (const_int 1)))))
6ef67412
JH
582 (plus (attr "prefix_rep")
583 (plus (attr "prefix_data16")
584 (plus (attr "length_immediate")
585 (attr "length_address")))))))
e075ae69
RH
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"
519517fd 592 (cond [(eq_attr "type" "other,multi,str,lwp")
e075ae69 593 (const_string "unknown")
90c56b45 594 (eq_attr "type" "lea,fcmov,fpspc")
e075ae69 595 (const_string "none")
4977bab6 596 (eq_attr "type" "fistp,leave")
22fb740d 597 (const_string "both")
edeacc14
UB
598 (eq_attr "type" "frndint")
599 (const_string "load")
e075ae69
RH
600 (eq_attr "type" "push")
601 (if_then_else (match_operand 1 "memory_operand" "")
602 (const_string "both")
603 (const_string "store"))
abd2dd6d 604 (eq_attr "type" "pop")
e075ae69
RH
605 (if_then_else (match_operand 0 "memory_operand" "")
606 (const_string "both")
607 (const_string "load"))
abd2dd6d
JH
608 (eq_attr "type" "setcc")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "store")
611 (const_string "none"))
f56e86bd 612 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
e075ae69
RH
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"))
ef719a44 629 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
a269a03c 630 (match_operand 1 "memory_operand" ""))
e075ae69
RH
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")
9a5834ae 639 (and (eq_attr "type"
f527d196 640 "!alu1,negnot,ishift1,
21efb4d4 641 imov,imovx,icmp,test,bitmanip,
9a5834ae 642 fmov,fcmp,fsgn,
04e1d06b
MM
643 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
644 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
e075ae69
RH
645 (match_operand 2 "memory_operand" ""))
646 (const_string "load")
04e1d06b 647 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
e075ae69
RH
648 (match_operand 3 "memory_operand" ""))
649 (const_string "load")
650 ]
a269a03c
JC
651 (const_string "none")))
652
e075ae69
RH
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")
1b245ade 658 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
e075ae69
RH
659 (and (match_operand 0 "memory_displacement_operand" "")
660 (match_operand 1 "immediate_operand" "")))
661 (const_string "true")
890d52e8 662 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
e075ae69
RH
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
edeacc14
UB
674;; Defines rounding mode of an FP operation.
675
ff680eb1 676(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
edeacc14
UB
677 (const_string "any"))
678
b6837b94
JY
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
e075ae69
RH
685;; Describe a user's asm statement.
686(define_asm_attributes
687 [(set_attr "length" "128")
688 (set_attr "type" "multi")])
0e8c2b0d 689
3abcb3a7 690(define_code_iterator plusminus [plus minus])
d39d658d 691
d1c3b587
L
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")])
14c27152
UB
703(define_code_attr plusminus_carry_mnemonic
704 [(plus "adc") (minus "sbb")])
d39d658d
RIL
705
706;; Mark commutative operators as such in constraints.
d1c3b587
L
707(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
708 (minus "") (ss_minus "") (us_minus "")])
d39d658d 709
78e8956b
L
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
95879c72
L
716;; Mapping of signed/unsigned max and min
717(define_code_iterator maxmin [smax smin umax umin])
718
78e8956b 719;; Base name for integer and FP insn mnemonic
4a5528cc
UB
720(define_code_attr maxmin_int [(smax "maxs") (smin "mins")
721 (umax "maxu") (umin "minu")])
722(define_code_attr maxmin_float [(smax "max") (smin "min")])
78e8956b 723
fe6ae2da 724;; Mapping of logic operators
c8427064 725(define_code_iterator any_logic [and ior xor])
c8427064 726(define_code_iterator any_or [ior xor])
94237c92
L
727
728;; Base name for insn mnemonic.
4a5528cc 729(define_code_attr logic [(and "and") (ior "or") (xor "xor")])
94237c92 730
d72ebc16
UB
731;; Mapping of shift-right operators
732(define_code_iterator any_shiftrt [lshiftrt ashiftrt])
733
734;; Base name for define_insn
735(define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
736
737;; Base name for insn mnemonic.
738(define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
739
e0db9cc6
UB
740;; Mapping of rotate operators
741(define_code_iterator any_rotate [rotate rotatert])
742
743;; Base name for define_insn
744(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
745
746;; Base name for insn mnemonic.
747(define_code_attr rotate [(rotate "rol") (rotatert "ror")])
748
6dd18eb1
UB
749;; Mapping of abs neg operators
750(define_code_iterator absneg [abs neg])
751
752;; Base name for x87 insn mnemonic.
4a5528cc 753(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
6dd18eb1 754
68bc0874
UB
755;; Used in signed and unsigned widening multiplications.
756(define_code_iterator any_extend [sign_extend zero_extend])
757
85760734
UB
758;; Various insn prefixes for signed and unsigned operations.
759(define_code_attr u [(sign_extend "") (zero_extend "u")
760 (div "") (udiv "u")])
68bc0874
UB
761(define_code_attr s [(sign_extend "s") (zero_extend "u")])
762
c8427064
UB
763;; Used in signed and unsigned divisions.
764(define_code_iterator any_div [div udiv])
765
85760734
UB
766;; Instruction prefix for signed and unsigned operations.
767(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
768 (div "i") (udiv "")])
68bc0874 769
a8ecfc9f
UB
770;; 64bit single word integer modes.
771(define_mode_iterator SWI1248x [QI HI SI DI])
772
773;; 64bit single word integer modes without QImode and HImode.
774(define_mode_iterator SWI48x [SI DI])
775
776;; Single word integer modes.
3abcb3a7 777(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
d39d658d 778
a8ecfc9f
UB
779;; Single word integer modes without SImode and DImode.
780(define_mode_iterator SWI12 [QI HI])
781
79564f1e
UB
782;; Single word integer modes without DImode.
783(define_mode_iterator SWI124 [QI HI SI])
784
a8ecfc9f
UB
785;; Single word integer modes without QImode and DImode.
786(define_mode_iterator SWI24 [HI SI])
787
a00ce5fe
UB
788;; Single word integer modes without QImode.
789(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
4e7f50e5 790
d2407a7a
UB
791;; Single word integer modes without QImode and HImode.
792(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
793
458c00ff
UB
794;; All math-dependant single and double word integer modes.
795(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
796 (HI "TARGET_HIMODE_MATH")
797 SI DI (TI "TARGET_64BIT")])
798
bfb59746
UB
799;; Math-dependant single word integer modes.
800(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
801 (HI "TARGET_HIMODE_MATH")
802 SI (DI "TARGET_64BIT")])
803
e0db9cc6
UB
804;; Math-dependant single word integer modes without DImode.
805(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
806 (HI "TARGET_HIMODE_MATH")
807 SI])
808
458c00ff
UB
809;; Math-dependant single word integer modes without QImode.
810(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
811 SI (DI "TARGET_64BIT")])
d2407a7a 812
68bc0874 813;; Double word integer modes.
014753cc
UB
814(define_mode_iterator DWI [(DI "!TARGET_64BIT")
815 (TI "TARGET_64BIT")])
816
817;; Double word integer modes as mode attribute.
68bc0874
UB
818(define_mode_attr DWI [(SI "DI") (DI "TI")])
819(define_mode_attr dwi [(SI "di") (DI "ti")])
d2407a7a 820
014753cc
UB
821;; Half mode for double word integer modes.
822(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
823 (DI "TARGET_64BIT")])
824
d39d658d
RIL
825;; Instruction suffix for integer modes.
826(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
827
d1e74401
UB
828;; Pointer size prefix for integer modes (Intel asm dialect)
829(define_mode_attr iptrsize [(QI "BYTE")
830 (HI "WORD")
831 (SI "DWORD")
832 (DI "QWORD")])
833
d39d658d
RIL
834;; Register class for integer modes.
835(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
836
837;; Immediate operand constraint for integer modes.
0edb82cb 838(define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
d39d658d 839
d2407a7a 840;; General operand constraint for word modes.
cf2b99ce 841(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
d2407a7a
UB
842
843;; Immediate operand constraint for double integer modes.
68bc0874 844(define_mode_attr di [(SI "iF") (DI "e")])
d2407a7a 845
014753cc
UB
846;; Immediate operand constraint for shifts.
847(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
848
d39d658d
RIL
849;; General operand predicate for integer modes.
850(define_mode_attr general_operand
851 [(QI "general_operand")
852 (HI "general_operand")
853 (SI "general_operand")
d2407a7a
UB
854 (DI "x86_64_general_operand")
855 (TI "x86_64_general_operand")])
856
cf2b99ce
UB
857;; General sign/zero extend operand predicate for integer modes.
858(define_mode_attr general_szext_operand
859 [(QI "general_operand")
860 (HI "general_operand")
861 (SI "general_operand")
862 (DI "x86_64_szext_general_operand")])
863
9aa5922d
UB
864;; Immediate operand predicate for integer modes.
865(define_mode_attr immediate_operand
866 [(QI "immediate_operand")
867 (HI "immediate_operand")
868 (SI "immediate_operand")
869 (DI "x86_64_immediate_operand")])
870
cfc20f00
UB
871;; Nonmemory operand predicate for integer modes.
872(define_mode_attr nonmemory_operand
873 [(QI "nonmemory_operand")
874 (HI "nonmemory_operand")
875 (SI "nonmemory_operand")
876 (DI "x86_64_nonmemory_operand")])
877
014753cc
UB
878;; Operand predicate for shifts.
879(define_mode_attr shift_operand
880 [(QI "nonimmediate_operand")
881 (HI "nonimmediate_operand")
882 (SI "nonimmediate_operand")
883 (DI "shiftdi_operand")
884 (TI "register_operand")])
885
886;; Operand predicate for shift argument.
887(define_mode_attr shift_immediate_operand
888 [(QI "const_1_to_31_operand")
889 (HI "const_1_to_31_operand")
890 (SI "const_1_to_31_operand")
891 (DI "const_1_to_63_operand")])
892
893;; Input operand predicate for arithmetic left shifts.
894(define_mode_attr ashl_input_operand
895 [(QI "nonimmediate_operand")
896 (HI "nonimmediate_operand")
897 (SI "nonimmediate_operand")
898 (DI "ashldi_input_operand")
899 (TI "reg_or_pm1_operand")])
900
00188daa
UB
901;; SSE and x87 SFmode and DFmode floating point modes
902(define_mode_iterator MODEF [SF DF])
903
9199f050 904;; All x87 floating point modes
3abcb3a7 905(define_mode_iterator X87MODEF [SF DF XF])
6300f037 906
9199f050 907;; All integer modes handled by x87 fisttp operator.
3abcb3a7 908(define_mode_iterator X87MODEI [HI SI DI])
9199f050 909
0e8c2b0d 910;; All integer modes handled by integer x87 operators.
3abcb3a7 911(define_mode_iterator X87MODEI12 [HI SI])
9199f050 912
9199f050 913;; All integer modes handled by SSE cvtts?2si* operators.
3abcb3a7 914(define_mode_iterator SSEMODEI24 [SI DI])
9199f050 915
01302104
UB
916;; SSE asm suffix for floating point modes
917(define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
918
174c12c7
RH
919;; SSE vector mode corresponding to a scalar mode
920(define_mode_attr ssevecmode
921 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
380edc9f
UB
922
923;; Instruction suffix for REX 64bit operators.
924(define_mode_attr rex64suffix [(SI "") (DI "{q}")])
90b48492
KT
925
926;; This mode iterator allows :P to be used for patterns that operate on
927;; pointer-sized quantities. Exactly one of the two alternatives will match.
928(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
e075ae69 929\f
8fe75e43
RH
930;; Scheduling descriptions
931
af2728a4
JL
932(include "pentium.md")
933(include "ppro.md")
934(include "k6.md")
935(include "athlon.md")
cfe1b18f 936(include "geode.md")
b6837b94 937(include "atom.md")
8fe75e43
RH
938
939\f
08b1e29a 940;; Operand and operator predicates and constraints
8fe75e43
RH
941
942(include "predicates.md")
08b1e29a 943(include "constraints.md")
8fe75e43 944
309ada50 945\f
f90b7a5a 946;; Compare and branch/compare and store instructions.
886c62d1 947
a81f2330 948(define_expand "cbranch<mode>4"
f90b7a5a 949 [(set (reg:CC FLAGS_REG)
a81f2330
UB
950 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
951 (match_operand:SDWIM 2 "<general_operand>" "")))
f90b7a5a 952 (set (pc) (if_then_else
f53ea4f0 953 (match_operator 0 "ordered_comparison_operator"
a81f2330
UB
954 [(reg:CC FLAGS_REG) (const_int 0)])
955 (label_ref (match_operand 3 "" ""))
956 (pc)))]
f90b7a5a
PB
957 ""
958{
959 if (MEM_P (operands[1]) && MEM_P (operands[2]))
a81f2330 960 operands[1] = force_reg (<MODE>mode, operands[1]);
dc91d892
UB
961 ix86_expand_branch (GET_CODE (operands[0]),
962 operands[1], operands[2], operands[3]);
f90b7a5a
PB
963 DONE;
964})
965
a81f2330 966(define_expand "cstore<mode>4"
f90b7a5a 967 [(set (reg:CC FLAGS_REG)
a81f2330
UB
968 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
969 (match_operand:SWIM 3 "<general_operand>" "")))
f90b7a5a 970 (set (match_operand:QI 0 "register_operand" "")
f53ea4f0 971 (match_operator 1 "ordered_comparison_operator"
a81f2330 972 [(reg:CC FLAGS_REG) (const_int 0)]))]
f90b7a5a
PB
973 ""
974{
975 if (MEM_P (operands[2]) && MEM_P (operands[3]))
a81f2330 976 operands[2] = force_reg (<MODE>mode, operands[2]);
dc91d892
UB
977 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
978 operands[2], operands[3]);
c572e5ba 979 DONE;
0f40f9f7 980})
886c62d1 981
a81f2330 982(define_expand "cmp<mode>_1"
8bc527af 983 [(set (reg:CC FLAGS_REG)
a81f2330 984 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
a427621f 985 (match_operand:SWI48 1 "<general_operand>" "")))])
9076b9c1 986
a81f2330 987(define_insn "*cmp<mode>_ccno_1"
42fabf21 988 [(set (reg FLAGS_REG)
a81f2330
UB
989 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
990 (match_operand:SWI 1 "const0_operand" "")))]
9076b9c1 991 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 992 "@
a81f2330
UB
993 test{<imodesuffix>}\t%0, %0
994 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6ef67412
JH
995 [(set_attr "type" "test,icmp")
996 (set_attr "length_immediate" "0,1")
a81f2330 997 (set_attr "mode" "<MODE>")])
886c62d1 998
a81f2330 999(define_insn "*cmp<mode>_1"
42fabf21 1000 [(set (reg FLAGS_REG)
a81f2330
UB
1001 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1002 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1003 "ix86_match_ccmode (insn, CCmode)"
1004 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6ef67412 1005 [(set_attr "type" "icmp")
a81f2330 1006 (set_attr "mode" "<MODE>")])
e075ae69 1007
a81f2330 1008(define_insn "*cmp<mode>_minus_1"
42fabf21 1009 [(set (reg FLAGS_REG)
a81f2330
UB
1010 (compare
1011 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1012 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1013 (const_int 0)))]
9076b9c1 1014 "ix86_match_ccmode (insn, CCGOCmode)"
a81f2330 1015 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
9076b9c1 1016 [(set_attr "type" "icmp")
a81f2330 1017 (set_attr "mode" "<MODE>")])
9076b9c1 1018
e075ae69 1019(define_insn "*cmpqi_ext_1"
42fabf21 1020 [(set (reg FLAGS_REG)
9076b9c1 1021 (compare
d2836273 1022 (match_operand:QI 0 "general_operand" "Qm")
e075ae69
RH
1023 (subreg:QI
1024 (zero_extract:SI
d2836273 1025 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1026 (const_int 8)
1027 (const_int 8)) 0)))]
d2836273 1028 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1029 "cmp{b}\t{%h1, %0|%0, %h1}"
d2836273
JH
1030 [(set_attr "type" "icmp")
1031 (set_attr "mode" "QI")])
1032
1033(define_insn "*cmpqi_ext_1_rex64"
42fabf21 1034 [(set (reg FLAGS_REG)
d2836273 1035 (compare
3522082b 1036 (match_operand:QI 0 "register_operand" "Q")
d2836273
JH
1037 (subreg:QI
1038 (zero_extract:SI
1039 (match_operand 1 "ext_register_operand" "Q")
1040 (const_int 8)
1041 (const_int 8)) 0)))]
1042 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1043 "cmp{b}\t{%h1, %0|%0, %h1}"
6ef67412
JH
1044 [(set_attr "type" "icmp")
1045 (set_attr "mode" "QI")])
e075ae69
RH
1046
1047(define_insn "*cmpqi_ext_2"
42fabf21 1048 [(set (reg FLAGS_REG)
16189740 1049 (compare
e075ae69
RH
1050 (subreg:QI
1051 (zero_extract:SI
d2836273 1052 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
1053 (const_int 8)
1054 (const_int 8)) 0)
0edb82cb 1055 (match_operand:QI 1 "const0_operand" "")))]
16189740 1056 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 1057 "test{b}\t%h0, %h0"
6ef67412
JH
1058 [(set_attr "type" "test")
1059 (set_attr "length_immediate" "0")
1060 (set_attr "mode" "QI")])
e075ae69 1061
9076b9c1 1062(define_expand "cmpqi_ext_3"
8bc527af 1063 [(set (reg:CC FLAGS_REG)
e075ae69
RH
1064 (compare:CC
1065 (subreg:QI
1066 (zero_extract:SI
d2836273 1067 (match_operand 0 "ext_register_operand" "")
e075ae69
RH
1068 (const_int 8)
1069 (const_int 8)) 0)
a427621f 1070 (match_operand:QI 1 "immediate_operand" "")))])
9076b9c1 1071
a81f2330 1072(define_insn "*cmpqi_ext_3_insn"
42fabf21 1073 [(set (reg FLAGS_REG)
9076b9c1
JH
1074 (compare
1075 (subreg:QI
1076 (zero_extract:SI
d2836273 1077 (match_operand 0 "ext_register_operand" "Q")
9076b9c1
JH
1078 (const_int 8)
1079 (const_int 8)) 0)
d2836273
JH
1080 (match_operand:QI 1 "general_operand" "Qmn")))]
1081 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1082 "cmp{b}\t{%1, %h0|%h0, %1}"
d2836273 1083 [(set_attr "type" "icmp")
725fd454 1084 (set_attr "modrm" "1")
d2836273
JH
1085 (set_attr "mode" "QI")])
1086
a81f2330 1087(define_insn "*cmpqi_ext_3_insn_rex64"
42fabf21 1088 [(set (reg FLAGS_REG)
d2836273
JH
1089 (compare
1090 (subreg:QI
1091 (zero_extract:SI
1092 (match_operand 0 "ext_register_operand" "Q")
1093 (const_int 8)
1094 (const_int 8)) 0)
1095 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1096 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1097 "cmp{b}\t{%1, %h0|%h0, %1}"
6ef67412 1098 [(set_attr "type" "icmp")
725fd454 1099 (set_attr "modrm" "1")
6ef67412 1100 (set_attr "mode" "QI")])
e075ae69
RH
1101
1102(define_insn "*cmpqi_ext_4"
42fabf21 1103 [(set (reg FLAGS_REG)
9076b9c1 1104 (compare
e075ae69
RH
1105 (subreg:QI
1106 (zero_extract:SI
d2836273 1107 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
1108 (const_int 8)
1109 (const_int 8)) 0)
1110 (subreg:QI
1111 (zero_extract:SI
d2836273 1112 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1113 (const_int 8)
1114 (const_int 8)) 0)))]
9076b9c1 1115 "ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1116 "cmp{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
1117 [(set_attr "type" "icmp")
1118 (set_attr "mode" "QI")])
e075ae69
RH
1119
1120;; These implement float point compares.
1121;; %%% See if we can get away with VOIDmode operands on the actual insns,
1122;; which would allow mix and match FP modes on the compares. Which is what
1123;; the old patterns did, but with many more of them.
c572e5ba 1124
f90b7a5a
PB
1125(define_expand "cbranchxf4"
1126 [(set (reg:CC FLAGS_REG)
1127 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1128 (match_operand:XF 2 "nonmemory_operand" "")))
1129 (set (pc) (if_then_else
0948ccb2 1130 (match_operator 0 "ix86_fp_comparison_operator"
f90b7a5a
PB
1131 [(reg:CC FLAGS_REG)
1132 (const_int 0)])
1133 (label_ref (match_operand 3 "" ""))
1134 (pc)))]
1135 "TARGET_80387"
1136{
dc91d892
UB
1137 ix86_expand_branch (GET_CODE (operands[0]),
1138 operands[1], operands[2], operands[3]);
f90b7a5a
PB
1139 DONE;
1140})
1141
1142(define_expand "cstorexf4"
8bc527af 1143 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
1144 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1145 (match_operand:XF 3 "nonmemory_operand" "")))
1146 (set (match_operand:QI 0 "register_operand" "")
0948ccb2 1147 (match_operator 1 "ix86_fp_comparison_operator"
f90b7a5a
PB
1148 [(reg:CC FLAGS_REG)
1149 (const_int 0)]))]
2b589241 1150 "TARGET_80387"
2b589241 1151{
dc91d892
UB
1152 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1153 operands[2], operands[3]);
2b589241 1154 DONE;
0f40f9f7 1155})
2b589241 1156
f90b7a5a 1157(define_expand "cbranch<mode>4"
8bc527af 1158 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
1159 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1160 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1161 (set (pc) (if_then_else
0948ccb2 1162 (match_operator 0 "ix86_fp_comparison_operator"
f90b7a5a
PB
1163 [(reg:CC FLAGS_REG)
1164 (const_int 0)])
1165 (label_ref (match_operand 3 "" ""))
1166 (pc)))]
8766652c 1167 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
c572e5ba 1168{
dc91d892
UB
1169 ix86_expand_branch (GET_CODE (operands[0]),
1170 operands[1], operands[2], operands[3]);
c572e5ba 1171 DONE;
0f40f9f7 1172})
c572e5ba 1173
f90b7a5a 1174(define_expand "cstore<mode>4"
4a77c72b 1175 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
1176 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1177 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1178 (set (match_operand:QI 0 "register_operand" "")
0948ccb2 1179 (match_operator 1 "ix86_fp_comparison_operator"
f90b7a5a
PB
1180 [(reg:CC FLAGS_REG)
1181 (const_int 0)]))]
1182 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1183{
dc91d892
UB
1184 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1185 operands[2], operands[3]);
f90b7a5a
PB
1186 DONE;
1187})
1188
1189(define_expand "cbranchcc4"
1190 [(set (pc) (if_then_else
1191 (match_operator 0 "comparison_operator"
1192 [(match_operand 1 "flags_reg_operand" "")
1193 (match_operand 2 "const0_operand" "")])
1194 (label_ref (match_operand 3 "" ""))
1195 (pc)))]
1196 ""
1197{
dc91d892
UB
1198 ix86_expand_branch (GET_CODE (operands[0]),
1199 operands[1], operands[2], operands[3]);
f90b7a5a
PB
1200 DONE;
1201})
1202
1203(define_expand "cstorecc4"
1204 [(set (match_operand:QI 0 "register_operand" "")
1205 (match_operator 1 "comparison_operator"
1206 [(match_operand 2 "flags_reg_operand" "")
1207 (match_operand 3 "const0_operand" "")]))]
4a77c72b
PB
1208 ""
1209{
dc91d892
UB
1210 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1211 operands[2], operands[3]);
4a77c72b
PB
1212 DONE;
1213})
1214
f90b7a5a 1215
e075ae69
RH
1216;; FP compares, step 1:
1217;; Set the FP condition codes.
1218;;
1219;; CCFPmode compare with exceptions
1220;; CCFPUmode compare with no exceptions
fe4435d9 1221
7c82106f
UB
1222;; We may not use "#" to split and emit these, since the REG_DEAD notes
1223;; used to manage the reg stack popping would not be preserved.
1224
af12f8ea 1225(define_insn "*cmpfp_0"
45c8c47f
UB
1226 [(set (match_operand:HI 0 "register_operand" "=a")
1227 (unspec:HI
1228 [(compare:CCFP
af12f8ea 1229 (match_operand 1 "register_operand" "f")
0edb82cb 1230 (match_operand 2 "const0_operand" ""))]
45c8c47f 1231 UNSPEC_FNSTSW))]
27ac40e2 1232 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
af12f8ea 1233 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7c82106f 1234 "* return output_fp_compare (insn, operands, 0, 0);"
45c8c47f 1235 [(set_attr "type" "multi")
af12f8ea
UB
1236 (set_attr "unit" "i387")
1237 (set (attr "mode")
1238 (cond [(match_operand:SF 1 "" "")
1239 (const_string "SF")
1240 (match_operand:DF 1 "" "")
1241 (const_string "DF")
1242 ]
1243 (const_string "XF")))])
c572e5ba 1244
1406ee90
UB
1245(define_insn_and_split "*cmpfp_0_cc"
1246 [(set (reg:CCFP FLAGS_REG)
1247 (compare:CCFP
1248 (match_operand 1 "register_operand" "f")
0edb82cb 1249 (match_operand 2 "const0_operand" "")))
1406ee90
UB
1250 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1251 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1252 && TARGET_SAHF && !TARGET_CMOVE
1253 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1254 "#"
1255 "&& reload_completed"
1256 [(set (match_dup 0)
1257 (unspec:HI
1258 [(compare:CCFP (match_dup 1)(match_dup 2))]
1259 UNSPEC_FNSTSW))
1260 (set (reg:CC FLAGS_REG)
1261 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1262 ""
1263 [(set_attr "type" "multi")
1264 (set_attr "unit" "i387")
1265 (set (attr "mode")
1266 (cond [(match_operand:SF 1 "" "")
1267 (const_string "SF")
1268 (match_operand:DF 1 "" "")
1269 (const_string "DF")
1270 ]
1271 (const_string "XF")))])
1272
8766652c 1273(define_insn "*cmpfp_xf"
e075ae69
RH
1274 [(set (match_operand:HI 0 "register_operand" "=a")
1275 (unspec:HI
1276 [(compare:CCFP
8766652c
UB
1277 (match_operand:XF 1 "register_operand" "f")
1278 (match_operand:XF 2 "register_operand" "f"))]
8ee41eaf 1279 UNSPEC_FNSTSW))]
4fb21e90 1280 "TARGET_80387"
7c82106f 1281 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412 1282 [(set_attr "type" "multi")
af12f8ea 1283 (set_attr "unit" "i387")
8766652c 1284 (set_attr "mode" "XF")])
e075ae69 1285
1406ee90
UB
1286(define_insn_and_split "*cmpfp_xf_cc"
1287 [(set (reg:CCFP FLAGS_REG)
1288 (compare:CCFP
1289 (match_operand:XF 1 "register_operand" "f")
1290 (match_operand:XF 2 "register_operand" "f")))
1291 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1292 "TARGET_80387
1293 && TARGET_SAHF && !TARGET_CMOVE"
1294 "#"
1295 "&& reload_completed"
1296 [(set (match_dup 0)
1297 (unspec:HI
1298 [(compare:CCFP (match_dup 1)(match_dup 2))]
1299 UNSPEC_FNSTSW))
1300 (set (reg:CC FLAGS_REG)
1301 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1302 ""
1303 [(set_attr "type" "multi")
1304 (set_attr "unit" "i387")
1305 (set_attr "mode" "XF")])
1306
8766652c 1307(define_insn "*cmpfp_<mode>"
e075ae69
RH
1308 [(set (match_operand:HI 0 "register_operand" "=a")
1309 (unspec:HI
1310 [(compare:CCFP
00188daa
UB
1311 (match_operand:MODEF 1 "register_operand" "f")
1312 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
8ee41eaf 1313 UNSPEC_FNSTSW))]
2b589241 1314 "TARGET_80387"
7c82106f 1315 "* return output_fp_compare (insn, operands, 0, 0);"
2b589241 1316 [(set_attr "type" "multi")
af12f8ea 1317 (set_attr "unit" "i387")
8766652c 1318 (set_attr "mode" "<MODE>")])
2b589241 1319
1406ee90
UB
1320(define_insn_and_split "*cmpfp_<mode>_cc"
1321 [(set (reg:CCFP FLAGS_REG)
1322 (compare:CCFP
00188daa
UB
1323 (match_operand:MODEF 1 "register_operand" "f")
1324 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1406ee90
UB
1325 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1326 "TARGET_80387
1327 && TARGET_SAHF && !TARGET_CMOVE"
1328 "#"
1329 "&& reload_completed"
1330 [(set (match_dup 0)
1331 (unspec:HI
1332 [(compare:CCFP (match_dup 1)(match_dup 2))]
1333 UNSPEC_FNSTSW))
1334 (set (reg:CC FLAGS_REG)
1335 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1336 ""
1337 [(set_attr "type" "multi")
1338 (set_attr "unit" "i387")
1339 (set_attr "mode" "<MODE>")])
1340
7c82106f 1341(define_insn "*cmpfp_u"
e075ae69
RH
1342 [(set (match_operand:HI 0 "register_operand" "=a")
1343 (unspec:HI
1344 [(compare:CCFPU
1345 (match_operand 1 "register_operand" "f")
8ee41eaf
RH
1346 (match_operand 2 "register_operand" "f"))]
1347 UNSPEC_FNSTSW))]
27ac40e2 1348 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
e075ae69 1349 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7c82106f 1350 "* return output_fp_compare (insn, operands, 0, 1);"
6ef67412 1351 [(set_attr "type" "multi")
af12f8ea 1352 (set_attr "unit" "i387")
4977bab6
ZW
1353 (set (attr "mode")
1354 (cond [(match_operand:SF 1 "" "")
1355 (const_string "SF")
1356 (match_operand:DF 1 "" "")
1357 (const_string "DF")
1358 ]
1359 (const_string "XF")))])
08a7baac 1360
1406ee90
UB
1361(define_insn_and_split "*cmpfp_u_cc"
1362 [(set (reg:CCFPU FLAGS_REG)
1363 (compare:CCFPU
1364 (match_operand 1 "register_operand" "f")
1365 (match_operand 2 "register_operand" "f")))
1366 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1367 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1368 && TARGET_SAHF && !TARGET_CMOVE
1369 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1370 "#"
1371 "&& reload_completed"
1372 [(set (match_dup 0)
1373 (unspec:HI
1374 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1375 UNSPEC_FNSTSW))
1376 (set (reg:CC FLAGS_REG)
1377 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1378 ""
1379 [(set_attr "type" "multi")
1380 (set_attr "unit" "i387")
1381 (set (attr "mode")
1382 (cond [(match_operand:SF 1 "" "")
1383 (const_string "SF")
1384 (match_operand:DF 1 "" "")
1385 (const_string "DF")
1386 ]
1387 (const_string "XF")))])
1388
0e8c2b0d 1389(define_insn "*cmpfp_<mode>"
7c82106f
UB
1390 [(set (match_operand:HI 0 "register_operand" "=a")
1391 (unspec:HI
1392 [(compare:CCFP
1393 (match_operand 1 "register_operand" "f")
1394 (match_operator 3 "float_operator"
0e8c2b0d 1395 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
7c82106f 1396 UNSPEC_FNSTSW))]
27ac40e2 1397 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
3debdc1e 1398 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
7c82106f
UB
1399 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1400 "* return output_fp_compare (insn, operands, 0, 0);"
1401 [(set_attr "type" "multi")
af12f8ea 1402 (set_attr "unit" "i387")
7c82106f 1403 (set_attr "fp_int_src" "true")
0e8c2b0d 1404 (set_attr "mode" "<MODE>")])
e075ae69 1405
1406ee90
UB
1406(define_insn_and_split "*cmpfp_<mode>_cc"
1407 [(set (reg:CCFP FLAGS_REG)
1408 (compare:CCFP
1409 (match_operand 1 "register_operand" "f")
1410 (match_operator 3 "float_operator"
1411 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1412 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1413 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1414 && TARGET_SAHF && !TARGET_CMOVE
3debdc1e 1415 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1406ee90
UB
1416 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1417 "#"
1418 "&& reload_completed"
1419 [(set (match_dup 0)
1420 (unspec:HI
1421 [(compare:CCFP
1422 (match_dup 1)
1423 (match_op_dup 3 [(match_dup 2)]))]
1424 UNSPEC_FNSTSW))
1425 (set (reg:CC FLAGS_REG)
1426 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1427 ""
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "fp_int_src" "true")
1431 (set_attr "mode" "<MODE>")])
1432
e075ae69
RH
1433;; FP compares, step 2
1434;; Move the fpsw to ax.
1435
5ae27cfa 1436(define_insn "x86_fnstsw_1"
e075ae69 1437 [(set (match_operand:HI 0 "register_operand" "=a")
8bc527af 1438 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
2ae0f82c 1439 "TARGET_80387"
0f40f9f7 1440 "fnstsw\t%0"
725fd454 1441 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
6ef67412 1442 (set_attr "mode" "SI")
56bab446 1443 (set_attr "unit" "i387")])
e075ae69
RH
1444
1445;; FP compares, step 3
1446;; Get ax into flags, general case.
1447
1448(define_insn "x86_sahf_1"
8bc527af 1449 [(set (reg:CC FLAGS_REG)
3c2d980c
UB
1450 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1451 UNSPEC_SAHF))]
1452 "TARGET_SAHF"
419452fe 1453{
953c29f7
UB
1454#ifndef HAVE_AS_IX86_SAHF
1455 if (TARGET_64BIT)
1456 return ASM_BYTE "0x9e";
1457 else
419452fe 1458#endif
953c29f7 1459 return "sahf";
419452fe 1460}
e075ae69 1461 [(set_attr "length" "1")
0b5107cf 1462 (set_attr "athlon_decode" "vector")
21efb4d4 1463 (set_attr "amdfam10_decode" "direct")
56bab446 1464 (set_attr "mode" "SI")])
e075ae69
RH
1465
1466;; Pentium Pro can do steps 1 through 3 in one go.
4f3f76e6 1467;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
eaa49b49 1468(define_insn "*cmpfp_i_mixed"
8bc527af 1469 [(set (reg:CCFP FLAGS_REG)
b5c82fa1
PB
1470 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1471 (match_operand 1 "nonimmediate_operand" "f,xm")))]
eaa49b49 1472 "TARGET_MIX_SSE_I387
0644b628 1473 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
869d095e 1474 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
0644b628 1475 "* return output_fp_compare (insn, operands, 1, 0);"
26771da7 1476 [(set_attr "type" "fcmp,ssecomi")
95879c72 1477 (set_attr "prefix" "orig,maybe_vex")
4977bab6
ZW
1478 (set (attr "mode")
1479 (if_then_else (match_operand:SF 1 "" "")
1480 (const_string "SF")
1481 (const_string "DF")))
725fd454
JJ
1482 (set (attr "prefix_rep")
1483 (if_then_else (eq_attr "type" "ssecomi")
1484 (const_string "0")
1485 (const_string "*")))
1486 (set (attr "prefix_data16")
1487 (cond [(eq_attr "type" "fcmp")
1488 (const_string "*")
1489 (eq_attr "mode" "DF")
1490 (const_string "1")
1491 ]
1492 (const_string "0")))
21efb4d4
HJ
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")])
0644b628 1495
eaa49b49 1496(define_insn "*cmpfp_i_sse"
8bc527af 1497 [(set (reg:CCFP FLAGS_REG)
0644b628
JH
1498 (compare:CCFP (match_operand 0 "register_operand" "x")
1499 (match_operand 1 "nonimmediate_operand" "xm")))]
eaa49b49
RH
1500 "TARGET_SSE_MATH
1501 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
869d095e 1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
0644b628 1503 "* return output_fp_compare (insn, operands, 1, 0);"
26771da7 1504 [(set_attr "type" "ssecomi")
95879c72 1505 (set_attr "prefix" "maybe_vex")
4977bab6
ZW
1506 (set (attr "mode")
1507 (if_then_else (match_operand:SF 1 "" "")
1508 (const_string "SF")
1509 (const_string "DF")))
725fd454
JJ
1510 (set_attr "prefix_rep" "0")
1511 (set (attr "prefix_data16")
1512 (if_then_else (eq_attr "mode" "DF")
1513 (const_string "1")
1514 (const_string "0")))
21efb4d4
HJ
1515 (set_attr "athlon_decode" "vector")
1516 (set_attr "amdfam10_decode" "direct")])
0644b628 1517
eaa49b49
RH
1518(define_insn "*cmpfp_i_i387"
1519 [(set (reg:CCFP FLAGS_REG)
1520 (compare:CCFP (match_operand 0 "register_operand" "f")
1521 (match_operand 1 "register_operand" "f")))]
27ac40e2
UB
1522 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1523 && TARGET_CMOVE
00188daa 1524 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
e075ae69 1525 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
eaa49b49 1526 "* return output_fp_compare (insn, operands, 1, 0);"
309ada50 1527 [(set_attr "type" "fcmp")
4977bab6
ZW
1528 (set (attr "mode")
1529 (cond [(match_operand:SF 1 "" "")
1530 (const_string "SF")
1531 (match_operand:DF 1 "" "")
1532 (const_string "DF")
1533 ]
1534 (const_string "XF")))
21efb4d4
HJ
1535 (set_attr "athlon_decode" "vector")
1536 (set_attr "amdfam10_decode" "direct")])
0644b628 1537
eaa49b49 1538(define_insn "*cmpfp_iu_mixed"
8bc527af 1539 [(set (reg:CCFPU FLAGS_REG)
b5c82fa1
PB
1540 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1541 (match_operand 1 "nonimmediate_operand" "f,xm")))]
eaa49b49 1542 "TARGET_MIX_SSE_I387
0644b628
JH
1543 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1544 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1545 "* return output_fp_compare (insn, operands, 1, 1);"
26771da7 1546 [(set_attr "type" "fcmp,ssecomi")
95879c72 1547 (set_attr "prefix" "orig,maybe_vex")
4977bab6
ZW
1548 (set (attr "mode")
1549 (if_then_else (match_operand:SF 1 "" "")
1550 (const_string "SF")
1551 (const_string "DF")))
725fd454
JJ
1552 (set (attr "prefix_rep")
1553 (if_then_else (eq_attr "type" "ssecomi")
1554 (const_string "0")
1555 (const_string "*")))
1556 (set (attr "prefix_data16")
1557 (cond [(eq_attr "type" "fcmp")
1558 (const_string "*")
1559 (eq_attr "mode" "DF")
1560 (const_string "1")
1561 ]
1562 (const_string "0")))
21efb4d4
HJ
1563 (set_attr "athlon_decode" "vector")
1564 (set_attr "amdfam10_decode" "direct")])
0644b628 1565
eaa49b49 1566(define_insn "*cmpfp_iu_sse"
8bc527af 1567 [(set (reg:CCFPU FLAGS_REG)
0644b628
JH
1568 (compare:CCFPU (match_operand 0 "register_operand" "x")
1569 (match_operand 1 "nonimmediate_operand" "xm")))]
eaa49b49
RH
1570 "TARGET_SSE_MATH
1571 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
0644b628
JH
1572 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1573 "* return output_fp_compare (insn, operands, 1, 1);"
26771da7 1574 [(set_attr "type" "ssecomi")
95879c72 1575 (set_attr "prefix" "maybe_vex")
4977bab6
ZW
1576 (set (attr "mode")
1577 (if_then_else (match_operand:SF 1 "" "")
1578 (const_string "SF")
1579 (const_string "DF")))
725fd454
JJ
1580 (set_attr "prefix_rep" "0")
1581 (set (attr "prefix_data16")
1582 (if_then_else (eq_attr "mode" "DF")
1583 (const_string "1")
1584 (const_string "0")))
21efb4d4
HJ
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")])
eaa49b49
RH
1587
1588(define_insn "*cmpfp_iu_387"
1589 [(set (reg:CCFPU FLAGS_REG)
1590 (compare:CCFPU (match_operand 0 "register_operand" "f")
1591 (match_operand 1 "register_operand" "f")))]
27ac40e2
UB
1592 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1593 && TARGET_CMOVE
00188daa 1594 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
eaa49b49
RH
1595 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1596 "* return output_fp_compare (insn, operands, 1, 1);"
1597 [(set_attr "type" "fcmp")
1598 (set (attr "mode")
1599 (cond [(match_operand:SF 1 "" "")
1600 (const_string "SF")
1601 (match_operand:DF 1 "" "")
1602 (const_string "DF")
1603 ]
1604 (const_string "XF")))
21efb4d4
HJ
1605 (set_attr "athlon_decode" "vector")
1606 (set_attr "amdfam10_decode" "direct")])
e075ae69 1607\f
7d2c38c0 1608;; Push/pop instructions.
886c62d1 1609
a8ecfc9f
UB
1610(define_insn "*pushdi2_rex64"
1611 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1612 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1613 "TARGET_64BIT"
1614 "@
1615 push{q}\t%1
1616 #"
1617 [(set_attr "type" "push,multi")
1618 (set_attr "mode" "DI")])
1619
1620;; Convert impossible pushes of immediate to existing instructions.
1621;; First try to get scratch register and go through it. In case this
1622;; fails, push sign extended lower part first and then overwrite
1623;; upper part by 32bit move.
1624(define_peephole2
1625 [(match_scratch:DI 2 "r")
1626 (set (match_operand:DI 0 "push_operand" "")
1627 (match_operand:DI 1 "immediate_operand" ""))]
1628 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1629 && !x86_64_immediate_operand (operands[1], DImode)"
1630 [(set (match_dup 2) (match_dup 1))
cfc20f00 1631 (set (match_dup 0) (match_dup 2))])
a8ecfc9f
UB
1632
1633;; We need to define this as both peepholer and splitter for case
1634;; peephole2 pass is not run.
1635;; "&& 1" is needed to keep it from matching the previous pattern.
1636(define_peephole2
1637 [(set (match_operand:DI 0 "push_operand" "")
1638 (match_operand:DI 1 "immediate_operand" ""))]
1639 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1640 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1641 [(set (match_dup 0) (match_dup 1))
1642 (set (match_dup 2) (match_dup 3))]
1643{
b146446c 1644 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
a8ecfc9f
UB
1645
1646 operands[1] = gen_lowpart (DImode, operands[2]);
1647 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1648 GEN_INT (4)));
1649})
1650
1651(define_split
1652 [(set (match_operand:DI 0 "push_operand" "")
1653 (match_operand:DI 1 "immediate_operand" ""))]
1654 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1655 ? epilogue_completed : reload_completed)
1656 && !symbolic_operand (operands[1], DImode)
1657 && !x86_64_immediate_operand (operands[1], DImode)"
1658 [(set (match_dup 0) (match_dup 1))
1659 (set (match_dup 2) (match_dup 3))]
1660{
b146446c 1661 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
a8ecfc9f
UB
1662
1663 operands[1] = gen_lowpart (DImode, operands[2]);
1664 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1665 GEN_INT (4)));
1666})
1667
1668(define_insn "*pushdi2"
1669 [(set (match_operand:DI 0 "push_operand" "=<")
1670 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1671 "!TARGET_64BIT"
1672 "#")
1673
1674(define_split
1675 [(set (match_operand:DI 0 "push_operand" "")
1676 (match_operand:DI 1 "general_operand" ""))]
1677 "!TARGET_64BIT && reload_completed
1678 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1679 [(const_int 0)]
1680 "ix86_split_long_move (operands); DONE;")
1681
a4414093 1682(define_insn "*pushsi2"
e075ae69 1683 [(set (match_operand:SI 0 "push_operand" "=<")
2c5a510c 1684 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
0ec259ed 1685 "!TARGET_64BIT"
0f40f9f7 1686 "push{l}\t%1"
6ef67412
JH
1687 [(set_attr "type" "push")
1688 (set_attr "mode" "SI")])
4fb21e90 1689
a8ecfc9f
UB
1690;; emit_push_insn when it calls move_by_pieces requires an insn to
1691;; "push a byte/word". But actually we use pushl, which has the effect
1692;; of rounding the amount pushed up to a word.
1693
770b37b9 1694;; For TARGET_64BIT we always round up to 8 bytes.
a8ecfc9f
UB
1695(define_insn "*push<mode>2_rex64"
1696 [(set (match_operand:SWI124 0 "push_operand" "=X")
1697 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
0ec259ed 1698 "TARGET_64BIT"
0f40f9f7 1699 "push{q}\t%q1"
0ec259ed 1700 [(set_attr "type" "push")
a8ecfc9f 1701 (set_attr "mode" "DI")])
0ec259ed 1702
a8ecfc9f
UB
1703(define_insn "*push<mode>2"
1704 [(set (match_operand:SWI12 0 "push_operand" "=X")
1705 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
0ec259ed 1706 "!TARGET_64BIT"
a8ecfc9f 1707 "push{l}\t%k1"
6ef67412
JH
1708 [(set_attr "type" "push")
1709 (set_attr "mode" "SI")])
bdeb029c 1710
a8ecfc9f
UB
1711(define_insn "*push<mode>2_prologue"
1712 [(set (match_operand:P 0 "push_operand" "=<")
1713 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1714 (clobber (mem:BLK (scratch)))]
1715 ""
1716 "push{<imodesuffix>}\t%1"
1717 [(set_attr "type" "push")
1718 (set_attr "mode" "<MODE>")])
1719
d8b08ecd 1720(define_insn "*pop<mode>1"
7d2c38c0
UB
1721 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1722 (match_operand:P 1 "pop_operand" ">"))]
1723 ""
1724 "pop{<imodesuffix>}\t%0"
a8ecfc9f 1725 [(set_attr "type" "pop")
7d2c38c0 1726 (set_attr "mode" "<MODE>")])
a8ecfc9f 1727
7d2c38c0
UB
1728(define_insn "*pop<mode>1_epilogue"
1729 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1730 (match_operand:P 1 "pop_operand" ">"))
a8ecfc9f 1731 (clobber (mem:BLK (scratch)))]
7d2c38c0
UB
1732 ""
1733 "pop{<imodesuffix>}\t%0"
6ef67412 1734 [(set_attr "type" "pop")
7d2c38c0 1735 (set_attr "mode" "<MODE>")])
cb1b497e
UB
1736\f
1737;; Move instructions.
1738
1739(define_expand "movoi"
1740 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1741 (match_operand:OI 1 "general_operand" ""))]
1742 "TARGET_AVX"
1743 "ix86_expand_move (OImode, operands); DONE;")
1744
1745(define_expand "movti"
1746 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1747 (match_operand:TI 1 "nonimmediate_operand" ""))]
1748 "TARGET_64BIT || TARGET_SSE"
1749{
1750 if (TARGET_64BIT)
1751 ix86_expand_move (TImode, operands);
1752 else if (push_operand (operands[0], TImode))
1753 ix86_expand_push (TImode, operands[1]);
1754 else
1755 ix86_expand_vector_move (TImode, operands);
1756 DONE;
1757})
1758
1759;; This expands to what emit_move_complex would generate if we didn't
1760;; have a movti pattern. Having this avoids problems with reload on
1761;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1762;; to have around all the time.
1763(define_expand "movcdi"
1764 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1765 (match_operand:CDI 1 "general_operand" ""))]
1766 ""
1767{
1768 if (push_operand (operands[0], CDImode))
1769 emit_move_complex_push (CDImode, operands[0], operands[1]);
1770 else
1771 emit_move_complex_parts (operands[0], operands[1]);
1772 DONE;
1773})
1774
1775(define_expand "mov<mode>"
1776 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1777 (match_operand:SWI1248x 1 "general_operand" ""))]
1778 ""
1779 "ix86_expand_move (<MODE>mode, operands); DONE;")
c572e5ba 1780
a8ecfc9f
UB
1781(define_insn "*mov<mode>_xor"
1782 [(set (match_operand:SWI48 0 "register_operand" "=r")
1783 (match_operand:SWI48 1 "const0_operand" ""))
8bc527af 1784 (clobber (reg:CC FLAGS_REG))]
18bd082d 1785 "reload_completed"
a8ecfc9f 1786 "xor{l}\t%k0, %k0"
591702de 1787 [(set_attr "type" "alu1")
6ef67412
JH
1788 (set_attr "mode" "SI")
1789 (set_attr "length_immediate" "0")])
6300f037 1790
a8ecfc9f
UB
1791(define_insn "*mov<mode>_or"
1792 [(set (match_operand:SWI48 0 "register_operand" "=r")
1793 (match_operand:SWI48 1 "const_int_operand" ""))
8bc527af 1794 (clobber (reg:CC FLAGS_REG))]
87d9741e 1795 "reload_completed
18bd082d 1796 && operands[1] == constm1_rtx"
a8ecfc9f 1797 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
591702de 1798 [(set_attr "type" "alu1")
a8ecfc9f 1799 (set_attr "mode" "<MODE>")
6ef67412 1800 (set_attr "length_immediate" "1")])
e075ae69 1801
a8ecfc9f
UB
1802(define_insn "*movoi_internal_avx"
1803 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1804 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1805 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8f62128d 1806{
a8ecfc9f 1807 switch (which_alternative)
8f62128d 1808 {
a8ecfc9f
UB
1809 case 0:
1810 return "vxorps\t%0, %0, %0";
1811 case 1:
1812 case 2:
1813 if (misaligned_operand (operands[0], OImode)
1814 || misaligned_operand (operands[1], OImode))
1815 return "vmovdqu\t{%1, %0|%0, %1}";
1816 else
1817 return "vmovdqa\t{%1, %0|%0, %1}";
1818 default:
1819 gcc_unreachable ();
1820 }
1821}
1822 [(set_attr "type" "sselog1,ssemov,ssemov")
1823 (set_attr "prefix" "vex")
1824 (set_attr "mode" "OI")])
8f62128d 1825
a8ecfc9f
UB
1826(define_insn "*movti_internal_rex64"
1827 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1828 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1829 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1830{
1831 switch (which_alternative)
1832 {
1833 case 0:
1834 case 1:
1835 return "#";
1836 case 2:
1837 if (get_attr_mode (insn) == MODE_V4SF)
1838 return "%vxorps\t%0, %d0";
1839 else
1840 return "%vpxor\t%0, %d0";
1841 case 3:
1842 case 4:
1843 /* TDmode values are passed as TImode on the stack. Moving them
1844 to stack may result in unaligned memory access. */
1845 if (misaligned_operand (operands[0], TImode)
1846 || misaligned_operand (operands[1], TImode))
f75959a6 1847 {
a8ecfc9f
UB
1848 if (get_attr_mode (insn) == MODE_V4SF)
1849 return "%vmovups\t{%1, %0|%0, %1}";
1850 else
1851 return "%vmovdqu\t{%1, %0|%0, %1}";
1852 }
1853 else
1854 {
1855 if (get_attr_mode (insn) == MODE_V4SF)
1856 return "%vmovaps\t{%1, %0|%0, %1}";
1857 else
1858 return "%vmovdqa\t{%1, %0|%0, %1}";
f75959a6 1859 }
e075ae69 1860 default:
a8ecfc9f 1861 gcc_unreachable ();
886c62d1 1862 }
0f40f9f7 1863}
a8ecfc9f
UB
1864 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1865 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
f75959a6 1866 (set (attr "mode")
a8ecfc9f
UB
1867 (cond [(eq_attr "alternative" "2,3")
1868 (if_then_else
1869 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1870 (const_int 0))
1871 (const_string "V4SF")
1872 (const_string "TI"))
1873 (eq_attr "alternative" "4")
1874 (if_then_else
1875 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1876 (const_int 0))
1877 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1878 (const_int 0)))
1879 (const_string "V4SF")
1880 (const_string "TI"))]
1881 (const_string "DI")))])
886c62d1 1882
a8ecfc9f
UB
1883(define_split
1884 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1885 (match_operand:TI 1 "general_operand" ""))]
1886 "reload_completed
1887 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1888 [(const_int 0)]
1889 "ix86_split_long_move (operands); DONE;")
2f2a49e8 1890
a8ecfc9f
UB
1891(define_insn "*movti_internal_sse"
1892 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1893 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1894 "TARGET_SSE && !TARGET_64BIT
7656aee4 1895 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
886c62d1 1896{
a8ecfc9f 1897 switch (which_alternative)
b76c90cf 1898 {
a8ecfc9f
UB
1899 case 0:
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vxorps\t%0, %d0";
b76c90cf 1902 else
a8ecfc9f
UB
1903 return "%vpxor\t%0, %d0";
1904 case 1:
1905 case 2:
1906 /* TDmode values are passed as TImode on the stack. Moving them
1907 to stack may result in unaligned memory access. */
1908 if (misaligned_operand (operands[0], TImode)
1909 || misaligned_operand (operands[1], TImode))
1910 {
1911 if (get_attr_mode (insn) == MODE_V4SF)
1912 return "%vmovups\t{%1, %0|%0, %1}";
1913 else
1914 return "%vmovdqu\t{%1, %0|%0, %1}";
1915 }
1916 else
1917 {
1918 if (get_attr_mode (insn) == MODE_V4SF)
1919 return "%vmovaps\t{%1, %0|%0, %1}";
1920 else
1921 return "%vmovdqa\t{%1, %0|%0, %1}";
1922 }
0ec259ed 1923 default:
a8ecfc9f 1924 gcc_unreachable ();
0ec259ed 1925 }
0f40f9f7 1926}
a8ecfc9f
UB
1927 [(set_attr "type" "sselog1,ssemov,ssemov")
1928 (set_attr "prefix" "maybe_vex")
0ec259ed 1929 (set (attr "mode")
a8ecfc9f
UB
1930 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1931 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1932 (const_int 0)))
1933 (const_string "V4SF")
1934 (and (eq_attr "alternative" "2")
1935 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1936 (const_int 0)))
1937 (const_string "V4SF")]
1938 (const_string "TI")))])
886c62d1 1939
a8ecfc9f
UB
1940(define_insn "*movdi_internal_rex64"
1941 [(set (match_operand:DI 0 "nonimmediate_operand"
1942 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1943 (match_operand:DI 1 "general_operand"
1944 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1945 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
f31fce3f 1946{
e075ae69 1947 switch (get_attr_type (insn))
f31fce3f 1948 {
a8ecfc9f
UB
1949 case TYPE_SSECVT:
1950 if (SSE_REG_P (operands[0]))
1951 return "movq2dq\t{%1, %0|%0, %1}";
1952 else
1953 return "movdq2q\t{%1, %0|%0, %1}";
e075ae69 1954
a8ecfc9f
UB
1955 case TYPE_SSEMOV:
1956 if (TARGET_AVX)
1957 {
1958 if (get_attr_mode (insn) == MODE_TI)
1959 return "vmovdqa\t{%1, %0|%0, %1}";
1960 else
1961 return "vmovq\t{%1, %0|%0, %1}";
1962 }
d2836273 1963
a8ecfc9f
UB
1964 if (get_attr_mode (insn) == MODE_TI)
1965 return "movdqa\t{%1, %0|%0, %1}";
1966 /* FALLTHRU */
d2836273 1967
a8ecfc9f
UB
1968 case TYPE_MMXMOV:
1969 /* Moves from and into integer register is done using movd
1970 opcode with REX prefix. */
1971 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1972 return "movd\t{%1, %0|%0, %1}";
1973 return "movq\t{%1, %0|%0, %1}";
8c996513 1974
a8ecfc9f
UB
1975 case TYPE_SSELOG1:
1976 return "%vpxor\t%0, %d0";
e075ae69 1977
a8ecfc9f
UB
1978 case TYPE_MMX:
1979 return "pxor\t%0, %0";
f31fce3f 1980
a8ecfc9f
UB
1981 case TYPE_MULTI:
1982 return "#";
f31fce3f 1983
a8ecfc9f
UB
1984 case TYPE_LEA:
1985 return "lea{q}\t{%a1, %0|%0, %a1}";
f31fce3f 1986
a8ecfc9f
UB
1987 default:
1988 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1989 if (get_attr_mode (insn) == MODE_SI)
1990 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1991 else if (which_alternative == 2)
1992 return "movabs{q}\t{%1, %0|%0, %1}";
1993 else
1994 return "mov{q}\t{%1, %0|%0, %1}";
1995 }
1996}
1997 [(set (attr "type")
1998 (cond [(eq_attr "alternative" "5")
1999 (const_string "mmx")
2000 (eq_attr "alternative" "6,7,8,9,10")
2001 (const_string "mmxmov")
2002 (eq_attr "alternative" "11")
2003 (const_string "sselog1")
2004 (eq_attr "alternative" "12,13,14,15,16")
2005 (const_string "ssemov")
2006 (eq_attr "alternative" "17,18")
2007 (const_string "ssecvt")
2008 (eq_attr "alternative" "4")
2009 (const_string "multi")
2010 (match_operand:DI 1 "pic_32bit_operand" "")
2011 (const_string "lea")
2012 ]
2013 (const_string "imov")))
2014 (set (attr "modrm")
2015 (if_then_else
2016 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2017 (const_string "0")
2018 (const_string "*")))
2019 (set (attr "length_immediate")
2020 (if_then_else
2021 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2022 (const_string "8")
2023 (const_string "*")))
2024 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2025 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2026 (set (attr "prefix")
2027 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2028 (const_string "maybe_vex")
2029 (const_string "orig")))
2030 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
0ec259ed 2031
a8ecfc9f 2032;; Convert impossible stores of immediate to existing instructions.
f5143c46 2033;; First try to get scratch register and go through it. In case this
a8ecfc9f 2034;; fails, move by 32bit parts.
0ec259ed
JH
2035(define_peephole2
2036 [(match_scratch:DI 2 "r")
a8ecfc9f 2037 (set (match_operand:DI 0 "memory_operand" "")
0ec259ed
JH
2038 (match_operand:DI 1 "immediate_operand" ""))]
2039 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2040 && !x86_64_immediate_operand (operands[1], DImode)"
2041 [(set (match_dup 2) (match_dup 1))
cfc20f00 2042 (set (match_dup 0) (match_dup 2))])
0ec259ed
JH
2043
2044;; We need to define this as both peepholer and splitter for case
2045;; peephole2 pass is not run.
731edaed 2046;; "&& 1" is needed to keep it from matching the previous pattern.
0ec259ed 2047(define_peephole2
a8ecfc9f 2048 [(set (match_operand:DI 0 "memory_operand" "")
0ec259ed
JH
2049 (match_operand:DI 1 "immediate_operand" ""))]
2050 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
731edaed 2051 && !x86_64_immediate_operand (operands[1], DImode) && 1"
a8ecfc9f
UB
2052 [(set (match_dup 2) (match_dup 3))
2053 (set (match_dup 4) (match_dup 5))]
b146446c 2054 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
0ec259ed
JH
2055
2056(define_split
a8ecfc9f 2057 [(set (match_operand:DI 0 "memory_operand" "")
0ec259ed 2058 (match_operand:DI 1 "immediate_operand" ""))]
99523994 2059 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
6fb5fa3c 2060 ? epilogue_completed : reload_completed)
0ec259ed
JH
2061 && !symbolic_operand (operands[1], DImode)
2062 && !x86_64_immediate_operand (operands[1], DImode)"
a8ecfc9f
UB
2063 [(set (match_dup 2) (match_dup 3))
2064 (set (match_dup 4) (match_dup 5))]
b146446c 2065 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
0ec259ed 2066
a8ecfc9f 2067(define_insn "*movdi_internal"
d30c9461 2068 [(set (match_operand:DI 0 "nonimmediate_operand"
e2520c41 2069 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
d30c9461 2070 (match_operand:DI 1 "general_operand"
e2520c41 2071 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
f75959a6 2072 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
915119a5
BS
2073 "@
2074 #
2075 #
f75959a6 2076 pxor\t%0, %0
0f40f9f7
ZW
2077 movq\t{%1, %0|%0, %1}
2078 movq\t{%1, %0|%0, %1}
95879c72
L
2079 %vpxor\t%0, %d0
2080 %vmovq\t{%1, %0|%0, %1}
2081 %vmovdqa\t{%1, %0|%0, %1}
2082 %vmovq\t{%1, %0|%0, %1}
f75959a6 2083 xorps\t%0, %0
d30c9461
RH
2084 movlps\t{%1, %0|%0, %1}
2085 movaps\t{%1, %0|%0, %1}
2086 movlps\t{%1, %0|%0, %1}"
51df7179 2087 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
95879c72
L
2088 (set (attr "prefix")
2089 (if_then_else (eq_attr "alternative" "5,6,7,8")
2090 (const_string "vex")
2091 (const_string "orig")))
f75959a6 2092 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
dc0f0eb8 2093
e075ae69 2094(define_split
c76aab11 2095 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69 2096 (match_operand:DI 1 "general_operand" ""))]
6c12e488 2097 "!TARGET_64BIT && reload_completed
a8ecfc9f
UB
2098 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2099 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
26e5b205
JH
2100 [(const_int 0)]
2101 "ix86_split_long_move (operands); DONE;")
0ec259ed 2102
a8ecfc9f
UB
2103(define_insn "*movsi_internal"
2104 [(set (match_operand:SI 0 "nonimmediate_operand"
2105 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2106 (match_operand:SI 1 "general_operand"
2107 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2108 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
0ec259ed
JH
2109{
2110 switch (get_attr_type (insn))
2111 {
a8ecfc9f
UB
2112 case TYPE_SSELOG1:
2113 if (get_attr_mode (insn) == MODE_TI)
2114 return "%vpxor\t%0, %d0";
2115 return "%vxorps\t%0, %d0";
ed69105c 2116
5f90a099 2117 case TYPE_SSEMOV:
a8ecfc9f 2118 switch (get_attr_mode (insn))
95879c72 2119 {
a8ecfc9f
UB
2120 case MODE_TI:
2121 return "%vmovdqa\t{%1, %0|%0, %1}";
2122 case MODE_V4SF:
2123 return "%vmovaps\t{%1, %0|%0, %1}";
2124 case MODE_SI:
2125 return "%vmovd\t{%1, %0|%0, %1}";
2126 case MODE_SF:
2127 return "%vmovss\t{%1, %0|%0, %1}";
2128 default:
2129 gcc_unreachable ();
95879c72
L
2130 }
2131
87673f84 2132 case TYPE_MMX:
f75959a6 2133 return "pxor\t%0, %0";
ed69105c 2134
a8ecfc9f
UB
2135 case TYPE_MMXMOV:
2136 if (get_attr_mode (insn) == MODE_DI)
2137 return "movq\t{%1, %0|%0, %1}";
2138 return "movd\t{%1, %0|%0, %1}";
ed69105c 2139
0ec259ed 2140 case TYPE_LEA:
a8ecfc9f 2141 return "lea{l}\t{%a1, %0|%0, %a1}";
ed69105c 2142
0ec259ed 2143 default:
7637e42c 2144 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
a8ecfc9f 2145 return "mov{l}\t{%1, %0|%0, %1}";
0ec259ed 2146 }
0f40f9f7 2147}
0ec259ed 2148 [(set (attr "type")
a8ecfc9f 2149 (cond [(eq_attr "alternative" "2")
87673f84 2150 (const_string "mmx")
a8ecfc9f 2151 (eq_attr "alternative" "3,4,5")
3d34cd91 2152 (const_string "mmxmov")
a8ecfc9f 2153 (eq_attr "alternative" "6")
f75959a6 2154 (const_string "sselog1")
a8ecfc9f 2155 (eq_attr "alternative" "7,8,9,10,11")
3d34cd91 2156 (const_string "ssemov")
47efdea4 2157 (match_operand:DI 1 "pic_32bit_operand" "")
0ec259ed
JH
2158 (const_string "lea")
2159 ]
2160 (const_string "imov")))
95879c72 2161 (set (attr "prefix")
a8ecfc9f
UB
2162 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2163 (const_string "orig")
2164 (const_string "maybe_vex")))
2165 (set (attr "prefix_data16")
2166 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2167 (const_string "1")
2168 (const_string "*")))
2169 (set (attr "mode")
2170 (cond [(eq_attr "alternative" "2,3")
2171 (const_string "DI")
2172 (eq_attr "alternative" "6,7")
2173 (if_then_else
2174 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2175 (const_string "V4SF")
2176 (const_string "TI"))
2177 (and (eq_attr "alternative" "8,9,10,11")
2178 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2179 (const_string "SF")
2180 ]
2181 (const_string "SI")))])
2182
2183(define_insn "*movhi_internal"
2184 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2185 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2186 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2187{
2188 switch (get_attr_type (insn))
2189 {
2190 case TYPE_IMOVX:
2191 /* movzwl is faster than movw on p2 due to partial word stalls,
2192 though not as fast as an aligned movl. */
2193 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2194 default:
2195 if (get_attr_mode (insn) == MODE_SI)
2196 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2197 else
2198 return "mov{w}\t{%1, %0|%0, %1}";
2199 }
2200}
2201 [(set (attr "type")
2202 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2203 (const_int 0))
2204 (const_string "imov")
2205 (and (eq_attr "alternative" "0")
2206 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2207 (const_int 0))
2208 (eq (symbol_ref "TARGET_HIMODE_MATH")
2209 (const_int 0))))
2210 (const_string "imov")
2211 (and (eq_attr "alternative" "1,2")
2212 (match_operand:HI 1 "aligned_operand" ""))
2213 (const_string "imov")
2214 (and (ne (symbol_ref "TARGET_MOVX")
2215 (const_int 0))
2216 (eq_attr "alternative" "0,2"))
2217 (const_string "imovx")
2218 ]
2219 (const_string "imov")))
2220 (set (attr "mode")
2221 (cond [(eq_attr "type" "imovx")
2222 (const_string "SI")
2223 (and (eq_attr "alternative" "1,2")
2224 (match_operand:HI 1 "aligned_operand" ""))
2225 (const_string "SI")
2226 (and (eq_attr "alternative" "0")
2227 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2228 (const_int 0))
2229 (eq (symbol_ref "TARGET_HIMODE_MATH")
2230 (const_int 0))))
2231 (const_string "SI")
2232 ]
2233 (const_string "HI")))])
2234
2235;; Situation is quite tricky about when to choose full sized (SImode) move
2236;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2237;; partial register dependency machines (such as AMD Athlon), where QImode
2238;; moves issue extra dependency and for partial register stalls machines
2239;; that don't use QImode patterns (and QImode move cause stall on the next
2240;; instruction).
2241;;
2242;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2243;; register stall machines with, where we use QImode instructions, since
2244;; partial register stall can be caused there. Then we use movzx.
2245(define_insn "*movqi_internal"
2246 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2247 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2248 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2249{
2250 switch (get_attr_type (insn))
2251 {
2252 case TYPE_IMOVX:
2253 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2254 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2255 default:
2256 if (get_attr_mode (insn) == MODE_SI)
2257 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2258 else
2259 return "mov{b}\t{%1, %0|%0, %1}";
2260 }
2261}
2262 [(set (attr "type")
2263 (cond [(and (eq_attr "alternative" "5")
2264 (not (match_operand:QI 1 "aligned_operand" "")))
2265 (const_string "imovx")
2266 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2267 (const_int 0))
2268 (const_string "imov")
2269 (and (eq_attr "alternative" "3")
2270 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2271 (const_int 0))
2272 (eq (symbol_ref "TARGET_QIMODE_MATH")
2273 (const_int 0))))
2274 (const_string "imov")
2275 (eq_attr "alternative" "3,5")
2276 (const_string "imovx")
2277 (and (ne (symbol_ref "TARGET_MOVX")
2278 (const_int 0))
2279 (eq_attr "alternative" "2"))
2280 (const_string "imovx")
2281 ]
2282 (const_string "imov")))
2283 (set (attr "mode")
2284 (cond [(eq_attr "alternative" "3,4,5")
2285 (const_string "SI")
2286 (eq_attr "alternative" "6")
2287 (const_string "QI")
2288 (eq_attr "type" "imovx")
2289 (const_string "SI")
2290 (and (eq_attr "type" "imov")
2291 (and (eq_attr "alternative" "0,1")
2292 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2293 (const_int 0))
2294 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2295 (const_int 0))
2296 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2297 (const_int 0))))))
2298 (const_string "SI")
2299 ;; Avoid partial register stalls when not using QImode arithmetic
2300 (and (eq_attr "type" "imov")
2301 (and (eq_attr "alternative" "0,1")
2302 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2303 (const_int 0))
2304 (eq (symbol_ref "TARGET_QIMODE_MATH")
2305 (const_int 0)))))
2306 (const_string "SI")
2307 ]
2308 (const_string "QI")))])
0ec259ed 2309
d1f87653 2310;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
2311;; We fake an second form of instruction to force reload to load address
2312;; into register when rax is not available
a8ecfc9f
UB
2313(define_insn "*movabs<mode>_1"
2314 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2315 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
7e6dc358 2316 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 2317 "@
a8ecfc9f
UB
2318 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2319 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
0ec259ed 2320 [(set_attr "type" "imov")
7e6dc358
JJ
2321 (set_attr "modrm" "0,*")
2322 (set_attr "length_address" "8,0")
2323 (set_attr "length_immediate" "0,*")
0ec259ed 2324 (set_attr "memory" "store")
a8ecfc9f 2325 (set_attr "mode" "<MODE>")])
0ec259ed 2326
a8ecfc9f
UB
2327(define_insn "*movabs<mode>_2"
2328 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2329 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 2330 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 2331 "@
a8ecfc9f
UB
2332 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2333 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
2334 [(set_attr "type" "imov")
2335 (set_attr "modrm" "0,*")
2336 (set_attr "length_address" "8,0")
2337 (set_attr "length_immediate" "0")
2338 (set_attr "memory" "load")
a8ecfc9f 2339 (set_attr "mode" "<MODE>")])
0ec259ed 2340
a8ecfc9f
UB
2341(define_insn "*swap<mode>"
2342 [(set (match_operand:SWI48 0 "register_operand" "+r")
2343 (match_operand:SWI48 1 "register_operand" "+r"))
2344 (set (match_dup 1)
2345 (match_dup 0))]
2346 ""
2347 "xchg{<imodesuffix>}\t%1, %0"
2348 [(set_attr "type" "imov")
2349 (set_attr "mode" "<MODE>")
2350 (set_attr "pent_pair" "np")
2351 (set_attr "athlon_decode" "vector")
2352 (set_attr "amdfam10_decode" "double")])
0ec259ed 2353
a8ecfc9f
UB
2354(define_insn "*swap<mode>_1"
2355 [(set (match_operand:SWI12 0 "register_operand" "+r")
2356 (match_operand:SWI12 1 "register_operand" "+r"))
0ec259ed
JH
2357 (set (match_dup 1)
2358 (match_dup 0))]
a8ecfc9f
UB
2359 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2360 "xchg{l}\t%k1, %k0"
0ec259ed 2361 [(set_attr "type" "imov")
a8ecfc9f 2362 (set_attr "mode" "SI")
7cc6af0c 2363 (set_attr "pent_pair" "np")
21efb4d4 2364 (set_attr "athlon_decode" "vector")
4f3f76e6 2365 (set_attr "amdfam10_decode" "double")])
0ec259ed 2366
a8ecfc9f
UB
2367;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2368;; is disabled for AMDFAM10
2369(define_insn "*swap<mode>_2"
2370 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2371 (match_operand:SWI12 1 "register_operand" "+<r>"))
2372 (set (match_dup 1)
2373 (match_dup 0))]
2374 "TARGET_PARTIAL_REG_STALL"
2375 "xchg{<imodesuffix>}\t%1, %0"
2376 [(set_attr "type" "imov")
2377 (set_attr "mode" "<MODE>")
2378 (set_attr "pent_pair" "np")
2379 (set_attr "athlon_decode" "vector")])
2380
2381(define_expand "movstrict<mode>"
2382 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2383 (match_operand:SWI12 1 "general_operand" ""))]
2384 ""
2385{
2386 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2387 FAIL;
2388 /* Don't generate memory->memory moves, go through a register */
2389 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2390 operands[1] = force_reg (<MODE>mode, operands[1]);
2391})
2392
2393(define_insn "*movstrict<mode>_1"
2394 [(set (strict_low_part
2395 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2396 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2397 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2398 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2399 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2400 [(set_attr "type" "imov")
2401 (set_attr "mode" "<MODE>")])
2402
2403(define_insn "*movstrict<mode>_xor"
2404 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2405 (match_operand:SWI12 1 "const0_operand" ""))
2406 (clobber (reg:CC FLAGS_REG))]
2407 "reload_completed"
2408 "xor{<imodesuffix>}\t%0, %0"
2409 [(set_attr "type" "alu1")
2410 (set_attr "mode" "<MODE>")
2411 (set_attr "length_immediate" "0")])
2412
2413(define_insn "*mov<mode>_extv_1"
2414 [(set (match_operand:SWI24 0 "register_operand" "=R")
2415 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2416 (const_int 8)
2417 (const_int 8)))]
2418 ""
2419 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2420 [(set_attr "type" "imovx")
2421 (set_attr "mode" "SI")])
95879c72 2422
a8ecfc9f
UB
2423(define_insn "*movqi_extv_1_rex64"
2424 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2425 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2426 (const_int 8)
2427 (const_int 8)))]
2428 "TARGET_64BIT"
95879c72 2429{
a8ecfc9f 2430 switch (get_attr_type (insn))
95879c72 2431 {
a8ecfc9f
UB
2432 case TYPE_IMOVX:
2433 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
95879c72 2434 default:
a8ecfc9f 2435 return "mov{b}\t{%h1, %0|%0, %h1}";
95879c72
L
2436 }
2437}
a8ecfc9f
UB
2438 [(set (attr "type")
2439 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2440 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2441 (ne (symbol_ref "TARGET_MOVX")
2442 (const_int 0))))
2443 (const_string "imovx")
2444 (const_string "imov")))
2445 (set (attr "mode")
2446 (if_then_else (eq_attr "type" "imovx")
2447 (const_string "SI")
2448 (const_string "QI")))])
95879c72 2449
a8ecfc9f
UB
2450(define_insn "*movqi_extv_1"
2451 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2452 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2453 (const_int 8)
2454 (const_int 8)))]
2455 "!TARGET_64BIT"
ef719a44 2456{
a8ecfc9f
UB
2457 switch (get_attr_type (insn))
2458 {
2459 case TYPE_IMOVX:
2460 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2461 default:
2462 return "mov{b}\t{%h1, %0|%0, %h1}";
2463 }
2464}
2465 [(set (attr "type")
2466 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2467 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2468 (ne (symbol_ref "TARGET_MOVX")
2469 (const_int 0))))
2470 (const_string "imovx")
2471 (const_string "imov")))
2472 (set (attr "mode")
2473 (if_then_else (eq_attr "type" "imovx")
2474 (const_string "SI")
2475 (const_string "QI")))])
ef719a44 2476
a8ecfc9f
UB
2477(define_insn "*mov<mode>_extzv_1"
2478 [(set (match_operand:SWI48 0 "register_operand" "=R")
2479 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2480 (const_int 8)
2481 (const_int 8)))]
2482 ""
2483 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2484 [(set_attr "type" "imovx")
2485 (set_attr "mode" "SI")])
2486
2487(define_insn "*movqi_extzv_2_rex64"
2488 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2489 (subreg:QI
2490 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2491 (const_int 8)
2492 (const_int 8)) 0))]
2493 "TARGET_64BIT"
ef719a44 2494{
a8ecfc9f 2495 switch (get_attr_type (insn))
ef719a44 2496 {
a8ecfc9f
UB
2497 case TYPE_IMOVX:
2498 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
ef719a44 2499 default:
a8ecfc9f 2500 return "mov{b}\t{%h1, %0|%0, %h1}";
ef719a44
RH
2501 }
2502}
a8ecfc9f
UB
2503 [(set (attr "type")
2504 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2505 (ne (symbol_ref "TARGET_MOVX")
2506 (const_int 0)))
2507 (const_string "imovx")
2508 (const_string "imov")))
ef719a44 2509 (set (attr "mode")
a8ecfc9f
UB
2510 (if_then_else (eq_attr "type" "imovx")
2511 (const_string "SI")
2512 (const_string "QI")))])
ef719a44 2513
a8ecfc9f
UB
2514(define_insn "*movqi_extzv_2"
2515 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2516 (subreg:QI
2517 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2518 (const_int 8)
2519 (const_int 8)) 0))]
2520 "!TARGET_64BIT"
ef719a44 2521{
a8ecfc9f 2522 switch (get_attr_type (insn))
ef719a44 2523 {
a8ecfc9f
UB
2524 case TYPE_IMOVX:
2525 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
ef719a44 2526 default:
a8ecfc9f 2527 return "mov{b}\t{%h1, %0|%0, %h1}";
ef719a44
RH
2528 }
2529}
a8ecfc9f
UB
2530 [(set (attr "type")
2531 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2532 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2533 (ne (symbol_ref "TARGET_MOVX")
2534 (const_int 0))))
2535 (const_string "imovx")
2536 (const_string "imov")))
ef719a44 2537 (set (attr "mode")
a8ecfc9f
UB
2538 (if_then_else (eq_attr "type" "imovx")
2539 (const_string "SI")
2540 (const_string "QI")))])
ef719a44 2541
a8ecfc9f
UB
2542(define_expand "mov<mode>_insv_1"
2543 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2544 (const_int 8)
2545 (const_int 8))
a427621f 2546 (match_operand:SWI48 1 "nonmemory_operand" ""))])
ef719a44 2547
a8ecfc9f
UB
2548(define_insn "*mov<mode>_insv_1_rex64"
2549 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2550 (const_int 8)
2551 (const_int 8))
2552 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2553 "TARGET_64BIT"
2554 "mov{b}\t{%b1, %h0|%h0, %b1}"
2555 [(set_attr "type" "imov")
2556 (set_attr "mode" "QI")])
2557
2558(define_insn "*movsi_insv_1"
2559 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2560 (const_int 8)
2561 (const_int 8))
2562 (match_operand:SI 1 "general_operand" "Qmn"))]
2563 "!TARGET_64BIT"
2564 "mov{b}\t{%b1, %h0|%h0, %b1}"
2565 [(set_attr "type" "imov")
2566 (set_attr "mode" "QI")])
2567
2568(define_insn "*movqi_insv_2"
2569 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2570 (const_int 8)
2571 (const_int 8))
2572 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2573 (const_int 8)))]
ceca734e 2574 ""
a8ecfc9f
UB
2575 "mov{b}\t{%h1, %h0|%h0, %h1}"
2576 [(set_attr "type" "imov")
2577 (set_attr "mode" "QI")])
2578\f
cb1b497e 2579;; Floating point push instructions.
e075ae69 2580
bc051083
UB
2581(define_insn "*pushtf"
2582 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2583 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2584 "TARGET_SSE2"
0be5d99f 2585{
bc051083
UB
2586 /* This insn should be already split before reg-stack. */
2587 gcc_unreachable ();
0f40f9f7 2588}
bc051083
UB
2589 [(set_attr "type" "multi")
2590 (set_attr "unit" "sse,*,*")
2591 (set_attr "mode" "TF,SI,SI")])
2592
770b37b9
UB
2593(define_split
2594 [(set (match_operand:TF 0 "push_operand" "")
2595 (match_operand:TF 1 "sse_reg_operand" ""))]
2596 "TARGET_SSE2 && reload_completed"
2597 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2598 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2599
bc051083
UB
2600(define_split
2601 [(set (match_operand:TF 0 "push_operand" "")
2602 (match_operand:TF 1 "general_operand" ""))]
2603 "TARGET_SSE2 && reload_completed
2604 && !SSE_REG_P (operands[1])"
2605 [(const_int 0)]
2606 "ix86_split_long_move (operands); DONE;")
2607
bc051083
UB
2608(define_insn "*pushxf"
2609 [(set (match_operand:XF 0 "push_operand" "=<,<")
2610 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2611 "optimize_function_for_speed_p (cfun)"
2612{
2613 /* This insn should be already split before reg-stack. */
2614 gcc_unreachable ();
2615}
2616 [(set_attr "type" "multi")
2617 (set_attr "unit" "i387,*")
2618 (set_attr "mode" "XF,SI")])
2619
2620;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2621;; Size of pushxf using integer instructions is 3+3*memory operand size
2622;; Pushing using integer instructions is longer except for constants
2623;; and direct memory references (assuming that any given constant is pushed
2624;; only once, but this ought to be handled elsewhere).
2625
2626(define_insn "*pushxf_nointeger"
2627 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2628 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2629 "optimize_function_for_size_p (cfun)"
2630{
2631 /* This insn should be already split before reg-stack. */
2632 gcc_unreachable ();
2633}
2634 [(set_attr "type" "multi")
af12f8ea 2635 (set_attr "unit" "i387,*,*")
bc051083
UB
2636 (set_attr "mode" "XF,SI,SI")])
2637
2638(define_split
2639 [(set (match_operand:XF 0 "push_operand" "")
770b37b9 2640 (match_operand:XF 1 "fp_register_operand" ""))]
bc051083
UB
2641 "reload_completed"
2642 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2643 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
b1c6d018 2644 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
bc051083
UB
2645
2646(define_split
2647 [(set (match_operand:XF 0 "push_operand" "")
2648 (match_operand:XF 1 "general_operand" ""))]
2649 "reload_completed
770b37b9 2650 && !FP_REG_P (operands[1])"
bc051083
UB
2651 [(const_int 0)]
2652 "ix86_split_long_move (operands); DONE;")
2653
2654(define_insn "*pushdf"
2655 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2656 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2657 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2658{
2659 /* This insn should be already split before reg-stack. */
2660 gcc_unreachable ();
2661}
2662 [(set_attr "type" "multi")
2663 (set_attr "unit" "i387,*,*")
2664 (set_attr "mode" "DF,SI,DF")])
2665
2666;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2667;; Size of pushdf using integer instructions is 2+2*memory operand size
2668;; On the average, pushdf using integers can be still shorter. Allow this
2669;; pattern for optimize_size too.
2670
2671(define_insn "*pushdf_nointeger"
2672 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2673 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2674 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2675{
2676 /* This insn should be already split before reg-stack. */
2677 gcc_unreachable ();
2678}
2679 [(set_attr "type" "multi")
2680 (set_attr "unit" "i387,*,*,*")
2681 (set_attr "mode" "DF,SI,SI,DF")])
2682
2683;; %%% Kill this when call knows how to work this out.
2684(define_split
2685 [(set (match_operand:DF 0 "push_operand" "")
2686 (match_operand:DF 1 "any_fp_register_operand" ""))]
2687 "reload_completed"
2688 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
cb1b497e 2689 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
bc051083
UB
2690
2691(define_split
2692 [(set (match_operand:DF 0 "push_operand" "")
2693 (match_operand:DF 1 "general_operand" ""))]
2694 "reload_completed
2695 && !ANY_FP_REG_P (operands[1])"
2696 [(const_int 0)]
2697 "ix86_split_long_move (operands); DONE;")
0be5d99f 2698
0ec259ed 2699(define_insn "*pushsf_rex64"
a7efdc84 2700 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
b5c82fa1 2701 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
0ec259ed 2702 "TARGET_64BIT"
0ec259ed 2703{
7637e42c
NS
2704 /* Anything else should be already split before reg-stack. */
2705 gcc_assert (which_alternative == 1);
2706 return "push{q}\t%q1";
0f40f9f7 2707}
0ec259ed 2708 [(set_attr "type" "multi,push,multi")
af12f8ea 2709 (set_attr "unit" "i387,*,*")
0ec259ed
JH
2710 (set_attr "mode" "SF,DI,SF")])
2711
bc051083
UB
2712(define_insn "*pushsf"
2713 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2714 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2715 "!TARGET_64BIT"
2716{
2717 /* Anything else should be already split before reg-stack. */
2718 gcc_assert (which_alternative == 1);
2719 return "push{l}\t%1";
2720}
2721 [(set_attr "type" "multi,push,multi")
2722 (set_attr "unit" "i387,*,*")
2723 (set_attr "mode" "SF,SI,SF")])
2724
d7a29404
JH
2725(define_split
2726 [(set (match_operand:SF 0 "push_operand" "")
2727 (match_operand:SF 1 "memory_operand" ""))]
2728 "reload_completed
7656aee4 2729 && MEM_P (operands[1])
2a450639 2730 && (operands[2] = find_constant_src (insn))"
d7a29404 2731 [(set (match_dup 0)
2a450639 2732 (match_dup 2))])
d7a29404 2733
e075ae69
RH
2734;; %%% Kill this when call knows how to work this out.
2735(define_split
2736 [(set (match_operand:SF 0 "push_operand" "")
c3c637e3 2737 (match_operand:SF 1 "any_fp_register_operand" ""))]
bc051083
UB
2738 "reload_completed"
2739 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2740 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2741 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
cb1b497e
UB
2742\f
2743;; Floating point move instructions.
2744
2745(define_expand "movtf"
2746 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2747 (match_operand:TF 1 "nonimmediate_operand" ""))]
2748 "TARGET_SSE2"
2749{
2750 ix86_expand_move (TFmode, operands);
2751 DONE;
2752})
2753
2754(define_expand "mov<mode>"
2755 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2756 (match_operand:X87MODEF 1 "general_operand" ""))]
2757 ""
2758 "ix86_expand_move (<MODE>mode, operands); DONE;")
0ec259ed 2759
bc051083
UB
2760(define_insn "*movtf_internal"
2761 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2762 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2763 "TARGET_SSE2
2764 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
886c62d1 2765{
e075ae69 2766 switch (which_alternative)
886c62d1 2767 {
e075ae69 2768 case 0:
e075ae69 2769 case 1:
4977bab6 2770 if (get_attr_mode (insn) == MODE_V4SF)
95879c72
L
2771 return "%vmovaps\t{%1, %0|%0, %1}";
2772 else
bc051083
UB
2773 return "%vmovdqa\t{%1, %0|%0, %1}";
2774 case 2:
2775 if (get_attr_mode (insn) == MODE_V4SF)
2776 return "%vxorps\t%0, %d0";
2b04e52b 2777 else
bc051083
UB
2778 return "%vpxor\t%0, %d0";
2779 case 3:
2780 case 4:
2781 return "#";
e075ae69 2782 default:
7637e42c 2783 gcc_unreachable ();
e075ae69 2784 }
0f40f9f7 2785}
bc051083
UB
2786 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2787 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
4977bab6 2788 (set (attr "mode")
bc051083 2789 (cond [(eq_attr "alternative" "0,2")
4977bab6 2790 (if_then_else
bc051083
UB
2791 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2792 (const_int 0))
2793 (const_string "V4SF")
2794 (const_string "TI"))
2795 (eq_attr "alternative" "1")
4977bab6 2796 (if_then_else
bc051083 2797 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
4977bab6 2798 (const_int 0))
bc051083 2799 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
4977bab6
ZW
2800 (const_int 0)))
2801 (const_string "V4SF")
bc051083
UB
2802 (const_string "TI"))]
2803 (const_string "DI")))])
d7a29404 2804
bc051083
UB
2805(define_split
2806 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2807 (match_operand:TF 1 "general_operand" ""))]
2808 "reload_completed
2809 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2810 [(const_int 0)]
2811 "ix86_split_long_move (operands); DONE;")
2812
2813(define_insn "*movxf_internal"
2814 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2815 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2816 "optimize_function_for_speed_p (cfun)
2817 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2818 && (reload_in_progress || reload_completed
2819 || GET_CODE (operands[1]) != CONST_DOUBLE
2820 || memory_operand (operands[0], XFmode))"
0be5d99f 2821{
bc051083
UB
2822 switch (which_alternative)
2823 {
2824 case 0:
2825 case 1:
2826 return output_387_reg_move (insn, operands);
0be5d99f 2827
bc051083
UB
2828 case 2:
2829 return standard_80387_constant_opcode (operands[1]);
55953cea 2830
bc051083
UB
2831 case 3: case 4:
2832 return "#";
8fcaaa80 2833
bc051083
UB
2834 default:
2835 gcc_unreachable ();
2836 }
0f40f9f7 2837}
bc051083
UB
2838 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839 (set_attr "mode" "XF,XF,XF,SI,SI")])
0b5107cf 2840
bc051083
UB
2841;; Do not use integer registers when optimizing for size
2842(define_insn "*movxf_internal_nointeger"
2843 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2844 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2845 "optimize_function_for_size_p (cfun)
2846 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2847 && (reload_in_progress || reload_completed
2848 || standard_80387_constant_p (operands[1])
2849 || GET_CODE (operands[1]) != CONST_DOUBLE
2850 || memory_operand (operands[0], XFmode))"
f31fce3f 2851{
bc051083
UB
2852 switch (which_alternative)
2853 {
2854 case 0:
2855 case 1:
2856 return output_387_reg_move (insn, operands);
f31fce3f 2857
bc051083
UB
2858 case 2:
2859 return standard_80387_constant_opcode (operands[1]);
2860
2861 case 3: case 4:
2862 return "#";
2863 default:
2864 gcc_unreachable ();
2865 }
2866}
2867 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2868 (set_attr "mode" "XF,XF,XF,SI,SI")])
0ec259ed 2869
e075ae69 2870(define_split
bc051083
UB
2871 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2872 (match_operand:XF 1 "general_operand" ""))]
2873 "reload_completed
2874 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
8b2b54f9 2875 && ! (FP_REG_P (operands[0]) ||
bc051083 2876 (GET_CODE (operands[0]) == SUBREG
8b2b54f9
UB
2877 && FP_REG_P (SUBREG_REG (operands[0]))))
2878 && ! (FP_REG_P (operands[1]) ||
bc051083 2879 (GET_CODE (operands[1]) == SUBREG
8b2b54f9 2880 && FP_REG_P (SUBREG_REG (operands[1]))))"
2450a057 2881 [(const_int 0)]
26e5b205 2882 "ix86_split_long_move (operands); DONE;")
0be5d99f 2883
bc051083 2884(define_insn "*movdf_internal_rex64"
6c4ccfd8 2885 [(set (match_operand:DF 0 "nonimmediate_operand"
bc051083 2886 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
6c4ccfd8 2887 (match_operand:DF 1 "general_operand"
bc051083
UB
2888 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2889 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
d7a29404 2890 && (reload_in_progress || reload_completed
3987b9db 2891 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3debdc1e
JH
2892 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2893 && optimize_function_for_size_p (cfun)
8002331e 2894 && standard_80387_constant_p (operands[1]))
d7a29404 2895 || GET_CODE (operands[1]) != CONST_DOUBLE
bc051083 2896 || memory_operand (operands[0], DFmode))"
8fcaaa80
JH
2897{
2898 switch (which_alternative)
2899 {
2900 case 0:
8fcaaa80 2901 case 1:
d869c351 2902 return output_387_reg_move (insn, operands);
8fcaaa80
JH
2903
2904 case 2:
881b2a96 2905 return standard_80387_constant_opcode (operands[1]);
8fcaaa80
JH
2906
2907 case 3:
2908 case 4:
0f40f9f7 2909 return "#";
bc051083 2910
446988df 2911 case 5:
4977bab6
ZW
2912 switch (get_attr_mode (insn))
2913 {
2914 case MODE_V4SF:
95879c72 2915 return "%vxorps\t%0, %d0";
4977bab6 2916 case MODE_V2DF:
1133125e
HJ
2917 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2918 return "%vxorps\t%0, %d0";
2919 else
2920 return "%vxorpd\t%0, %d0";
4977bab6 2921 case MODE_TI:
1133125e
HJ
2922 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2923 return "%vxorps\t%0, %d0";
2924 else
2925 return "%vpxor\t%0, %d0";
4977bab6 2926 default:
7637e42c 2927 gcc_unreachable ();
4977bab6 2928 }
446988df 2929 case 6:
6c4ccfd8
RH
2930 case 7:
2931 case 8:
4977bab6
ZW
2932 switch (get_attr_mode (insn))
2933 {
2934 case MODE_V4SF:
95879c72 2935 return "%vmovaps\t{%1, %0|%0, %1}";
4977bab6 2936 case MODE_V2DF:
1133125e
HJ
2937 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938 return "%vmovaps\t{%1, %0|%0, %1}";
2939 else
2940 return "%vmovapd\t{%1, %0|%0, %1}";
6c4ccfd8 2941 case MODE_TI:
1133125e
HJ
2942 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2943 return "%vmovaps\t{%1, %0|%0, %1}";
2944 else
2945 return "%vmovdqa\t{%1, %0|%0, %1}";
6c4ccfd8 2946 case MODE_DI:
95879c72 2947 return "%vmovq\t{%1, %0|%0, %1}";
4977bab6 2948 case MODE_DF:
95879c72
L
2949 if (TARGET_AVX)
2950 {
2951 if (REG_P (operands[0]) && REG_P (operands[1]))
2952 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2953 else
2954 return "vmovsd\t{%1, %0|%0, %1}";
2955 }
2956 else
2957 return "movsd\t{%1, %0|%0, %1}";
6c4ccfd8 2958 case MODE_V1DF:
bc051083 2959 return "%vmovlpd\t{%1, %d0|%d0, %1}";
d30c9461 2960 case MODE_V2SF:
bc051083 2961 return "%vmovlps\t{%1, %d0|%d0, %1}";
4977bab6 2962 default:
7637e42c 2963 gcc_unreachable ();
4977bab6 2964 }
8fcaaa80 2965
bc051083
UB
2966 case 9:
2967 case 10:
2968 return "%vmovd\t{%1, %0|%0, %1}";
2969
8fcaaa80 2970 default:
bc051083 2971 gcc_unreachable();
8fcaaa80 2972 }
0f40f9f7 2973}
bc051083 2974 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
95879c72
L
2975 (set (attr "prefix")
2976 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2977 (const_string "orig")
2978 (const_string "maybe_vex")))
725fd454
JJ
2979 (set (attr "prefix_data16")
2980 (if_then_else (eq_attr "mode" "V1DF")
2981 (const_string "1")
2982 (const_string "*")))
4977bab6 2983 (set (attr "mode")
d30c9461
RH
2984 (cond [(eq_attr "alternative" "0,1,2")
2985 (const_string "DF")
bc051083
UB
2986 (eq_attr "alternative" "3,4,9,10")
2987 (const_string "DI")
6c4ccfd8
RH
2988
2989 /* For SSE1, we have many fewer alternatives. */
2990 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2991 (cond [(eq_attr "alternative" "5,6")
d30c9461 2992 (const_string "V4SF")
6c4ccfd8 2993 ]
d30c9461 2994 (const_string "V2SF"))
6c4ccfd8 2995
4977bab6
ZW
2996 /* xorps is one byte shorter. */
2997 (eq_attr "alternative" "5")
3debdc1e 2998 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
4977bab6
ZW
2999 (const_int 0))
3000 (const_string "V4SF")
3001 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3002 (const_int 0))
6c4ccfd8
RH
3003 (const_string "TI")
3004 ]
4977bab6 3005 (const_string "V2DF"))
6c4ccfd8 3006
4977bab6
ZW
3007 /* For architectures resolving dependencies on
3008 whole SSE registers use APD move to break dependency
3009 chains, otherwise use short move to avoid extra work.
3010
3011 movaps encodes one byte shorter. */
3012 (eq_attr "alternative" "6")
3013 (cond
3debdc1e 3014 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
6c4ccfd8
RH
3015 (const_int 0))
3016 (const_string "V4SF")
3017 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3018 (const_int 0))
3019 (const_string "V2DF")
3020 ]
4977bab6 3021 (const_string "DF"))
d1f87653 3022 /* For architectures resolving dependencies on register
4977bab6
ZW
3023 parts we may avoid extra work to zero out upper part
3024 of register. */
3025 (eq_attr "alternative" "7")
3026 (if_then_else
41afe4ef 3027 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
4977bab6 3028 (const_int 0))
6c4ccfd8
RH
3029 (const_string "V1DF")
3030 (const_string "DF"))
3031 ]
3032 (const_string "DF")))])
8fcaaa80 3033
bc051083 3034(define_insn "*movdf_internal"
ed69105c 3035 [(set (match_operand:DF 0 "nonimmediate_operand"
bc051083 3036 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
ed69105c 3037 (match_operand:DF 1 "general_operand"
bc051083
UB
3038 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3039 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3040 && optimize_function_for_speed_p (cfun)
3041 && TARGET_INTEGER_DFMODE_MOVES
ed69105c
RH
3042 && (reload_in_progress || reload_completed
3043 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3debdc1e
JH
3044 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3045 && optimize_function_for_size_p (cfun)
ed69105c
RH
3046 && standard_80387_constant_p (operands[1]))
3047 || GET_CODE (operands[1]) != CONST_DOUBLE
3048 || memory_operand (operands[0], DFmode))"
3049{
3050 switch (which_alternative)
3051 {
3052 case 0:
ed69105c 3053 case 1:
d869c351 3054 return output_387_reg_move (insn, operands);
ed69105c
RH
3055
3056 case 2:
3057 return standard_80387_constant_opcode (operands[1]);
3058
3059 case 3:
3060 case 4:
3061 return "#";
3062
3063 case 5:
3064 switch (get_attr_mode (insn))
3065 {
3066 case MODE_V4SF:
bc051083 3067 return "xorps\t%0, %0";
ed69105c 3068 case MODE_V2DF:
1133125e 3069 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
bc051083 3070 return "xorps\t%0, %0";
1133125e 3071 else
bc051083 3072 return "xorpd\t%0, %0";
ed69105c 3073 case MODE_TI:
1133125e 3074 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
bc051083 3075 return "xorps\t%0, %0";
1133125e 3076 else
bc051083 3077 return "pxor\t%0, %0";
ed69105c
RH
3078 default:
3079 gcc_unreachable ();
3080 }
3081 case 6:
3082 case 7:
3083 case 8:
3084 switch (get_attr_mode (insn))
3085 {
3086 case MODE_V4SF:
bc051083 3087 return "movaps\t{%1, %0|%0, %1}";
ed69105c 3088 case MODE_V2DF:
1133125e 3089 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
bc051083 3090 return "movaps\t{%1, %0|%0, %1}";
1133125e 3091 else
bc051083 3092 return "movapd\t{%1, %0|%0, %1}";
ed69105c 3093 case MODE_TI:
1133125e 3094 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
bc051083 3095 return "movaps\t{%1, %0|%0, %1}";
1133125e 3096 else
bc051083 3097 return "movdqa\t{%1, %0|%0, %1}";
ed69105c 3098 case MODE_DI:
bc051083 3099 return "movq\t{%1, %0|%0, %1}";
ed69105c 3100 case MODE_DF:
bc051083 3101 return "movsd\t{%1, %0|%0, %1}";
ed69105c 3102 case MODE_V1DF:
bc051083 3103 return "movlpd\t{%1, %0|%0, %1}";
ed69105c 3104 case MODE_V2SF:
bc051083 3105 return "movlps\t{%1, %0|%0, %1}";
ed69105c
RH
3106 default:
3107 gcc_unreachable ();
3108 }
3109
ed69105c
RH
3110 default:
3111 gcc_unreachable();
3112 }
3113}
bc051083 3114 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
725fd454
JJ
3115 (set (attr "prefix_data16")
3116 (if_then_else (eq_attr "mode" "V1DF")
3117 (const_string "1")
3118 (const_string "*")))
ed69105c
RH
3119 (set (attr "mode")
3120 (cond [(eq_attr "alternative" "0,1,2")
3121 (const_string "DF")
bc051083
UB
3122 (eq_attr "alternative" "3,4")
3123 (const_string "SI")
ed69105c
RH
3124
3125 /* For SSE1, we have many fewer alternatives. */
3126 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3127 (cond [(eq_attr "alternative" "5,6")
3128 (const_string "V4SF")
3129 ]
3130 (const_string "V2SF"))
3131
3132 /* xorps is one byte shorter. */
3133 (eq_attr "alternative" "5")
3debdc1e 3134 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
ed69105c
RH
3135 (const_int 0))
3136 (const_string "V4SF")
3137 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3138 (const_int 0))
3139 (const_string "TI")
3140 ]
3141 (const_string "V2DF"))
3142
3143 /* For architectures resolving dependencies on
3144 whole SSE registers use APD move to break dependency
3145 chains, otherwise use short move to avoid extra work.
3146
3147 movaps encodes one byte shorter. */
3148 (eq_attr "alternative" "6")
3149 (cond
3debdc1e 3150 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
ed69105c
RH
3151 (const_int 0))
3152 (const_string "V4SF")
3153 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3154 (const_int 0))
3155 (const_string "V2DF")
3156 ]
3157 (const_string "DF"))
3158 /* For architectures resolving dependencies on register
3159 parts we may avoid extra work to zero out upper part
3160 of register. */
3161 (eq_attr "alternative" "7")
3162 (if_then_else
3163 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3164 (const_int 0))
3165 (const_string "V1DF")
3166 (const_string "DF"))
3167 ]
3168 (const_string "DF")))])
3169
bc051083
UB
3170;; Moving is usually shorter when only FP registers are used. This separate
3171;; movdf pattern avoids the use of integer registers for FP operations
3172;; when optimizing for size.
3173
3174(define_insn "*movdf_internal_nointeger"
6c4ccfd8 3175 [(set (match_operand:DF 0 "nonimmediate_operand"
bc051083 3176 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
6c4ccfd8 3177 (match_operand:DF 1 "general_operand"
bc051083 3178 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
7656aee4 3179 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
bc051083
UB
3180 && ((optimize_function_for_size_p (cfun)
3181 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
d7a29404 3182 && (reload_in_progress || reload_completed
3987b9db 3183 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3debdc1e
JH
3184 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3185 && optimize_function_for_size_p (cfun)
bc051083 3186 && !memory_operand (operands[0], DFmode)
8002331e 3187 && standard_80387_constant_p (operands[1]))
d7a29404 3188 || GET_CODE (operands[1]) != CONST_DOUBLE
bc051083
UB
3189 || ((optimize_function_for_size_p (cfun)
3190 || !TARGET_MEMORY_MISMATCH_STALL
3191 || reload_in_progress || reload_completed)
3192 && memory_operand (operands[0], DFmode)))"
886c62d1 3193{
e075ae69 3194 switch (which_alternative)
886c62d1 3195 {
e075ae69 3196 case 0:
e075ae69 3197 case 1:
d869c351 3198 return output_387_reg_move (insn, operands);
886c62d1 3199
e075ae69 3200 case 2:
881b2a96 3201 return standard_80387_constant_opcode (operands[1]);
886c62d1 3202
e075ae69
RH
3203 case 3:
3204 case 4:
0f40f9f7 3205 return "#";
cb1b497e 3206
446988df 3207 case 5:
4977bab6
ZW
3208 switch (get_attr_mode (insn))
3209 {
3210 case MODE_V4SF:
bc051083 3211 return "%vxorps\t%0, %d0";
4977bab6 3212 case MODE_V2DF:
1133125e 3213 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
bc051083 3214 return "%vxorps\t%0, %d0";
1133125e 3215 else
bc051083 3216 return "%vxorpd\t%0, %d0";
4977bab6 3217 case MODE_TI:
1133125e 3218 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
bc051083 3219 return "%vxorps\t%0, %d0";
1133125e 3220 else
bc051083 3221 return "%vpxor\t%0, %d0";
4977bab6 3222 default:
7637e42c 3223 gcc_unreachable ();
4977bab6 3224 }
446988df 3225 case 6:
6c4ccfd8
RH
3226 case 7:
3227 case 8:
4977bab6
ZW
3228 switch (get_attr_mode (insn))
3229 {
3230 case MODE_V4SF:
bc051083 3231 return "%vmovaps\t{%1, %0|%0, %1}";
4977bab6 3232 case MODE_V2DF:
1133125e 3233 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
bc051083 3234 return "%vmovaps\t{%1, %0|%0, %1}";
1133125e 3235 else
bc051083 3236 return "%vmovapd\t{%1, %0|%0, %1}";
6c4ccfd8 3237 case MODE_TI:
1133125e 3238 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
bc051083 3239 return "%vmovaps\t{%1, %0|%0, %1}";
1133125e 3240 else
bc051083 3241 return "%vmovdqa\t{%1, %0|%0, %1}";
6c4ccfd8 3242 case MODE_DI:
bc051083 3243 return "%vmovq\t{%1, %0|%0, %1}";
4977bab6 3244 case MODE_DF:
bc051083
UB
3245 if (TARGET_AVX)
3246 {
3247 if (REG_P (operands[0]) && REG_P (operands[1]))
3248 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3249 else
3250 return "vmovsd\t{%1, %0|%0, %1}";
3251 }
3252 else
3253 return "movsd\t{%1, %0|%0, %1}";
6c4ccfd8 3254 case MODE_V1DF:
bc051083
UB
3255 if (TARGET_AVX)
3256 {
3257 if (REG_P (operands[0]))
3258 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3259 else
3260 return "vmovlpd\t{%1, %0|%0, %1}";
3261 }
3262 else
3263 return "movlpd\t{%1, %0|%0, %1}";
d30c9461 3264 case MODE_V2SF:
bc051083
UB
3265 if (TARGET_AVX)
3266 {
3267 if (REG_P (operands[0]))
3268 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3269 else
3270 return "vmovlps\t{%1, %0|%0, %1}";
3271 }
3272 else
3273 return "movlps\t{%1, %0|%0, %1}";
4977bab6 3274 default:
7637e42c 3275 gcc_unreachable ();
4977bab6 3276 }
446988df 3277
e075ae69 3278 default:
bc051083 3279 gcc_unreachable ();
e075ae69 3280 }
0f40f9f7 3281}
4501d314 3282 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
bc051083
UB
3283 (set (attr "prefix")
3284 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3285 (const_string "orig")
3286 (const_string "maybe_vex")))
725fd454
JJ
3287 (set (attr "prefix_data16")
3288 (if_then_else (eq_attr "mode" "V1DF")
3289 (const_string "1")
3290 (const_string "*")))
4977bab6 3291 (set (attr "mode")
d30c9461
RH
3292 (cond [(eq_attr "alternative" "0,1,2")
3293 (const_string "DF")
3294 (eq_attr "alternative" "3,4")
4977bab6 3295 (const_string "SI")
6c4ccfd8
RH
3296
3297 /* For SSE1, we have many fewer alternatives. */
3298 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3299 (cond [(eq_attr "alternative" "5,6")
d30c9461 3300 (const_string "V4SF")
6c4ccfd8 3301 ]
d30c9461 3302 (const_string "V2SF"))
6c4ccfd8 3303
4977bab6
ZW
3304 /* xorps is one byte shorter. */
3305 (eq_attr "alternative" "5")
3debdc1e 3306 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
4977bab6
ZW
3307 (const_int 0))
3308 (const_string "V4SF")
3309 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3310 (const_int 0))
6c4ccfd8
RH
3311 (const_string "TI")
3312 ]
4977bab6 3313 (const_string "V2DF"))
6c4ccfd8 3314
4977bab6
ZW
3315 /* For architectures resolving dependencies on
3316 whole SSE registers use APD move to break dependency
6c4ccfd8 3317 chains, otherwise use short move to avoid extra work.
4977bab6
ZW
3318
3319 movaps encodes one byte shorter. */
3320 (eq_attr "alternative" "6")
3321 (cond
3debdc1e 3322 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
6c4ccfd8
RH
3323 (const_int 0))
3324 (const_string "V4SF")
3325 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3326 (const_int 0))
3327 (const_string "V2DF")
3328 ]
4977bab6 3329 (const_string "DF"))
d1f87653 3330 /* For architectures resolving dependencies on register
4977bab6
ZW
3331 parts we may avoid extra work to zero out upper part
3332 of register. */
3333 (eq_attr "alternative" "7")
3334 (if_then_else
41afe4ef 3335 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
4977bab6 3336 (const_int 0))
6c4ccfd8
RH
3337 (const_string "V1DF")
3338 (const_string "DF"))
3339 ]
bc051083 3340 (const_string "DF")))])
2b589241 3341
2450a057 3342(define_split
bc051083
UB
3343 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3344 (match_operand:DF 1 "general_operand" ""))]
2450a057 3345 "reload_completed
bc051083
UB
3346 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3347 && ! (ANY_FP_REG_P (operands[0]) ||
3348 (GET_CODE (operands[0]) == SUBREG
3349 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3350 && ! (ANY_FP_REG_P (operands[1]) ||
3351 (GET_CODE (operands[1]) == SUBREG
3352 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2450a057 3353 [(const_int 0)]
26e5b205 3354 "ix86_split_long_move (operands); DONE;")
2450a057 3355
bc051083
UB
3356(define_insn "*movsf_internal"
3357 [(set (match_operand:SF 0 "nonimmediate_operand"
3358 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3359 (match_operand:SF 1 "general_operand"
3360 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3361 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
d7a29404 3362 && (reload_in_progress || reload_completed
bc051083
UB
3363 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3364 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3365 && standard_80387_constant_p (operands[1]))
d7a29404 3366 || GET_CODE (operands[1]) != CONST_DOUBLE
bc051083 3367 || memory_operand (operands[0], SFmode))"
4fb21e90 3368{
e075ae69 3369 switch (which_alternative)
4fb21e90 3370 {
e075ae69 3371 case 0:
e075ae69 3372 case 1:
d869c351 3373 return output_387_reg_move (insn, operands);
2f17722a 3374
e075ae69 3375 case 2:
881b2a96 3376 return standard_80387_constant_opcode (operands[1]);
467403ca 3377
bc051083
UB
3378 case 3:
3379 case 4:
3380 return "mov{l}\t{%1, %0|%0, %1}";
3381 case 5:
3382 if (get_attr_mode (insn) == MODE_TI)
3383 return "%vpxor\t%0, %d0";
3384 else
3385 return "%vxorps\t%0, %d0";
3386 case 6:
a91d32a4 3387 if (get_attr_mode (insn) == MODE_V4SF)
95879c72 3388 return "%vmovaps\t{%1, %0|%0, %1}";
a91d32a4 3389 else
bc051083
UB
3390 return "%vmovss\t{%1, %d0|%d0, %1}";
3391 case 7:
3392 if (TARGET_AVX)
3393 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3394 : "vmovss\t{%1, %0|%0, %1}";
a91d32a4 3395 else
bc051083
UB
3396 return "movss\t{%1, %0|%0, %1}";
3397 case 8:
3398 return "%vmovss\t{%1, %0|%0, %1}";
3399
3400 case 9: case 10: case 14: case 15:
3401 return "movd\t{%1, %0|%0, %1}";
3402 case 12: case 13:
3403 return "%vmovd\t{%1, %0|%0, %1}";
3404
3405 case 11:
3406 return "movq\t{%1, %0|%0, %1}";
3407
a91d32a4
UB
3408 default:
3409 gcc_unreachable ();
3410 }
3411}
bc051083
UB
3412 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3413 (set (attr "prefix")
3414 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3415 (const_string "maybe_vex")
3416 (const_string "orig")))
a91d32a4 3417 (set (attr "mode")
bc051083
UB
3418 (cond [(eq_attr "alternative" "3,4,9,10")
3419 (const_string "SI")
3420 (eq_attr "alternative" "5")
a91d32a4 3421 (if_then_else
bc051083
UB
3422 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3423 (const_int 0))
3424 (ne (symbol_ref "TARGET_SSE2")
3425 (const_int 0)))
3426 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3427 (const_int 0)))
3428 (const_string "TI")
3429 (const_string "V4SF"))
3430 /* For architectures resolving dependencies on
3431 whole SSE registers use APS move to break dependency
3432 chains, otherwise use short move to avoid extra work.
3433
3434 Do the same for architectures resolving dependencies on
3435 the parts. While in DF mode it is better to always handle
3436 just register parts, the SF mode is different due to lack
3437 of instructions to load just part of the register. It is
3438 better to maintain the whole registers in single format
3439 to avoid problems on using packed logical operations. */
3440 (eq_attr "alternative" "6")
a91d32a4 3441 (if_then_else
bc051083 3442 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
a91d32a4 3443 (const_int 0))
bc051083 3444 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
a91d32a4
UB
3445 (const_int 0)))
3446 (const_string "V4SF")
bc051083
UB
3447 (const_string "SF"))
3448 (eq_attr "alternative" "11")
3449 (const_string "DI")]
3450 (const_string "SF")))])
467403ca 3451
d7a29404 3452(define_split
2b589241
JH
3453 [(set (match_operand 0 "register_operand" "")
3454 (match_operand 1 "memory_operand" ""))]
d7a29404 3455 "reload_completed
7656aee4 3456 && MEM_P (operands[1])
edc5bbcd
UB
3457 && (GET_MODE (operands[0]) == TFmode
3458 || GET_MODE (operands[0]) == XFmode
bc051083
UB
3459 || GET_MODE (operands[0]) == DFmode
3460 || GET_MODE (operands[0]) == SFmode)
2a450639
RS
3461 && (operands[2] = find_constant_src (insn))"
3462 [(set (match_dup 0) (match_dup 2))]
b87cfcfb 3463{
2a450639 3464 rtx c = operands[2];
b87cfcfb
RH
3465 rtx r = operands[0];
3466
3467 if (GET_CODE (r) == SUBREG)
3468 r = SUBREG_REG (r);
3469
3470 if (SSE_REG_P (r))
3471 {
3472 if (!standard_sse_constant_p (c))
3473 FAIL;
3474 }
3475 else if (FP_REG_P (r))
3476 {
3477 if (!standard_80387_constant_p (c))
3478 FAIL;
3479 }
3480 else if (MMX_REG_P (r))
3481 FAIL;
b87cfcfb 3482})
d7a29404 3483
ce7d4645
UB
3484(define_split
3485 [(set (match_operand 0 "register_operand" "")
3486 (float_extend (match_operand 1 "memory_operand" "")))]
3487 "reload_completed
7656aee4 3488 && MEM_P (operands[1])
a91d32a4
UB
3489 && (GET_MODE (operands[0]) == TFmode
3490 || GET_MODE (operands[0]) == XFmode
bc051083
UB
3491 || GET_MODE (operands[0]) == DFmode
3492 || GET_MODE (operands[0]) == SFmode)
2a450639
RS
3493 && (operands[2] = find_constant_src (insn))"
3494 [(set (match_dup 0) (match_dup 2))]
ce7d4645 3495{
2a450639 3496 rtx c = operands[2];
ce7d4645
UB
3497 rtx r = operands[0];
3498
3499 if (GET_CODE (r) == SUBREG)
3500 r = SUBREG_REG (r);
3501
3502 if (SSE_REG_P (r))
3503 {
3504 if (!standard_sse_constant_p (c))
3505 FAIL;
3506 }
3507 else if (FP_REG_P (r))
3508 {
3509 if (!standard_80387_constant_p (c))
3510 FAIL;
3511 }
3512 else if (MMX_REG_P (r))
3513 FAIL;
ce7d4645
UB
3514})
3515
2e1f15bd
UB
3516;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3517(define_split
3518 [(set (match_operand:X87MODEF 0 "register_operand" "")
3519 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3520 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3521 && (standard_80387_constant_p (operands[1]) == 8
3522 || standard_80387_constant_p (operands[1]) == 9)"
3523 [(set (match_dup 0)(match_dup 1))
3524 (set (match_dup 0)
3525 (neg:X87MODEF (match_dup 0)))]
3526{
3527 REAL_VALUE_TYPE r;
3528
3529 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3530 if (real_isnegzero (&r))
3531 operands[1] = CONST0_RTX (<MODE>mode);
3532 else
3533 operands[1] = CONST1_RTX (<MODE>mode);
3534})
3535
bc051083
UB
3536(define_insn "swapxf"
3537 [(set (match_operand:XF 0 "register_operand" "+f")
3538 (match_operand:XF 1 "register_operand" "+f"))
3539 (set (match_dup 1)
3540 (match_dup 0))]
3541 "TARGET_80387"
3542{
3543 if (STACK_TOP_P (operands[0]))
3544 return "fxch\t%1";
3545 else
3546 return "fxch\t%0";
3547}
3548 [(set_attr "type" "fxch")
3549 (set_attr "mode" "XF")])
3550
3551(define_insn "*swap<mode>"
3552 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3553 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3554 (set (match_dup 1)
3555 (match_dup 0))]
3556 "TARGET_80387 || reload_completed"
3557{
3558 if (STACK_TOP_P (operands[0]))
3559 return "fxch\t%1";
3560 else
3561 return "fxch\t%0";
3562}
3563 [(set_attr "type" "fxch")
3564 (set_attr "mode" "<MODE>")])
886c62d1 3565\f
e075ae69 3566;; Zero extension instructions
886c62d1 3567
9552aca7
UB
3568(define_expand "zero_extendsidi2"
3569 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3570 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3571 ""
3572{
3573 if (!TARGET_64BIT)
3574 {
3575 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3576 DONE;
3577 }
3578})
3579
3580(define_insn "*zero_extendsidi2_rex64"
3581 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3582 (zero_extend:DI
3583 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3584 "TARGET_64BIT"
3585 "@
3586 mov\t{%k1, %k0|%k0, %k1}
3587 #
3588 movd\t{%1, %0|%0, %1}
3589 movd\t{%1, %0|%0, %1}
3590 %vmovd\t{%1, %0|%0, %1}
3591 %vmovd\t{%1, %0|%0, %1}"
3592 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3593 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3594 (set_attr "prefix_0f" "0,*,*,*,*,*")
3595 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3596
3597(define_split
3598 [(set (match_operand:DI 0 "memory_operand" "")
3599 (zero_extend:DI (match_dup 0)))]
3600 "TARGET_64BIT"
3601 [(set (match_dup 4) (const_int 0))]
b146446c 3602 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
9552aca7
UB
3603
3604;; %%% Kill me once multi-word ops are sane.
3605(define_insn "zero_extendsidi2_1"
3606 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3607 (zero_extend:DI
3608 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3609 (clobber (reg:CC FLAGS_REG))]
3610 "!TARGET_64BIT"
3611 "@
3612 #
3613 #
3614 #
3615 movd\t{%1, %0|%0, %1}
3616 movd\t{%1, %0|%0, %1}
3617 %vmovd\t{%1, %0|%0, %1}
3618 %vmovd\t{%1, %0|%0, %1}"
3619 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3620 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3621 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3622
3623(define_split
3624 [(set (match_operand:DI 0 "register_operand" "")
3625 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3626 (clobber (reg:CC FLAGS_REG))]
3627 "!TARGET_64BIT && reload_completed
3628 && true_regnum (operands[0]) == true_regnum (operands[1])"
3629 [(set (match_dup 4) (const_int 0))]
b146446c 3630 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
9552aca7
UB
3631
3632(define_split
3633 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3634 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3635 (clobber (reg:CC FLAGS_REG))]
3636 "!TARGET_64BIT && reload_completed
3637 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3638 [(set (match_dup 3) (match_dup 1))
3639 (set (match_dup 4) (const_int 0))]
b146446c 3640 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
9552aca7
UB
3641
3642(define_insn "zero_extend<mode>di2"
3643 [(set (match_operand:DI 0 "register_operand" "=r")
3644 (zero_extend:DI
3645 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3646 "TARGET_64BIT"
3647 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3648 [(set_attr "type" "imovx")
3649 (set_attr "mode" "SI")])
3650
8f7661f2
JH
3651(define_expand "zero_extendhisi2"
3652 [(set (match_operand:SI 0 "register_operand" "")
9552aca7 3653 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
d626200a 3654 ""
e075ae69 3655{
3debdc1e 3656 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
2ae0f82c 3657 {
8f7661f2
JH
3658 operands[1] = force_reg (HImode, operands[1]);
3659 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3660 DONE;
2ae0f82c 3661 }
0f40f9f7 3662})
886c62d1 3663
9552aca7 3664(define_insn_and_split "zero_extendhisi2_and"
8f7661f2 3665 [(set (match_operand:SI 0 "register_operand" "=r")
9552aca7 3666 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
8bc527af 3667 (clobber (reg:CC FLAGS_REG))]
3debdc1e 3668 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
8f7661f2 3669 "#"
9552aca7 3670 "&& reload_completed"
8f7661f2 3671 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
8bc527af 3672 (clobber (reg:CC FLAGS_REG))])]
9552aca7
UB
3673 ""
3674 [(set_attr "type" "alu1")
3675 (set_attr "mode" "SI")])
d626200a 3676
8f7661f2
JH
3677(define_insn "*zero_extendhisi2_movzwl"
3678 [(set (match_operand:SI 0 "register_operand" "=r")
9552aca7 3679 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3debdc1e
JH
3680 "!TARGET_ZERO_EXTEND_WITH_AND
3681 || optimize_function_for_size_p (cfun)"
0f40f9f7 3682 "movz{wl|x}\t{%1, %0|%0, %1}"
6ef67412
JH
3683 [(set_attr "type" "imovx")
3684 (set_attr "mode" "SI")])
8f7661f2 3685
9552aca7 3686(define_expand "zero_extendqi<mode>2"
8f7661f2 3687 [(parallel
9552aca7
UB
3688 [(set (match_operand:SWI24 0 "register_operand" "")
3689 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
a427621f 3690 (clobber (reg:CC FLAGS_REG))])])
8f7661f2 3691
9552aca7
UB
3692(define_insn "*zero_extendqi<mode>2_and"
3693 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3694 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
8bc527af 3695 (clobber (reg:CC FLAGS_REG))]
3debdc1e 3696 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
8f7661f2 3697 "#"
6ef67412 3698 [(set_attr "type" "alu1")
9552aca7 3699 (set_attr "mode" "<MODE>")])
2ae0f82c 3700
8f7661f2
JH
3701;; When source and destination does not overlap, clear destination
3702;; first and then do the movb
2ae0f82c 3703(define_split
9552aca7
UB
3704 [(set (match_operand:SWI24 0 "register_operand" "")
3705 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 3706 (clobber (reg:CC FLAGS_REG))]
e075ae69 3707 "reload_completed
9552aca7 3708 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
1a06f5fe 3709 && ANY_QI_REG_P (operands[0])
9552aca7 3710 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
8f7661f2 3711 && !reg_overlap_mentioned_p (operands[0], operands[1])"
b09ee6aa
UB
3712 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3713{
3714 operands[2] = gen_lowpart (QImode, operands[0]);
3715 ix86_expand_clear (operands[0]);
3716})
2ae0f82c 3717
9552aca7
UB
3718(define_insn "*zero_extendqi<mode>2_movzbl_and"
3719 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3720 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
8bc527af 3721 (clobber (reg:CC FLAGS_REG))]
3debdc1e 3722 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
8f7661f2 3723 "#"
6ef67412 3724 [(set_attr "type" "imovx,alu1")
9552aca7 3725 (set_attr "mode" "<MODE>")])
8f7661f2
JH
3726
3727;; For the movzbl case strip only the clobber
3728(define_split
9552aca7
UB
3729 [(set (match_operand:SWI24 0 "register_operand" "")
3730 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 3731 (clobber (reg:CC FLAGS_REG))]
6300f037 3732 "reload_completed
3debdc1e 3733 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
1a06f5fe 3734 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2 3735 [(set (match_dup 0)
9552aca7 3736 (zero_extend:SWI24 (match_dup 1)))])
8f7661f2 3737
9552aca7
UB
3738; zero extend to SImode to avoid partial register stalls
3739(define_insn "*zero_extendqi<mode>2_movzbl"
3740 [(set (match_operand:SWI24 0 "register_operand" "=r")
3741 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
e075ae69 3742 "reload_completed
9552aca7
UB
3743 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3744 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3745 [(set_attr "type" "imovx")
3746 (set_attr "mode" "SI")])
2ae0f82c 3747
8f7661f2 3748;; Rest is handled by single and.
2ae0f82c 3749(define_split
9552aca7
UB
3750 [(set (match_operand:SWI24 0 "register_operand" "")
3751 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
8bc527af 3752 (clobber (reg:CC FLAGS_REG))]
e075ae69 3753 "reload_completed
8f7661f2 3754 && true_regnum (operands[0]) == true_regnum (operands[1])"
9552aca7 3755 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
cb1b497e 3756 (clobber (reg:CC FLAGS_REG))])])
886c62d1 3757\f
e075ae69 3758;; Sign extension instructions
886c62d1 3759
123bf9e3 3760(define_expand "extendsidi2"
9552aca7
UB
3761 [(set (match_operand:DI 0 "register_operand" "")
3762 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
123bf9e3 3763 ""
123bf9e3 3764{
9552aca7 3765 if (!TARGET_64BIT)
123bf9e3 3766 {
9552aca7 3767 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
123bf9e3
JH
3768 DONE;
3769 }
0f40f9f7 3770})
123bf9e3 3771
9552aca7 3772(define_insn "*extendsidi2_rex64"
123bf9e3
JH
3773 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3774 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3775 "TARGET_64BIT"
3776 "@
3777 {cltq|cdqe}
725fd454 3778 movs{lq|x}\t{%1, %0|%0, %1}"
123bf9e3
JH
3779 [(set_attr "type" "imovx")
3780 (set_attr "mode" "DI")
3781 (set_attr "prefix_0f" "0")
3782 (set_attr "modrm" "0,1")])
3783
9552aca7
UB
3784(define_insn "extendsidi2_1"
3785 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3786 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3787 (clobber (reg:CC FLAGS_REG))
3788 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3789 "!TARGET_64BIT"
3790 "#")
123bf9e3 3791
724d568a 3792;; Extend to memory case when source register does die.
6300f037 3793(define_split
724d568a
JH
3794 [(set (match_operand:DI 0 "memory_operand" "")
3795 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3796 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3797 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 3798 "(reload_completed
724d568a
JH
3799 && dead_or_set_p (insn, operands[1])
3800 && !reg_mentioned_p (operands[1], operands[0]))"
3801 [(set (match_dup 3) (match_dup 1))
e075ae69 3802 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
8bc527af 3803 (clobber (reg:CC FLAGS_REG))])
724d568a 3804 (set (match_dup 4) (match_dup 1))]
b146446c 3805 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
724d568a
JH
3806
3807;; Extend to memory case when source register does not die.
6300f037 3808(define_split
724d568a
JH
3809 [(set (match_operand:DI 0 "memory_operand" "")
3810 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3811 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3812 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 3813 "reload_completed"
724d568a 3814 [(const_int 0)]
9c530261 3815{
b146446c 3816 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
724d568a
JH
3817
3818 emit_move_insn (operands[3], operands[1]);
3819
3820 /* Generate a cltd if possible and doing so it profitable. */
3debdc1e 3821 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
29b74761
UB
3822 && true_regnum (operands[1]) == AX_REG
3823 && true_regnum (operands[2]) == DX_REG)
71a247f0 3824 {
27431d88 3825 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
724d568a
JH
3826 }
3827 else
3828 {
3829 emit_move_insn (operands[2], operands[1]);
27431d88 3830 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
71a247f0 3831 }
724d568a
JH
3832 emit_move_insn (operands[4], operands[2]);
3833 DONE;
0f40f9f7 3834})
9c530261 3835
724d568a
JH
3836;; Extend to register case. Optimize case where source and destination
3837;; registers match and cases where we can use cltd.
6300f037 3838(define_split
724d568a
JH
3839 [(set (match_operand:DI 0 "register_operand" "")
3840 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3841 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3842 (clobber (match_scratch:SI 2 ""))]
724d568a
JH
3843 "reload_completed"
3844 [(const_int 0)]
724d568a 3845{
b146446c 3846 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
724d568a
JH
3847
3848 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3849 emit_move_insn (operands[3], operands[1]);
9c530261 3850
724d568a 3851 /* Generate a cltd if possible and doing so it profitable. */
3debdc1e 3852 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
719938ae
UB
3853 && true_regnum (operands[3]) == AX_REG
3854 && true_regnum (operands[4]) == DX_REG)
724d568a 3855 {
27431d88 3856 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
724d568a
JH
3857 DONE;
3858 }
3859
3860 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3861 emit_move_insn (operands[4], operands[1]);
3862
27431d88 3863 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
724d568a 3864 DONE;
0f40f9f7 3865})
886c62d1 3866
9552aca7
UB
3867(define_insn "extend<mode>di2"
3868 [(set (match_operand:DI 0 "register_operand" "=r")
3869 (sign_extend:DI
3870 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3871 "TARGET_64BIT"
3872 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3873 [(set_attr "type" "imovx")
3874 (set_attr "mode" "DI")])
3875
886c62d1 3876(define_insn "extendhisi2"
e075ae69
RH
3877 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3878 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
886c62d1 3879 ""
886c62d1 3880{
6ef67412 3881 switch (get_attr_prefix_0f (insn))
e075ae69 3882 {
6ef67412 3883 case 0:
0f40f9f7 3884 return "{cwtl|cwde}";
e075ae69 3885 default:
725fd454 3886 return "movs{wl|x}\t{%1, %0|%0, %1}";
e075ae69 3887 }
0f40f9f7 3888}
e075ae69 3889 [(set_attr "type" "imovx")
6ef67412
JH
3890 (set_attr "mode" "SI")
3891 (set (attr "prefix_0f")
3892 ;; movsx is short decodable while cwtl is vector decoded.
3893 (if_then_else (and (eq_attr "cpu" "!k6")
3894 (eq_attr "alternative" "0"))
3895 (const_string "0")
3896 (const_string "1")))
3897 (set (attr "modrm")
3898 (if_then_else (eq_attr "prefix_0f" "0")
3899 (const_string "0")
3900 (const_string "1")))])
886c62d1 3901
123bf9e3
JH
3902(define_insn "*extendhisi2_zext"
3903 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3904 (zero_extend:DI
9552aca7
UB
3905 (sign_extend:SI
3906 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
123bf9e3 3907 "TARGET_64BIT"
123bf9e3
JH
3908{
3909 switch (get_attr_prefix_0f (insn))
3910 {
3911 case 0:
0f40f9f7 3912 return "{cwtl|cwde}";
123bf9e3 3913 default:
725fd454 3914 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
123bf9e3 3915 }
0f40f9f7 3916}
123bf9e3
JH
3917 [(set_attr "type" "imovx")
3918 (set_attr "mode" "SI")
3919 (set (attr "prefix_0f")
3920 ;; movsx is short decodable while cwtl is vector decoded.
3921 (if_then_else (and (eq_attr "cpu" "!k6")
3922 (eq_attr "alternative" "0"))
3923 (const_string "0")
3924 (const_string "1")))
3925 (set (attr "modrm")
3926 (if_then_else (eq_attr "prefix_0f" "0")
3927 (const_string "0")
3928 (const_string "1")))])
3929
9552aca7
UB
3930(define_insn "extendqisi2"
3931 [(set (match_operand:SI 0 "register_operand" "=r")
3932 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3933 ""
3934 "movs{bl|x}\t{%1, %0|%0, %1}"
3935 [(set_attr "type" "imovx")
3936 (set_attr "mode" "SI")])
3937
3938(define_insn "*extendqisi2_zext"
3939 [(set (match_operand:DI 0 "register_operand" "=r")
3940 (zero_extend:DI
3941 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3942 "TARGET_64BIT"
3943 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3944 [(set_attr "type" "imovx")
3945 (set_attr "mode" "SI")])
3946
886c62d1 3947(define_insn "extendqihi2"
e075ae69
RH
3948 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3949 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
886c62d1 3950 ""
886c62d1 3951{
6ef67412 3952 switch (get_attr_prefix_0f (insn))
e075ae69 3953 {
6ef67412 3954 case 0:
0f40f9f7 3955 return "{cbtw|cbw}";
e075ae69 3956 default:
725fd454 3957 return "movs{bw|x}\t{%1, %0|%0, %1}";
e075ae69 3958 }
0f40f9f7 3959}
e075ae69 3960 [(set_attr "type" "imovx")
6ef67412
JH
3961 (set_attr "mode" "HI")
3962 (set (attr "prefix_0f")
3963 ;; movsx is short decodable while cwtl is vector decoded.
3964 (if_then_else (and (eq_attr "cpu" "!k6")
3965 (eq_attr "alternative" "0"))
3966 (const_string "0")
3967 (const_string "1")))
3968 (set (attr "modrm")
3969 (if_then_else (eq_attr "prefix_0f" "0")
3970 (const_string "0")
3971 (const_string "1")))])
886c62d1
JVA
3972\f
3973;; Conversions between float and double.
3974
770b37b9
UB
3975;; These are all no-ops in the model used for the 80387.
3976;; So just emit moves.
6a4a5d95 3977
6300f037 3978;; %%% Kill these when call knows how to work out a DFmode push earlier.
6a4a5d95 3979(define_split
e075ae69 3980 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3 3981 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
770b37b9 3982 "reload_completed"
90b48492
KT
3983 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3984 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
123bf9e3 3985
e4ad1003 3986(define_split
e075ae69 3987 [(set (match_operand:XF 0 "push_operand" "")
770b37b9
UB
3988 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3989 "reload_completed"
90b48492
KT
3990 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3991 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
b1c6d018 3992 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
e4ad1003 3993
f97d9ec3
JH
3994(define_expand "extendsfdf2"
3995 [(set (match_operand:DF 0 "nonimmediate_operand" "")
51286de6 3996 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
2312581e 3997 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
f97d9ec3 3998{
51286de6
RH
3999 /* ??? Needed for compress_float_constant since all fp constants
4000 are LEGITIMATE_CONSTANT_P. */
4001 if (GET_CODE (operands[1]) == CONST_DOUBLE)
e046a30a
PB
4002 {
4003 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4004 && standard_80387_constant_p (operands[1]) > 0)
4005 {
4006 operands[1] = simplify_const_unary_operation
4007 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4008 emit_move_insn_1 (operands[0], operands[1]);
4009 DONE;
4010 }
4011 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4012 }
0f40f9f7 4013})
f97d9ec3 4014
4845dbb5
JH
4015/* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4016 cvtss2sd:
4017 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4018 cvtps2pd xmm2,xmm1
4019 We do the conversion post reload to avoid producing of 128bit spills
4020 that might lead to ICE on 32bit target. The sequence unlikely combine
4021 anyway. */
4022(define_split
4023 [(set (match_operand:DF 0 "register_operand" "")
4024 (float_extend:DF
4025 (match_operand:SF 1 "nonimmediate_operand" "")))]
54723b46 4026 "TARGET_USE_VECTOR_FP_CONVERTS
3debdc1e 4027 && optimize_insn_for_speed_p ()
4845dbb5
JH
4028 && reload_completed && SSE_REG_P (operands[0])"
4029 [(set (match_dup 2)
4030 (float_extend:V2DF
4031 (vec_select:V2SF
4032 (match_dup 3)
4033 (parallel [(const_int 0) (const_int 1)]))))]
4034{
4035 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4036 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4037 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4038 Try to avoid move when unpacking can be done in source. */
4039 if (REG_P (operands[1]))
4040 {
4041 /* If it is unsafe to overwrite upper half of source, we need
4042 to move to destination and unpack there. */
4043 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4044 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4045 && true_regnum (operands[0]) != true_regnum (operands[1]))
4046 {
4047 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4048 emit_move_insn (tmp, operands[1]);
4049 }
4050 else
4051 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
b0d49a6e
RH
4052 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4053 operands[3]));
4845dbb5
JH
4054 }
4055 else
4f3f76e6 4056 emit_insn (gen_vec_setv4sf_0 (operands[3],
4845dbb5
JH
4057 CONST0_RTX (V4SFmode), operands[1]));
4058})
4059
2312581e 4060(define_insn "*extendsfdf2_mixed"
50961141
RH
4061 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4062 (float_extend:DF
4063 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
509a77dc 4064 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4fb21e90 4065{
e075ae69 4066 switch (which_alternative)
4fb21e90 4067 {
e075ae69 4068 case 0:
e075ae69 4069 case 1:
d869c351 4070 return output_387_reg_move (insn, operands);
5ea9cb6e 4071
42a0aa6f 4072 case 2:
95879c72 4073 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4fb21e90 4074
e075ae69 4075 default:
7637e42c 4076 gcc_unreachable ();
e075ae69 4077 }
0f40f9f7 4078}
3d34cd91 4079 [(set_attr "type" "fmov,fmov,ssecvt")
95879c72 4080 (set_attr "prefix" "orig,orig,maybe_vex")
a811cc63 4081 (set_attr "mode" "SF,XF,DF")])
42a0aa6f 4082
2312581e 4083(define_insn "*extendsfdf2_sse"
50961141
RH
4084 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4085 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
509a77dc 4086 "TARGET_SSE2 && TARGET_SSE_MATH"
95879c72 4087 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3d34cd91 4088 [(set_attr "type" "ssecvt")
95879c72 4089 (set_attr "prefix" "maybe_vex")
42a0aa6f 4090 (set_attr "mode" "DF")])
e075ae69 4091
2312581e
UB
4092(define_insn "*extendsfdf2_i387"
4093 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4094 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
509a77dc 4095 "TARGET_80387"
d869c351 4096 "* return output_387_reg_move (insn, operands);"
2312581e
UB
4097 [(set_attr "type" "fmov")
4098 (set_attr "mode" "SF,XF")])
4099
a344e3cb 4100(define_expand "extend<mode>xf2"
f97d9ec3 4101 [(set (match_operand:XF 0 "nonimmediate_operand" "")
00188daa 4102 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
f8a1ebc6 4103 "TARGET_80387"
f97d9ec3 4104{
51286de6
RH
4105 /* ??? Needed for compress_float_constant since all fp constants
4106 are LEGITIMATE_CONSTANT_P. */
4107 if (GET_CODE (operands[1]) == CONST_DOUBLE)
e046a30a
PB
4108 {
4109 if (standard_80387_constant_p (operands[1]) > 0)
4110 {
4111 operands[1] = simplify_const_unary_operation
a344e3cb 4112 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
e046a30a
PB
4113 emit_move_insn_1 (operands[0], operands[1]);
4114 DONE;
4115 }
a344e3cb 4116 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
e046a30a 4117 }
0f40f9f7 4118})
f97d9ec3 4119
a344e3cb 4120(define_insn "*extend<mode>xf2_i387"
e075ae69 4121 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
a344e3cb 4122 (float_extend:XF
00188daa 4123 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
509a77dc 4124 "TARGET_80387"
d869c351 4125 "* return output_387_reg_move (insn, operands);"
2b589241 4126 [(set_attr "type" "fmov")
a344e3cb 4127 (set_attr "mode" "<MODE>,XF")])
2b589241 4128
e075ae69
RH
4129;; %%% This seems bad bad news.
4130;; This cannot output into an f-reg because there is no way to be sure
4131;; of truncating in that case. Otherwise this is just like a simple move
4132;; insn. So we pretend we can output to a reg in order to get better
4133;; register preferencing, but we really use a stack slot.
886c62d1 4134
5b1f1e63 4135;; Conversion from DFmode to SFmode.
bc725565 4136
5b1f1e63
RH
4137(define_expand "truncdfsf2"
4138 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4139 (float_truncate:SF
4140 (match_operand:DF 1 "nonimmediate_operand" "")))]
4141 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
82a6a758 4142{
5b1f1e63
RH
4143 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4144 ;
4145 else if (flag_unsafe_math_optimizations)
4146 ;
4147 else
4148 {
bbbbb16a
ILT
4149 enum ix86_stack_slot slot = (virtuals_instantiated
4150 ? SLOT_TEMP
4151 : SLOT_VIRTUAL);
be0c4603 4152 rtx temp = assign_386_stack_local (SFmode, slot);
5b1f1e63
RH
4153 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4154 DONE;
4155 }
4156})
4157
4845dbb5
JH
4158/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4159 cvtsd2ss:
4160 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4161 cvtpd2ps xmm2,xmm1
4162 We do the conversion post reload to avoid producing of 128bit spills
4163 that might lead to ICE on 32bit target. The sequence unlikely combine
4164 anyway. */
4165(define_split
4166 [(set (match_operand:SF 0 "register_operand" "")
4167 (float_truncate:SF
4168 (match_operand:DF 1 "nonimmediate_operand" "")))]
54723b46 4169 "TARGET_USE_VECTOR_FP_CONVERTS
3debdc1e 4170 && optimize_insn_for_speed_p ()
4845dbb5
JH
4171 && reload_completed && SSE_REG_P (operands[0])"
4172 [(set (match_dup 2)
4173 (vec_concat:V4SF
4174 (float_truncate:V2SF
4175 (match_dup 4))
4176 (match_dup 3)))]
4177{
4178 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4179 operands[3] = CONST0_RTX (V2SFmode);
4180 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4181 /* Use movsd for loading from memory, unpcklpd for registers.
4182 Try to avoid move when unpacking can be done in source, or SSE3
4183 movddup is available. */
4184 if (REG_P (operands[1]))
4185 {
4186 if (!TARGET_SSE3
4187 && true_regnum (operands[0]) != true_regnum (operands[1])
4188 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4189 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4190 {
4191 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4192 emit_move_insn (tmp, operands[1]);
4193 operands[1] = tmp;
4194 }
4195 else if (!TARGET_SSE3)
4196 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4197 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4198 }
4199 else
4200 emit_insn (gen_sse2_loadlpd (operands[4],
4201 CONST0_RTX (V2DFmode), operands[1]));
4202})
4203
5b1f1e63
RH
4204(define_expand "truncdfsf2_with_temp"
4205 [(parallel [(set (match_operand:SF 0 "" "")
4206 (float_truncate:SF (match_operand:DF 1 "" "")))
a427621f 4207 (clobber (match_operand:SF 2 "" ""))])])
5b1f1e63
RH
4208
4209(define_insn "*truncdfsf_fast_mixed"
73e8165a 4210 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
5b1f1e63 4211 (float_truncate:SF
73e8165a 4212 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
5b1f1e63 4213 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
e075ae69
RH
4214{
4215 switch (which_alternative)
4216 {
4217 case 0:
5b1f1e63 4218 return output_387_reg_move (insn, operands);
73e8165a 4219 case 1:
95879c72 4220 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
46ed7963 4221 default:
7637e42c 4222 gcc_unreachable ();
e075ae69 4223 }
0f40f9f7 4224}
73e8165a 4225 [(set_attr "type" "fmov,ssecvt")
95879c72 4226 (set_attr "prefix" "orig,maybe_vex")
5b1f1e63
RH
4227 (set_attr "mode" "SF")])
4228
4229;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4230;; because nothing we do here is unsafe.
4231(define_insn "*truncdfsf_fast_sse"
50961141 4232 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
5b1f1e63 4233 (float_truncate:SF
50961141 4234 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
5b1f1e63 4235 "TARGET_SSE2 && TARGET_SSE_MATH"
95879c72 4236 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
5b1f1e63 4237 [(set_attr "type" "ssecvt")
95879c72 4238 (set_attr "prefix" "maybe_vex")
5b1f1e63
RH
4239 (set_attr "mode" "SF")])
4240
4241(define_insn "*truncdfsf_fast_i387"
4242 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4243 (float_truncate:SF
4244 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4245 "TARGET_80387 && flag_unsafe_math_optimizations"
4246 "* return output_387_reg_move (insn, operands);"
4247 [(set_attr "type" "fmov")
4248 (set_attr "mode" "SF")])
42a0aa6f 4249
5b1f1e63 4250(define_insn "*truncdfsf_mixed"
9ade279b 4251 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
42a0aa6f 4252 (float_truncate:SF
9ade279b
UB
4253 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4254 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
5b1f1e63 4255 "TARGET_MIX_SSE_I387"
4977bab6
ZW
4256{
4257 switch (which_alternative)
4258 {
4259 case 0:
a344e3cb 4260 return output_387_reg_move (insn, operands);
5b1f1e63 4261 case 1:
95879c72 4262 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
9ade279b 4263
46ed7963 4264 default:
9ade279b 4265 return "#";
42a0aa6f 4266 }
0f40f9f7 4267}
9ade279b
UB
4268 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4269 (set_attr "unit" "*,*,i387,i387,i387")
4270 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
5b1f1e63 4271 (set_attr "mode" "SF")])
53b5ce19 4272
5b1f1e63 4273(define_insn "*truncdfsf_i387"
9ade279b 4274 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
42a0aa6f 4275 (float_truncate:SF
9ade279b
UB
4276 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4277 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
5b1f1e63 4278 "TARGET_80387"
42a0aa6f
JH
4279{
4280 switch (which_alternative)
4281 {
4282 case 0:
a344e3cb
UB
4283 return output_387_reg_move (insn, operands);
4284
0f40f9f7 4285 default:
9ade279b 4286 return "#";
42a0aa6f 4287 }
0f40f9f7 4288}
9ade279b
UB
4289 [(set_attr "type" "fmov,multi,multi,multi")
4290 (set_attr "unit" "*,i387,i387,i387")
26f74aa3 4291 (set_attr "mode" "SF")])
acaa3bf7
RS
4292
4293(define_insn "*truncdfsf2_i387_1"
4294 [(set (match_operand:SF 0 "memory_operand" "=m")
4295 (float_truncate:SF
4296 (match_operand:DF 1 "register_operand" "f")))]
4297 "TARGET_80387
4298 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299 && !TARGET_MIX_SSE_I387"
a344e3cb 4300 "* return output_387_reg_move (insn, operands);"
acaa3bf7
RS
4301 [(set_attr "type" "fmov")
4302 (set_attr "mode" "SF")])
42a0aa6f 4303
42a0aa6f 4304(define_split
4977bab6 4305 [(set (match_operand:SF 0 "register_operand" "")
42a0aa6f 4306 (float_truncate:SF
5b1f1e63 4307 (match_operand:DF 1 "fp_register_operand" "")))
42a0aa6f 4308 (clobber (match_operand 2 "" ""))]
5b1f1e63
RH
4309 "reload_completed"
4310 [(set (match_dup 2) (match_dup 1))
4311 (set (match_dup 0) (match_dup 2))]
cb1b497e 4312 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
42a0aa6f 4313
a344e3cb 4314;; Conversion from XFmode to {SF,DF}mode
53b5ce19 4315
a344e3cb 4316(define_expand "truncxf<mode>2"
00188daa
UB
4317 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4318 (float_truncate:MODEF
a344e3cb 4319 (match_operand:XF 1 "register_operand" "")))
e075ae69 4320 (clobber (match_dup 2))])]
f8a1ebc6 4321 "TARGET_80387"
5b1f1e63 4322{
0c5faf29
RS
4323 if (flag_unsafe_math_optimizations)
4324 {
a344e3cb
UB
4325 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4326 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
0c5faf29
RS
4327 if (reg != operands[0])
4328 emit_move_insn (operands[0], reg);
4329 DONE;
4330 }
4331 else
be0c4603 4332 {
1f944e88
ILT
4333 enum ix86_stack_slot slot = (virtuals_instantiated
4334 ? SLOT_TEMP
4335 : SLOT_VIRTUAL);
be0c4603
UB
4336 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4337 }
5b1f1e63
RH
4338})
4339
4340(define_insn "*truncxfsf2_mixed"
9ade279b 4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
5b1f1e63 4342 (float_truncate:SF
9ade279b
UB
4343 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4344 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
e26feb2c 4345 "TARGET_80387"
5b1f1e63 4346{
7637e42c 4347 gcc_assert (!which_alternative);
a344e3cb 4348 return output_387_reg_move (insn, operands);
0f40f9f7 4349}
9ade279b
UB
4350 [(set_attr "type" "fmov,multi,multi,multi")
4351 (set_attr "unit" "*,i387,i387,i387")
6ef67412 4352 (set_attr "mode" "SF")])
bc725565 4353
5b1f1e63 4354(define_insn "*truncxfdf2_mixed"
9ade279b 4355 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
5b1f1e63 4356 (float_truncate:DF
9ade279b
UB
4357 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4358 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
e26feb2c 4359 "TARGET_80387"
5b1f1e63 4360{
7637e42c 4361 gcc_assert (!which_alternative);
a344e3cb 4362 return output_387_reg_move (insn, operands);
5b1f1e63 4363}
9ade279b
UB
4364 [(set_attr "type" "fmov,multi,multi,multi")
4365 (set_attr "unit" "*,i387,i387,i387")
5b1f1e63 4366 (set_attr "mode" "DF")])
0c5faf29 4367
a344e3cb 4368(define_insn "truncxf<mode>2_i387_noop"
00188daa
UB
4369 [(set (match_operand:MODEF 0 "register_operand" "=f")
4370 (float_truncate:MODEF
a344e3cb 4371 (match_operand:XF 1 "register_operand" "f")))]
0c5faf29 4372 "TARGET_80387 && flag_unsafe_math_optimizations"
01302104 4373 "* return output_387_reg_move (insn, operands);"
82a6a758 4374 [(set_attr "type" "fmov")
a344e3cb 4375 (set_attr "mode" "<MODE>")])
bc725565 4376
a344e3cb 4377(define_insn "*truncxf<mode>2_i387"
00188daa
UB
4378 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4379 (float_truncate:MODEF
e075ae69 4380 (match_operand:XF 1 "register_operand" "f")))]
f8a1ebc6 4381 "TARGET_80387"
a344e3cb 4382 "* return output_387_reg_move (insn, operands);"
6ef67412 4383 [(set_attr "type" "fmov")
a344e3cb 4384 (set_attr "mode" "<MODE>")])
bc725565
JW
4385
4386(define_split
00188daa
UB
4387 [(set (match_operand:MODEF 0 "register_operand" "")
4388 (float_truncate:MODEF
a344e3cb 4389 (match_operand:XF 1 "register_operand" "")))
00188daa 4390 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
5b1f1e63 4391 "TARGET_80387 && reload_completed"
00188daa 4392 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
cb1b497e 4393 (set (match_dup 0) (match_dup 2))])
4fb21e90 4394
bc725565 4395(define_split
00188daa
UB
4396 [(set (match_operand:MODEF 0 "memory_operand" "")
4397 (float_truncate:MODEF
a344e3cb 4398 (match_operand:XF 1 "register_operand" "")))
00188daa 4399 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
5b1f1e63 4400 "TARGET_80387"
cb1b497e 4401 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
e075ae69 4402\f
e075ae69
RH
4403;; Signed conversion to DImode.
4404
2b589241 4405(define_expand "fix_truncxfdi2"
ec13ba83
CT
4406 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4407 (fix:DI (match_operand:XF 1 "register_operand" "")))
8bc527af 4408 (clobber (reg:CC FLAGS_REG))])]
bc725565 4409 "TARGET_80387"
46ed7963 4410{
9199f050 4411 if (TARGET_FISTTP)
46ed7963 4412 {
9199f050 4413 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
46ed7963
JH
4414 DONE;
4415 }
0f40f9f7 4416})
53b5ce19 4417
9199f050 4418(define_expand "fix_trunc<mode>di2"
ec13ba83 4419 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
00188daa 4420 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
9199f050
UB
4421 (clobber (reg:CC FLAGS_REG))])]
4422 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
46ed7963 4423{
9199f050
UB
4424 if (TARGET_FISTTP
4425 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4426 {
4427 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4428 DONE;
4429 }
4430 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
46ed7963
JH
4431 {
4432 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
9199f050 4433 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
46ed7963
JH
4434 if (out != operands[0])
4435 emit_move_insn (operands[0], out);
4436 DONE;
4437 }
0f40f9f7 4438})
e075ae69 4439
e075ae69 4440;; Signed conversion to SImode.
53b5ce19 4441
e075ae69 4442(define_expand "fix_truncxfsi2"
ec13ba83 4443 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9199f050 4444 (fix:SI (match_operand:XF 1 "register_operand" "")))
8bc527af 4445 (clobber (reg:CC FLAGS_REG))])]
2b589241 4446 "TARGET_80387"
42a0aa6f 4447{
9199f050 4448 if (TARGET_FISTTP)
42a0aa6f 4449 {
9199f050 4450 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
42a0aa6f
JH
4451 DONE;
4452 }
0f40f9f7 4453})
886c62d1 4454
9199f050 4455(define_expand "fix_trunc<mode>si2"
ec13ba83 4456 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
00188daa 4457 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
9199f050 4458 (clobber (reg:CC FLAGS_REG))])]
84c2b4da 4459 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
42a0aa6f 4460{
9199f050
UB
4461 if (TARGET_FISTTP
4462 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4463 {
4464 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4465 DONE;
4466 }
4467 if (SSE_FLOAT_MODE_P (<MODE>mode))
42a0aa6f 4468 {
ca9a9b12 4469 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
9199f050 4470 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
b1675dbd
JH
4471 if (out != operands[0])
4472 emit_move_insn (operands[0], out);
42a0aa6f
JH
4473 DONE;
4474 }
0f40f9f7 4475})
e075ae69 4476
9199f050
UB
4477;; Signed conversion to HImode.
4478
4479(define_expand "fix_trunc<mode>hi2"
4480 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4481 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4482 (clobber (reg:CC FLAGS_REG))])]
4483 "TARGET_80387
4484 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
22fb740d 4485{
9199f050
UB
4486 if (TARGET_FISTTP)
4487 {
4488 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4489 DONE;
4490 }
4491})
22fb740d 4492
ebff937c
SH
4493;; Unsigned conversion to SImode.
4494
4495(define_expand "fixuns_trunc<mode>si2"
174c12c7
RH
4496 [(parallel
4497 [(set (match_operand:SI 0 "register_operand" "")
4498 (unsigned_fix:SI
00188daa 4499 (match_operand:MODEF 1 "nonimmediate_operand" "")))
174c12c7
RH
4500 (use (match_dup 2))
4501 (clobber (match_scratch:<ssevecmode> 3 ""))
4502 (clobber (match_scratch:<ssevecmode> 4 ""))])]
18bd082d 4503 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
174c12c7
RH
4504{
4505 enum machine_mode mode = <MODE>mode;
4506 enum machine_mode vecmode = <ssevecmode>mode;
4507 REAL_VALUE_TYPE TWO31r;
4508 rtx two31;
4509
18bd082d
JH
4510 if (optimize_insn_for_size_p ())
4511 FAIL;
4512
174c12c7
RH
4513 real_ldexp (&TWO31r, &dconst1, 31);
4514 two31 = const_double_from_real_value (TWO31r, mode);
4515 two31 = ix86_build_const_vector (mode, true, two31);
4516 operands[2] = force_reg (vecmode, two31);
4517})
4518
4519(define_insn_and_split "*fixuns_trunc<mode>_1"
4520 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4521 (unsigned_fix:SI
00188daa 4522 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
174c12c7
RH
4523 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4524 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4525 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
3debdc1e
JH
4526 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4527 && optimize_function_for_speed_p (cfun)"
174c12c7
RH
4528 "#"
4529 "&& reload_completed"
4530 [(const_int 0)]
ebff937c 4531{
174c12c7 4532 ix86_split_convert_uns_si_sse (operands);
ebff937c
SH
4533 DONE;
4534})
4535
4536;; Unsigned conversion to HImode.
4537;; Without these patterns, we'll try the unsigned SI conversion which
4538;; is complex for SSE, rather than the signed SI conversion, which isn't.
4539
d8e3118a 4540(define_expand "fixuns_trunc<mode>hi2"
ebff937c 4541 [(set (match_dup 2)
00188daa 4542 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
ebff937c
SH
4543 (set (match_operand:HI 0 "nonimmediate_operand" "")
4544 (subreg:HI (match_dup 2) 0))]
d8e3118a 4545 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
ebff937c
SH
4546 "operands[2] = gen_reg_rtx (SImode);")
4547
9199f050 4548;; When SSE is available, it is always faster to use it!
d8e3118a 4549(define_insn "fix_trunc<mode>di_sse"
9199f050 4550 [(set (match_operand:DI 0 "register_operand" "=r,r")
00188daa 4551 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
d8e3118a
UB
4552 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4553 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
95879c72 4554 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
9199f050 4555 [(set_attr "type" "sseicvt")
95879c72 4556 (set_attr "prefix" "maybe_vex")
725fd454 4557 (set_attr "prefix_rex" "1")
d8e3118a 4558 (set_attr "mode" "<MODE>")
21efb4d4
HJ
4559 (set_attr "athlon_decode" "double,vector")
4560 (set_attr "amdfam10_decode" "double,double")])
22fb740d 4561
d8e3118a 4562(define_insn "fix_trunc<mode>si_sse"
f56e86bd 4563 [(set (match_operand:SI 0 "register_operand" "=r,r")
00188daa 4564 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
d8e3118a
UB
4565 "SSE_FLOAT_MODE_P (<MODE>mode)
4566 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
95879c72 4567 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
f56e86bd 4568 [(set_attr "type" "sseicvt")
95879c72 4569 (set_attr "prefix" "maybe_vex")
d8e3118a 4570 (set_attr "mode" "<MODE>")
21efb4d4
HJ
4571 (set_attr "athlon_decode" "double,vector")
4572 (set_attr "amdfam10_decode" "double,double")])
42a0aa6f 4573
962ef7fe
UB
4574;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4575(define_peephole2
00188daa
UB
4576 [(set (match_operand:MODEF 0 "register_operand" "")
4577 (match_operand:MODEF 1 "memory_operand" ""))
962ef7fe
UB
4578 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4579 (fix:SSEMODEI24 (match_dup 0)))]
ddff69b9 4580 "TARGET_SHORTEN_X87_SSE
501d1a70 4581 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
962ef7fe 4582 && peep2_reg_dead_p (2, operands[0])"
cfc20f00 4583 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
962ef7fe 4584
9199f050 4585;; Avoid vector decoded forms of the instruction.
8dfa3bb0 4586(define_peephole2
e2520c41 4587 [(match_scratch:DF 2 "Y2")
9199f050
UB
4588 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4589 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
3debdc1e 4590 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
8dfa3bb0 4591 [(set (match_dup 2) (match_dup 1))
cfc20f00 4592 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
8dfa3bb0 4593
9199f050
UB
4594(define_peephole2
4595 [(match_scratch:SF 2 "x")
4596 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4597 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
3debdc1e 4598 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
9199f050 4599 [(set (match_dup 2) (match_dup 1))
cfc20f00 4600 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4fb21e90 4601
9199f050 4602(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
00188daa
UB
4603 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4604 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
27ac40e2
UB
4605 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4606 && TARGET_FISTTP
9199f050
UB
4607 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4608 && (TARGET_64BIT || <MODE>mode != DImode))
4609 && TARGET_SSE_MATH)
5071eab7 4610 && can_create_pseudo_p ()"
9199f050
UB
4611 "#"
4612 "&& 1"
4613 [(const_int 0)]
4614{
4615 if (memory_operand (operands[0], VOIDmode))
4616 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4617 else
4618 {
ff680eb1 4619 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
9199f050
UB
4620 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4621 operands[1],
4622 operands[2]));
4623 }
4624 DONE;
4625}
4626 [(set_attr "type" "fisttp")
4627 (set_attr "mode" "<MODE>")])
22fb740d 4628
9199f050
UB
4629(define_insn "fix_trunc<mode>_i387_fisttp"
4630 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4631 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4632 (clobber (match_scratch:XF 2 "=&1f"))]
27ac40e2
UB
4633 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4634 && TARGET_FISTTP
9199f050
UB
4635 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4636 && (TARGET_64BIT || <MODE>mode != DImode))
4637 && TARGET_SSE_MATH)"
4638 "* return output_fix_trunc (insn, operands, 1);"
4639 [(set_attr "type" "fisttp")
4640 (set_attr "mode" "<MODE>")])
46d21d2c 4641
9199f050
UB
4642(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4643 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4644 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
73e8165a 4645 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
9199f050 4646 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
27ac40e2
UB
4647 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4648 && TARGET_FISTTP
9199f050
UB
4649 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4650 && (TARGET_64BIT || <MODE>mode != DImode))
4651 && TARGET_SSE_MATH)"
4652 "#"
4653 [(set_attr "type" "fisttp")
4654 (set_attr "mode" "<MODE>")])
2b589241 4655
9199f050
UB
4656(define_split
4657 [(set (match_operand:X87MODEI 0 "register_operand" "")
4658 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4659 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4660 (clobber (match_scratch 3 ""))]
4661 "reload_completed"
4662 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4663 (clobber (match_dup 3))])
cb1b497e 4664 (set (match_dup 0) (match_dup 2))])
46d21d2c 4665
9199f050
UB
4666(define_split
4667 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4668 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4669 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4670 (clobber (match_scratch 3 ""))]
4671 "reload_completed"
4672 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
cb1b497e 4673 (clobber (match_dup 3))])])
22fb740d
JH
4674
4675;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
9199f050
UB
4676;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4677;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4678;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4679;; function in i386.c.
4680(define_insn_and_split "*fix_trunc<mode>_i387_1"
00188daa
UB
4681 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4682 (fix:X87MODEI (match_operand 1 "register_operand" "")))
8bc527af 4683 (clobber (reg:CC FLAGS_REG))]
27ac40e2
UB
4684 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4685 && !TARGET_FISTTP
9199f050
UB
4686 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4687 && (TARGET_64BIT || <MODE>mode != DImode))
5071eab7 4688 && can_create_pseudo_p ()"
22fb740d 4689 "#"
d7518354 4690 "&& 1"
22fb740d
JH
4691 [(const_int 0)]
4692{
ff680eb1
UB
4693 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4694
4695 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4696 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
22fb740d 4697 if (memory_operand (operands[0], VOIDmode))
9199f050
UB
4698 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4699 operands[2], operands[3]));
22fb740d
JH
4700 else
4701 {
ff680eb1 4702 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
9199f050
UB
4703 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4704 operands[2], operands[3],
4705 operands[4]));
22fb740d
JH
4706 }
4707 DONE;
4708}
26f74aa3 4709 [(set_attr "type" "fistp")
edeacc14 4710 (set_attr "i387_cw" "trunc")
9199f050
UB
4711 (set_attr "mode" "<MODE>")])
4712
4713(define_insn "fix_truncdi_i387"
4714 [(set (match_operand:DI 0 "memory_operand" "=m")
4715 (fix:DI (match_operand 1 "register_operand" "f")))
4716 (use (match_operand:HI 2 "memory_operand" "m"))
4717 (use (match_operand:HI 3 "memory_operand" "m"))
4718 (clobber (match_scratch:XF 4 "=&1f"))]
27ac40e2
UB
4719 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4720 && !TARGET_FISTTP
9199f050
UB
4721 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4722 "* return output_fix_trunc (insn, operands, 0);"
4723 [(set_attr "type" "fistp")
4724 (set_attr "i387_cw" "trunc")
4725 (set_attr "mode" "DI")])
46d21d2c 4726
9199f050
UB
4727(define_insn "fix_truncdi_i387_with_temp"
4728 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4729 (fix:DI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
4730 (use (match_operand:HI 2 "memory_operand" "m,m"))
4731 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 4732 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
9199f050 4733 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
27ac40e2
UB
4734 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4735 && !TARGET_FISTTP
9199f050 4736 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
22fb740d 4737 "#"
26f74aa3 4738 [(set_attr "type" "fistp")
edeacc14 4739 (set_attr "i387_cw" "trunc")
9199f050 4740 (set_attr "mode" "DI")])
22fb740d 4741
6300f037 4742(define_split
9199f050
UB
4743 [(set (match_operand:DI 0 "register_operand" "")
4744 (fix:DI (match_operand 1 "register_operand" "")))
4745 (use (match_operand:HI 2 "memory_operand" ""))
4746 (use (match_operand:HI 3 "memory_operand" ""))
4747 (clobber (match_operand:DI 4 "memory_operand" ""))
4748 (clobber (match_scratch 5 ""))]
4749 "reload_completed"
4750 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4751 (use (match_dup 2))
4752 (use (match_dup 3))
4753 (clobber (match_dup 5))])
cb1b497e 4754 (set (match_dup 0) (match_dup 4))])
9199f050 4755
6300f037 4756(define_split
9199f050
UB
4757 [(set (match_operand:DI 0 "memory_operand" "")
4758 (fix:DI (match_operand 1 "register_operand" "")))
4759 (use (match_operand:HI 2 "memory_operand" ""))
4760 (use (match_operand:HI 3 "memory_operand" ""))
4761 (clobber (match_operand:DI 4 "memory_operand" ""))
4762 (clobber (match_scratch 5 ""))]
4763 "reload_completed"
4764 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4765 (use (match_dup 2))
4766 (use (match_dup 3))
cb1b497e 4767 (clobber (match_dup 5))])])
9199f050
UB
4768
4769(define_insn "fix_trunc<mode>_i387"
4770 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4771 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
22fb740d
JH
4772 (use (match_operand:HI 2 "memory_operand" "m"))
4773 (use (match_operand:HI 3 "memory_operand" "m"))]
27ac40e2
UB
4774 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4775 && !TARGET_FISTTP
22fb740d 4776 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
9199f050 4777 "* return output_fix_trunc (insn, operands, 0);"
26f74aa3 4778 [(set_attr "type" "fistp")
edeacc14 4779 (set_attr "i387_cw" "trunc")
9199f050
UB
4780 (set_attr "mode" "<MODE>")])
4781
4782(define_insn "fix_trunc<mode>_i387_with_temp"
4783 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4784 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4785 (use (match_operand:HI 2 "memory_operand" "m,m"))
4786 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 4787 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
27ac40e2
UB
4788 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4789 && !TARGET_FISTTP
9199f050
UB
4790 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4791 "#"
4792 [(set_attr "type" "fistp")
4793 (set_attr "i387_cw" "trunc")
4794 (set_attr "mode" "<MODE>")])
22fb740d 4795
6300f037 4796(define_split
9199f050
UB
4797 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4798 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
22fb740d
JH
4799 (use (match_operand:HI 2 "memory_operand" ""))
4800 (use (match_operand:HI 3 "memory_operand" ""))
9199f050 4801 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
22fb740d 4802 "reload_completed"
9199f050 4803 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
22fb740d 4804 (use (match_dup 2))
9199f050 4805 (use (match_dup 3))])
cb1b497e 4806 (set (match_dup 0) (match_dup 4))])
46d21d2c 4807
6300f037 4808(define_split
9199f050
UB
4809 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4810 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
7a2e09f4
JH
4811 (use (match_operand:HI 2 "memory_operand" ""))
4812 (use (match_operand:HI 3 "memory_operand" ""))
9199f050 4813 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
46d21d2c 4814 "reload_completed"
9199f050 4815 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
7a2e09f4 4816 (use (match_dup 2))
cb1b497e 4817 (use (match_dup 3))])])
46d21d2c 4818
e075ae69 4819(define_insn "x86_fnstcw_1"
c76aab11 4820 [(set (match_operand:HI 0 "memory_operand" "=m")
03c259ad 4821 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
e1f998ad 4822 "TARGET_80387"
0f40f9f7 4823 "fnstcw\t%0"
cb1b497e
UB
4824 [(set (attr "length")
4825 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
6ef67412 4826 (set_attr "mode" "HI")
56bab446 4827 (set_attr "unit" "i387")])
bc725565 4828
e075ae69 4829(define_insn "x86_fldcw_1"
03c259ad 4830 [(set (reg:HI FPCR_REG)
8ee41eaf 4831 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
bc725565 4832 "TARGET_80387"
0f40f9f7 4833 "fldcw\t%0"
cb1b497e
UB
4834 [(set (attr "length")
4835 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
6ef67412 4836 (set_attr "mode" "HI")
3d34cd91 4837 (set_attr "unit" "i387")
21efb4d4 4838 (set_attr "athlon_decode" "vector")
4f3f76e6 4839 (set_attr "amdfam10_decode" "vector")])
e075ae69
RH
4840\f
4841;; Conversion between fixed point and floating point.
886c62d1 4842
e075ae69
RH
4843;; Even though we only accept memory inputs, the backend _really_
4844;; wants to be able to do this between registers.
4845
0218c012 4846(define_expand "floathi<mode>2"
380edc9f
UB
4847 [(set (match_operand:X87MODEF 0 "register_operand" "")
4848 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4849 "TARGET_80387
4850 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
a427621f 4851 || TARGET_MIX_SSE_I387)")
35c28a13 4852
380edc9f
UB
4853;; Pre-reload splitter to add memory clobber to the pattern.
4854(define_insn_and_split "*floathi<mode>2_1"
4855 [(set (match_operand:X87MODEF 0 "register_operand" "")
4856 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4857 "TARGET_80387
4858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4859 || TARGET_MIX_SSE_I387)
5071eab7 4860 && can_create_pseudo_p ()"
380edc9f
UB
4861 "#"
4862 "&& 1"
4863 [(parallel [(set (match_dup 0)
4864 (float:X87MODEF (match_dup 1)))
4865 (clobber (match_dup 2))])]
4866 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4867
4868(define_insn "*floathi<mode>2_i387_with_temp"
4869 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4870 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4871 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
0218c012
UB
4872 "TARGET_80387
4873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4874 || TARGET_MIX_SSE_I387)"
380edc9f 4875 "#"
155d8a47 4876 [(set_attr "type" "fmov,multi")
0218c012 4877 (set_attr "mode" "<MODE>")
af12f8ea 4878 (set_attr "unit" "*,i387")
155d8a47
JW
4879 (set_attr "fp_int_src" "true")])
4880
380edc9f
UB
4881(define_insn "*floathi<mode>2_i387"
4882 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4883 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4884 "TARGET_80387
4885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4886 || TARGET_MIX_SSE_I387)"
a3a5e3d1 4887 "fild%Z1\t%1"
380edc9f
UB
4888 [(set_attr "type" "fmov")
4889 (set_attr "mode" "<MODE>")
630ecd8d
JH
4890 (set_attr "fp_int_src" "true")])
4891
4f3f76e6 4892(define_split
380edc9f
UB
4893 [(set (match_operand:X87MODEF 0 "register_operand" "")
4894 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4895 (clobber (match_operand:HI 2 "memory_operand" ""))]
4896 "TARGET_80387
4897 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4898 || TARGET_MIX_SSE_I387)
4899 && reload_completed"
4900 [(set (match_dup 2) (match_dup 1))
cb1b497e 4901 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4845dbb5 4902
4f3f76e6 4903(define_split
380edc9f
UB
4904 [(set (match_operand:X87MODEF 0 "register_operand" "")
4905 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4906 (clobber (match_operand:HI 2 "memory_operand" ""))]
4907 "TARGET_80387
4908 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4909 || TARGET_MIX_SSE_I387)
4910 && reload_completed"
cb1b497e 4911 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4845dbb5 4912
380edc9f
UB
4913(define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4914 [(set (match_operand:X87MODEF 0 "register_operand" "")
4915 (float:X87MODEF
4916 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4917 "TARGET_80387
4918 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4919 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
8ce94e44
JM
4920{
4921 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4922 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4923 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4924 {
4925 rtx reg = gen_reg_rtx (XFmode);
458c00ff
UB
4926 rtx insn;
4927
8ce94e44 4928 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
458c00ff
UB
4929
4930 if (<X87MODEF:MODE>mode == SFmode)
4931 insn = gen_truncxfsf2 (operands[0], reg);
4932 else if (<X87MODEF:MODE>mode == DFmode)
4933 insn = gen_truncxfdf2 (operands[0], reg);
4934 else
4935 gcc_unreachable ();
4936
4937 emit_insn (insn);
8ce94e44
JM
4938 DONE;
4939 }
4afd0ef4 4940})
bc725565 4941
380edc9f
UB
4942;; Pre-reload splitter to add memory clobber to the pattern.
4943(define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4944 [(set (match_operand:X87MODEF 0 "register_operand" "")
4945 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4946 "((TARGET_80387
8ce94e44 4947 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
380edc9f
UB
4948 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4949 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4950 || TARGET_MIX_SSE_I387))
4951 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4952 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4953 && ((<SSEMODEI24:MODE>mode == SImode
3debdc1e
JH
4954 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4955 && optimize_function_for_speed_p (cfun)
380edc9f 4956 && flag_trapping_math)
3debdc1e
JH
4957 || !(TARGET_INTER_UNIT_CONVERSIONS
4958 || optimize_function_for_size_p (cfun)))))
5071eab7 4959 && can_create_pseudo_p ()"
380edc9f
UB
4960 "#"
4961 "&& 1"
4962 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4963 (clobber (match_dup 2))])]
7b198002
UB
4964{
4965 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4966
4967 /* Avoid store forwarding (partial memory) stall penalty
4968 by passing DImode value through XMM registers. */
1ffcdc02
L
4969 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4970 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
3debdc1e 4971 && optimize_function_for_speed_p (cfun))
7b198002
UB
4972 {
4973 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4974 operands[1],
4975 operands[2]));
4976 DONE;
4977 }
4978})
630ecd8d 4979
380edc9f
UB
4980(define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4981 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4982 (float:MODEF
4983 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
73e8165a 4984 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4845dbb5 4985 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3debdc1e 4986 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
380edc9f 4987 "#"
4845dbb5 4988 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
380edc9f 4989 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4845dbb5
JH
4990 (set_attr "unit" "*,i387,*,*,*")
4991 (set_attr "athlon_decode" "*,*,double,direct,double")
4992 (set_attr "amdfam10_decode" "*,*,vector,double,double")
380edc9f 4993 (set_attr "fp_int_src" "true")])
4845dbb5 4994
380edc9f
UB
4995(define_insn "*floatsi<mode>2_vector_mixed"
4996 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4997 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
630ecd8d 4998 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3debdc1e 4999 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
630ecd8d 5000 "@
a3a5e3d1 5001 fild%Z1\t%1
380edc9f 5002 #"
630ecd8d 5003 [(set_attr "type" "fmov,sseicvt")
380edc9f
UB
5004 (set_attr "mode" "<MODE>,<ssevecmode>")
5005 (set_attr "unit" "i387,*")
630ecd8d
JH
5006 (set_attr "athlon_decode" "*,direct")
5007 (set_attr "amdfam10_decode" "*,double")
5008 (set_attr "fp_int_src" "true")])
5009
380edc9f
UB
5010(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5011 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5012 (float:MODEF
5013 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
73e8165a 5014 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
380edc9f
UB
5015 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5016 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5017 "#"
5018 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5019 (set_attr "mode" "<MODEF:MODE>")
5020 (set_attr "unit" "*,i387,*,*")
5021 (set_attr "athlon_decode" "*,*,double,direct")
5022 (set_attr "amdfam10_decode" "*,*,vector,double")
0218c012
UB
5023 (set_attr "fp_int_src" "true")])
5024
4f3f76e6 5025(define_split
380edc9f
UB
5026 [(set (match_operand:MODEF 0 "register_operand" "")
5027 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5028 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5029 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5030 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5031 && TARGET_INTER_UNIT_CONVERSIONS
5032 && reload_completed
5033 && (SSE_REG_P (operands[0])
5034 || (GET_CODE (operands[0]) == SUBREG
5035 && SSE_REG_P (operands[0])))"
cb1b497e 5036 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
0218c012 5037
380edc9f
UB
5038(define_split
5039 [(set (match_operand:MODEF 0 "register_operand" "")
5040 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5041 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5042 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5043 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
3debdc1e 5044 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
380edc9f
UB
5045 && reload_completed
5046 && (SSE_REG_P (operands[0])
5047 || (GET_CODE (operands[0]) == SUBREG
5048 && SSE_REG_P (operands[0])))"
5049 [(set (match_dup 2) (match_dup 1))
cb1b497e 5050 (set (match_dup 0) (float:MODEF (match_dup 2)))])
630ecd8d 5051
380edc9f
UB
5052(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5053 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
00188daa 5054 (float:MODEF
0d5fd2b8 5055 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
380edc9f
UB
5056 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5057 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
3debdc1e 5058 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
e075ae69 5059 "@
a3a5e3d1 5060 fild%Z1\t%1
95879c72
L
5061 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5062 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
380edc9f 5063 [(set_attr "type" "fmov,sseicvt,sseicvt")
95879c72 5064 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
380edc9f 5065 (set_attr "mode" "<MODEF:MODE>")
a952487c
JJ
5066 (set (attr "prefix_rex")
5067 (if_then_else
5068 (and (eq_attr "prefix" "maybe_vex")
5069 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5070 (const_string "1")
5071 (const_string "*")))
380edc9f
UB
5072 (set_attr "unit" "i387,*,*")
5073 (set_attr "athlon_decode" "*,double,direct")
5074 (set_attr "amdfam10_decode" "*,vector,double")
46ed7963
JH
5075 (set_attr "fp_int_src" "true")])
5076
380edc9f
UB
5077(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5078 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5079 (float:MODEF
5080 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5081 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5082 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
3debdc1e 5083 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
630ecd8d 5084 "@
a3a5e3d1 5085 fild%Z1\t%1
95879c72 5086 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
630ecd8d 5087 [(set_attr "type" "fmov,sseicvt")
95879c72 5088 (set_attr "prefix" "orig,maybe_vex")
380edc9f 5089 (set_attr "mode" "<MODEF:MODE>")
a952487c
JJ
5090 (set (attr "prefix_rex")
5091 (if_then_else
5092 (and (eq_attr "prefix" "maybe_vex")
5093 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5094 (const_string "1")
5095 (const_string "*")))
380edc9f 5096 (set_attr "athlon_decode" "*,direct")
630ecd8d
JH
5097 (set_attr "amdfam10_decode" "*,double")
5098 (set_attr "fp_int_src" "true")])
5099
380edc9f
UB
5100(define_insn "*floatsi<mode>2_vector_sse_with_temp"
5101 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5102 (float:MODEF
5103 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
73e8165a 5104 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
380edc9f 5105 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5106 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
380edc9f 5107 "#"
f56e86bd 5108 [(set_attr "type" "sseicvt")
380edc9f
UB
5109 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5110 (set_attr "athlon_decode" "double,direct,double")
5111 (set_attr "amdfam10_decode" "vector,double,double")
e075ae69 5112 (set_attr "fp_int_src" "true")])
bc725565 5113
380edc9f
UB
5114(define_insn "*floatsi<mode>2_vector_sse"
5115 [(set (match_operand:MODEF 0 "register_operand" "=x")
5116 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5117 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5118 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
380edc9f 5119 "#"
630ecd8d 5120 [(set_attr "type" "sseicvt")
380edc9f
UB
5121 (set_attr "mode" "<MODE>")
5122 (set_attr "athlon_decode" "direct")
630ecd8d
JH
5123 (set_attr "amdfam10_decode" "double")
5124 (set_attr "fp_int_src" "true")])
5125
380edc9f
UB
5126(define_split
5127 [(set (match_operand:MODEF 0 "register_operand" "")
5128 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5129 (clobber (match_operand:SI 2 "memory_operand" ""))]
5130 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5131 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
380edc9f
UB
5132 && reload_completed
5133 && (SSE_REG_P (operands[0])
5134 || (GET_CODE (operands[0]) == SUBREG
5135 && SSE_REG_P (operands[0])))"
5136 [(const_int 0)]
ebff937c 5137{
380edc9f
UB
5138 rtx op1 = operands[1];
5139
5140 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5141 <MODE>mode, 0);
5142 if (GET_CODE (op1) == SUBREG)
5143 op1 = SUBREG_REG (op1);
5144
5145 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
ebff937c 5146 {
380edc9f
UB
5147 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5148 emit_insn (gen_sse2_loadld (operands[4],
5149 CONST0_RTX (V4SImode), operands[1]));
ebff937c 5150 }
380edc9f
UB
5151 /* We can ignore possible trapping value in the
5152 high part of SSE register for non-trapping math. */
5153 else if (SSE_REG_P (op1) && !flag_trapping_math)
5154 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5155 else
630ecd8d 5156 {
380edc9f
UB
5157 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5158 emit_move_insn (operands[2], operands[1]);
5159 emit_insn (gen_sse2_loadld (operands[4],
5160 CONST0_RTX (V4SImode), operands[2]));
630ecd8d 5161 }
380edc9f
UB
5162 emit_insn
5163 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5164 DONE;
ebff937c 5165})
da8947b0 5166
380edc9f
UB
5167(define_split
5168 [(set (match_operand:MODEF 0 "register_operand" "")
5169 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5170 (clobber (match_operand:SI 2 "memory_operand" ""))]
5171 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5172 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
380edc9f
UB
5173 && reload_completed
5174 && (SSE_REG_P (operands[0])
5175 || (GET_CODE (operands[0]) == SUBREG
5176 && SSE_REG_P (operands[0])))"
5177 [(const_int 0)]
5178{
5179 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5180 <MODE>mode, 0);
5181 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5182
5183 emit_insn (gen_sse2_loadld (operands[4],
5184 CONST0_RTX (V4SImode), operands[1]));
5185 emit_insn
5186 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5187 DONE;
5188})
46ed7963 5189
380edc9f
UB
5190(define_split
5191 [(set (match_operand:MODEF 0 "register_operand" "")
5192 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5193 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5194 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
380edc9f
UB
5195 && reload_completed
5196 && (SSE_REG_P (operands[0])
5197 || (GET_CODE (operands[0]) == SUBREG
5198 && SSE_REG_P (operands[0])))"
5199 [(const_int 0)]
5200{
5201 rtx op1 = operands[1];
5202
5203 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5204 <MODE>mode, 0);
5205 if (GET_CODE (op1) == SUBREG)
5206 op1 = SUBREG_REG (op1);
5207
5208 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5209 {
5210 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5211 emit_insn (gen_sse2_loadld (operands[4],
5212 CONST0_RTX (V4SImode), operands[1]));
5213 }
5214 /* We can ignore possible trapping value in the
5215 high part of SSE register for non-trapping math. */
5216 else if (SSE_REG_P (op1) && !flag_trapping_math)
5217 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5218 else
5219 gcc_unreachable ();
ddd5eeb1
L
5220 emit_insn
5221 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5222 DONE;
380edc9f
UB
5223})
5224
5225(define_split
5226 [(set (match_operand:MODEF 0 "register_operand" "")
5227 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5228 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5229 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
380edc9f
UB
5230 && reload_completed
5231 && (SSE_REG_P (operands[0])
5232 || (GET_CODE (operands[0]) == SUBREG
5233 && SSE_REG_P (operands[0])))"
5234 [(const_int 0)]
5235{
5236 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5237 <MODE>mode, 0);
5238 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5239
5240 emit_insn (gen_sse2_loadld (operands[4],
5241 CONST0_RTX (V4SImode), operands[1]));
5242 emit_insn
5243 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5244 DONE;
5245})
5246
5247(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5248 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5249 (float:MODEF
5250 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
73e8165a 5251 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
380edc9f
UB
5252 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5253 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5254 "#"
5255 [(set_attr "type" "sseicvt")
5256 (set_attr "mode" "<MODEF:MODE>")
5257 (set_attr "athlon_decode" "double,direct")
5258 (set_attr "amdfam10_decode" "vector,double")
630ecd8d
JH
5259 (set_attr "fp_int_src" "true")])
5260
380edc9f
UB
5261(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5262 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5263 (float:MODEF
5264 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5265 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5266 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
3debdc1e 5267 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
95879c72 5268 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
f56e86bd 5269 [(set_attr "type" "sseicvt")
95879c72 5270 (set_attr "prefix" "maybe_vex")
380edc9f 5271 (set_attr "mode" "<MODEF:MODE>")
a952487c
JJ
5272 (set (attr "prefix_rex")
5273 (if_then_else
5274 (and (eq_attr "prefix" "maybe_vex")
5275 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5276 (const_string "1")
5277 (const_string "*")))
f56e86bd 5278 (set_attr "athlon_decode" "double,direct")
21efb4d4 5279 (set_attr "amdfam10_decode" "vector,double")
e075ae69 5280 (set_attr "fp_int_src" "true")])
bc725565 5281
380edc9f
UB
5282(define_split
5283 [(set (match_operand:MODEF 0 "register_operand" "")
5284 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5285 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5286 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5287 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
3debdc1e 5288 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
380edc9f
UB
5289 && reload_completed
5290 && (SSE_REG_P (operands[0])
5291 || (GET_CODE (operands[0]) == SUBREG
5292 && SSE_REG_P (operands[0])))"
cb1b497e 5293 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
380edc9f
UB
5294
5295(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5296 [(set (match_operand:MODEF 0 "register_operand" "=x")
5297 (float:MODEF
5298 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5299 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
3debdc1e 5301 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
95879c72 5302 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
630ecd8d 5303 [(set_attr "type" "sseicvt")
95879c72 5304 (set_attr "prefix" "maybe_vex")
380edc9f 5305 (set_attr "mode" "<MODEF:MODE>")
a952487c
JJ
5306 (set (attr "prefix_rex")
5307 (if_then_else
5308 (and (eq_attr "prefix" "maybe_vex")
5309 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5310 (const_string "1")
5311 (const_string "*")))
630ecd8d
JH
5312 (set_attr "athlon_decode" "direct")
5313 (set_attr "amdfam10_decode" "double")
5314 (set_attr "fp_int_src" "true")])
5315
380edc9f
UB
5316(define_split
5317 [(set (match_operand:MODEF 0 "register_operand" "")
5318 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5319 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5320 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5321 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
3debdc1e 5322 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
380edc9f
UB
5323 && reload_completed
5324 && (SSE_REG_P (operands[0])
5325 || (GET_CODE (operands[0]) == SUBREG
5326 && SSE_REG_P (operands[0])))"
5327 [(set (match_dup 2) (match_dup 1))
cb1b497e 5328 (set (match_dup 0) (float:MODEF (match_dup 2)))])
380edc9f
UB
5329
5330(define_split
5331 [(set (match_operand:MODEF 0 "register_operand" "")
5332 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5333 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5334 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5335 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5336 && reload_completed
5337 && (SSE_REG_P (operands[0])
5338 || (GET_CODE (operands[0]) == SUBREG
5339 && SSE_REG_P (operands[0])))"
cb1b497e 5340 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
380edc9f
UB
5341
5342(define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5343 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5344 (float:X87MODEF
5345 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
73e8165a 5346 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
8ce94e44
JM
5347 "TARGET_80387
5348 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
2b589241 5349 "@
a3a5e3d1 5350 fild%Z1\t%1
2b589241
JH
5351 #"
5352 [(set_attr "type" "fmov,multi")
380edc9f 5353 (set_attr "mode" "<X87MODEF:MODE>")
af12f8ea 5354 (set_attr "unit" "*,i387")
2b589241
JH
5355 (set_attr "fp_int_src" "true")])
5356
380edc9f
UB
5357(define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5358 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5359 (float:X87MODEF
5360 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
8ce94e44
JM
5361 "TARGET_80387
5362 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
a3a5e3d1 5363 "fild%Z1\t%1"
380edc9f
UB
5364 [(set_attr "type" "fmov")
5365 (set_attr "mode" "<X87MODEF:MODE>")
2b589241
JH
5366 (set_attr "fp_int_src" "true")])
5367
155d8a47 5368(define_split
380edc9f
UB
5369 [(set (match_operand:X87MODEF 0 "register_operand" "")
5370 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5371 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5372 "TARGET_80387
8ce94e44 5373 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
380edc9f
UB
5374 && reload_completed
5375 && FP_REG_P (operands[0])"
5376 [(set (match_dup 2) (match_dup 1))
cb1b497e 5377 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
380edc9f
UB
5378
5379(define_split
5380 [(set (match_operand:X87MODEF 0 "register_operand" "")
5381 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5382 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5383 "TARGET_80387
8ce94e44 5384 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
380edc9f
UB
5385 && reload_completed
5386 && FP_REG_P (operands[0])"
cb1b497e 5387 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
8d705469 5388
7b198002
UB
5389;; Avoid store forwarding (partial memory) stall penalty
5390;; by passing DImode value through XMM registers. */
5391
5392(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5393 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5394 (float:X87MODEF
5395 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
73e8165a
UB
5396 (clobber (match_scratch:V4SI 3 "=X,x"))
5397 (clobber (match_scratch:V4SI 4 "=X,x"))
5398 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
8ce94e44
JM
5399 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5400 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
3debdc1e 5401 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
7b198002
UB
5402 "#"
5403 [(set_attr "type" "multi")
5404 (set_attr "mode" "<X87MODEF:MODE>")
5405 (set_attr "unit" "i387")
5406 (set_attr "fp_int_src" "true")])
5407
5408(define_split
5409 [(set (match_operand:X87MODEF 0 "register_operand" "")
5410 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
e356fac8
UB
5411 (clobber (match_scratch:V4SI 3 ""))
5412 (clobber (match_scratch:V4SI 4 ""))
7b198002 5413 (clobber (match_operand:DI 2 "memory_operand" ""))]
8ce94e44
JM
5414 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5415 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
3debdc1e 5416 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
7b198002
UB
5417 && reload_completed
5418 && FP_REG_P (operands[0])"
5419 [(set (match_dup 2) (match_dup 3))
5420 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5421{
5422 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5423 Assemble the 64-bit DImode value in an xmm register. */
5424 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5425 gen_rtx_SUBREG (SImode, operands[1], 0)));
5426 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5427 gen_rtx_SUBREG (SImode, operands[1], 4)));
b0d49a6e
RH
5428 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5429 operands[4]));
7b198002
UB
5430
5431 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5432})
5433
5434(define_split
5435 [(set (match_operand:X87MODEF 0 "register_operand" "")
5436 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
e356fac8
UB
5437 (clobber (match_scratch:V4SI 3 ""))
5438 (clobber (match_scratch:V4SI 4 ""))
5439 (clobber (match_operand:DI 2 "memory_operand" ""))]
8ce94e44
JM
5440 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5441 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
3debdc1e 5442 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
7b198002
UB
5443 && reload_completed
5444 && FP_REG_P (operands[0])"
cb1b497e 5445 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
7b198002 5446
7fb1431b
UB
5447;; Avoid store forwarding (partial memory) stall penalty by extending
5448;; SImode value to DImode through XMM register instead of pushing two
5449;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5450;; targets benefit from this optimization. Also note that fild
5451;; loads from memory only.
5452
5453(define_insn "*floatunssi<mode>2_1"
5454 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5455 (unsigned_float:X87MODEF
5456 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5457 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5458 (clobber (match_scratch:SI 3 "=X,x"))]
5459 "!TARGET_64BIT
8f612190 5460 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
8ce94e44 5461 && TARGET_SSE"
7fb1431b
UB
5462 "#"
5463 [(set_attr "type" "multi")
5464 (set_attr "mode" "<MODE>")])
5465
5466(define_split
5467 [(set (match_operand:X87MODEF 0 "register_operand" "")
5468 (unsigned_float:X87MODEF
5469 (match_operand:SI 1 "register_operand" "")))
5470 (clobber (match_operand:DI 2 "memory_operand" ""))
5471 (clobber (match_scratch:SI 3 ""))]
5472 "!TARGET_64BIT
8f612190 5473 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
8ce94e44 5474 && TARGET_SSE
7fb1431b
UB
5475 && reload_completed"
5476 [(set (match_dup 2) (match_dup 1))
5477 (set (match_dup 0)
5478 (float:X87MODEF (match_dup 2)))]
5479 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5480
5481(define_split
5482 [(set (match_operand:X87MODEF 0 "register_operand" "")
5483 (unsigned_float:X87MODEF
5484 (match_operand:SI 1 "memory_operand" "")))
5485 (clobber (match_operand:DI 2 "memory_operand" ""))
5486 (clobber (match_scratch:SI 3 ""))]
5487 "!TARGET_64BIT
8f612190 5488 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
8ce94e44 5489 && TARGET_SSE
7fb1431b
UB
5490 && reload_completed"
5491 [(set (match_dup 2) (match_dup 3))
5492 (set (match_dup 0)
5493 (float:X87MODEF (match_dup 2)))]
5494{
5495 emit_move_insn (operands[3], operands[1]);
5496 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5497})
5498
def7425b 5499(define_expand "floatunssi<mode>2"
7fb1431b
UB
5500 [(parallel
5501 [(set (match_operand:X87MODEF 0 "register_operand" "")
5502 (unsigned_float:X87MODEF
5503 (match_operand:SI 1 "nonimmediate_operand" "")))
5504 (clobber (match_dup 2))
5505 (clobber (match_scratch:SI 3 ""))])]
5506 "!TARGET_64BIT
8f612190 5507 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
8ce94e44 5508 && TARGET_SSE)
7fb1431b 5509 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
ebff937c 5510{
7fb1431b
UB
5511 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5512 {
5513 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5514 DONE;
5515 }
5516 else
5517 {
bbbbb16a
ILT
5518 enum ix86_stack_slot slot = (virtuals_instantiated
5519 ? SLOT_TEMP
5520 : SLOT_VIRTUAL);
7fb1431b
UB
5521 operands[2] = assign_386_stack_local (DImode, slot);
5522 }
ebff937c
SH
5523})
5524
8d705469
JH
5525(define_expand "floatunsdisf2"
5526 [(use (match_operand:SF 0 "register_operand" ""))
ebff937c 5527 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
da8947b0 5528 "TARGET_64BIT && TARGET_SSE_MATH"
8d705469
JH
5529 "x86_emit_floatuns (operands); DONE;")
5530
5531(define_expand "floatunsdidf2"
5532 [(use (match_operand:DF 0 "register_operand" ""))
ebff937c 5533 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
def7425b
UB
5534 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5535 && TARGET_SSE2 && TARGET_SSE_MATH"
ebff937c
SH
5536{
5537 if (TARGET_64BIT)
5538 x86_emit_floatuns (operands);
5539 else
5540 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5541 DONE;
5542})
997404de 5543\f
e075ae69 5544;; Add instructions
53b5ce19 5545
d2407a7a 5546(define_expand "add<mode>3"
458c00ff
UB
5547 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5548 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5549 (match_operand:SDWIM 2 "<general_operand>" "")))]
9b70259d 5550 ""
d2407a7a 5551 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
9b70259d 5552
68bc0874
UB
5553(define_insn_and_split "*add<dwi>3_doubleword"
5554 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5555 (plus:<DWI>
5556 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5557 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
8bc527af 5558 (clobber (reg:CC FLAGS_REG))]
68bc0874 5559 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
d2407a7a
UB
5560 "#"
5561 "reload_completed"
5562 [(parallel [(set (reg:CC FLAGS_REG)
5563 (unspec:CC [(match_dup 1) (match_dup 2)]
5564 UNSPEC_ADD_CARRY))
5565 (set (match_dup 0)
68bc0874 5566 (plus:DWIH (match_dup 1) (match_dup 2)))])
e075ae69 5567 (parallel [(set (match_dup 3)
68bc0874 5568 (plus:DWIH
14c27152 5569 (match_dup 4)
68bc0874
UB
5570 (plus:DWIH
5571 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
14c27152 5572 (match_dup 5))))
8bc527af 5573 (clobber (reg:CC FLAGS_REG))])]
b146446c 5574 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
d2407a7a 5575
d2407a7a 5576(define_insn "*add<mode>3_cc"
8bc527af 5577 [(set (reg:CC FLAGS_REG)
d2407a7a
UB
5578 (unspec:CC
5579 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5580 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5581 UNSPEC_ADD_CARRY))
5582 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5583 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5584 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5585 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
265dab10 5586 [(set_attr "type" "alu")
d2407a7a 5587 (set_attr "mode" "<MODE>")])
7e08e190
JH
5588
5589(define_insn "addqi3_cc"
8bc527af 5590 [(set (reg:CC FLAGS_REG)
d2407a7a
UB
5591 (unspec:CC
5592 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5593 (match_operand:QI 2 "general_operand" "qn,qm")]
5594 UNSPEC_ADD_CARRY))
7e08e190
JH
5595 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5596 (plus:QI (match_dup 1) (match_dup 2)))]
5597 "ix86_binary_operator_ok (PLUS, QImode, operands)"
0f40f9f7 5598 "add{b}\t{%2, %0|%0, %2}"
7e08e190
JH
5599 [(set_attr "type" "alu")
5600 (set_attr "mode" "QI")])
265dab10 5601
68bc0874 5602(define_insn "*lea_1"
f1b62c9f
UB
5603 [(set (match_operand:P 0 "register_operand" "=r")
5604 (match_operand:P 1 "no_seg_address_operand" "p"))]
68bc0874
UB
5605 ""
5606 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
f8921d7d 5607 [(set_attr "type" "lea")
68bc0874 5608 (set_attr "mode" "<MODE>")])
f8921d7d 5609
68bc0874 5610(define_insn "*lea_2"
f8921d7d 5611 [(set (match_operand:SI 0 "register_operand" "=r")
68bc0874
UB
5612 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5613 "TARGET_64BIT"
f8921d7d
UB
5614 "lea{l}\t{%a1, %0|%0, %a1}"
5615 [(set_attr "type" "lea")
5616 (set_attr "mode" "SI")])
5617
68bc0874 5618(define_insn "*lea_2_zext"
f8921d7d
UB
5619 [(set (match_operand:DI 0 "register_operand" "=r")
5620 (zero_extend:DI
68bc0874 5621 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
f8921d7d
UB
5622 "TARGET_64BIT"
5623 "lea{l}\t{%a1, %k0|%k0, %a1}"
5624 [(set_attr "type" "lea")
5625 (set_attr "mode" "SI")])
5626
d2407a7a 5627(define_insn "*add<mode>_1"
ff534e89 5628 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
d2407a7a 5629 (plus:SWI48
ff534e89
L
5630 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5631 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
d2407a7a
UB
5632 (clobber (reg:CC FLAGS_REG))]
5633 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5634{
5635 switch (get_attr_type (insn))
5636 {
5637 case TYPE_LEA:
21667997 5638 return "#";
ac62a60e 5639
d2407a7a
UB
5640 case TYPE_INCDEC:
5641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642 if (operands[2] == const1_rtx)
5643 return "inc{<imodesuffix>}\t%0";
5644 else
5645 {
5646 gcc_assert (operands[2] == constm1_rtx);
5647 return "dec{<imodesuffix>}\t%0";
5648 }
ac62a60e 5649
d2407a7a 5650 default:
21667997
UB
5651 /* For most processors, ADD is faster than LEA. This alternative
5652 was added to use ADD as much as possible. */
1c111d0a 5653 if (which_alternative == 2)
21667997
UB
5654 {
5655 rtx tmp;
5656 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5657 }
ff534e89 5658
d2407a7a 5659 gcc_assert (rtx_equal_p (operands[0], operands[1]));
d079b87f
UB
5660 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5661 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
58787064 5662
d2407a7a
UB
5663 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5664 }
0f40f9f7 5665}
d2407a7a 5666 [(set (attr "type")
1c111d0a 5667 (cond [(eq_attr "alternative" "3")
ff534e89 5668 (const_string "lea")
d2407a7a
UB
5669 (match_operand:SWI48 2 "incdec_operand" "")
5670 (const_string "incdec")
5671 ]
5672 (const_string "alu")))
5673 (set (attr "length_immediate")
5674 (if_then_else
5675 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5676 (const_string "1")
5677 (const_string "*")))
5678 (set_attr "mode" "<MODE>")])
58787064 5679
d2407a7a
UB
5680;; It may seem that nonimmediate operand is proper one for operand 1.
5681;; The addsi_1 pattern allows nonimmediate operand at that place and
5682;; we take care in ix86_binary_operator_ok to not allow two memory
5683;; operands so proper swapping will be done in reload. This allow
5684;; patterns constructed from addsi_1 to match.
5685
5686(define_insn "*addsi_1_zext"
21667997 5687 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
ac62a60e 5688 (zero_extend:DI
21667997
UB
5689 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5690 (match_operand:SI 2 "general_operand" "g,0,li"))))
d2407a7a
UB
5691 (clobber (reg:CC FLAGS_REG))]
5692 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
ac62a60e 5693{
d2407a7a
UB
5694 switch (get_attr_type (insn))
5695 {
5696 case TYPE_LEA:
21667997 5697 return "#";
9b70259d 5698
e075ae69
RH
5699 case TYPE_INCDEC:
5700 if (operands[2] == const1_rtx)
0f40f9f7 5701 return "inc{l}\t%k0";
9b70259d 5702 else
7637e42c
NS
5703 {
5704 gcc_assert (operands[2] == constm1_rtx);
5705 return "dec{l}\t%k0";
5706 }
9b70259d
JH
5707
5708 default:
21667997
UB
5709 /* For most processors, ADD is faster than LEA. This alternative
5710 was added to use ADD as much as possible. */
5711 if (which_alternative == 1)
5712 {
5713 rtx tmp;
5714 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5715 }
5716
d079b87f
UB
5717 if (x86_maybe_negate_const_int (&operands[2], SImode))
5718 return "sub{l}\t{%2, %k0|%k0, %2}";
5719
0f40f9f7 5720 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 5721 }
0f40f9f7 5722}
9b70259d 5723 [(set (attr "type")
21667997 5724 (cond [(eq_attr "alternative" "2")
9b70259d 5725 (const_string "lea")
9b70259d
JH
5726 (match_operand:SI 2 "incdec_operand" "")
5727 (const_string "incdec")
5728 ]
5729 (const_string "alu")))
a952487c
JJ
5730 (set (attr "length_immediate")
5731 (if_then_else
5732 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5733 (const_string "1")
5734 (const_string "*")))
9b70259d
JH
5735 (set_attr "mode" "SI")])
5736
d2407a7a
UB
5737(define_insn "*addhi_1"
5738 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5739 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5740 (match_operand:HI 2 "general_operand" "rn,rm")))
8bc527af 5741 (clobber (reg:CC FLAGS_REG))]
d2407a7a
UB
5742 "TARGET_PARTIAL_REG_STALL
5743 && ix86_binary_operator_ok (PLUS, HImode, operands)"
9b70259d
JH
5744{
5745 switch (get_attr_type (insn))
5746 {
5747 case TYPE_INCDEC:
9b70259d 5748 if (operands[2] == const1_rtx)
d2407a7a 5749 return "inc{w}\t%0";
9b70259d 5750 else
7637e42c
NS
5751 {
5752 gcc_assert (operands[2] == constm1_rtx);
d2407a7a 5753 return "dec{w}\t%0";
7637e42c 5754 }
9b70259d
JH
5755
5756 default:
d079b87f
UB
5757 if (x86_maybe_negate_const_int (&operands[2], HImode))
5758 return "sub{w}\t{%2, %0|%0, %2}";
5759
d2407a7a 5760 return "add{w}\t{%2, %0|%0, %2}";
9b70259d 5761 }
0f40f9f7 5762}
9b70259d 5763 [(set (attr "type")
d2407a7a 5764 (if_then_else (match_operand:HI 2 "incdec_operand" "")
9b70259d
JH
5765 (const_string "incdec")
5766 (const_string "alu")))
a952487c
JJ
5767 (set (attr "length_immediate")
5768 (if_then_else
5769 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5770 (const_string "1")
5771 (const_string "*")))
d2407a7a 5772 (set_attr "mode" "HI")])
9b70259d 5773
d2407a7a 5774(define_insn "*addhi_1_lea"
21667997
UB
5775 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5776 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5777 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
d2407a7a
UB
5778 (clobber (reg:CC FLAGS_REG))]
5779 "!TARGET_PARTIAL_REG_STALL
5780 && ix86_binary_operator_ok (PLUS, HImode, operands)"
9b70259d
JH
5781{
5782 switch (get_attr_type (insn))
5783 {
d2407a7a
UB
5784 case TYPE_LEA:
5785 return "#";
7d1f0f8a 5786
9b70259d 5787 case TYPE_INCDEC:
7d1f0f8a 5788 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d 5789 if (operands[2] == const1_rtx)
d2407a7a 5790 return "inc{w}\t%0";
9b70259d 5791 else
7637e42c
NS
5792 {
5793 gcc_assert (operands[2] == constm1_rtx);
d2407a7a 5794 return "dec{w}\t%0";
7637e42c 5795 }
9b70259d
JH
5796
5797 default:
21667997
UB
5798 /* For most processors, ADD is faster than LEA. This alternative
5799 was added to use ADD as much as possible. */
5800 if (which_alternative == 2)
5801 {
5802 rtx tmp;
5803 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5804 }
5805
7d1f0f8a 5806 gcc_assert (rtx_equal_p (operands[0], operands[1]));
d079b87f
UB
5807 if (x86_maybe_negate_const_int (&operands[2], HImode))
5808 return "sub{w}\t{%2, %0|%0, %2}";
5809
d2407a7a 5810 return "add{w}\t{%2, %0|%0, %2}";
9b70259d 5811 }
0f40f9f7 5812}
9b70259d 5813 [(set (attr "type")
21667997
UB
5814 (cond [(eq_attr "alternative" "3")
5815 (const_string "lea")
5816 (match_operand:HI 2 "incdec_operand" "")
5817 (const_string "incdec")
5818 ]
5819 (const_string "alu")))
a952487c
JJ
5820 (set (attr "length_immediate")
5821 (if_then_else
5822 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5823 (const_string "1")
5824 (const_string "*")))
21667997 5825 (set_attr "mode" "HI,HI,HI,SI")])
9b70259d 5826
21667997 5827;; %%% Potential partial reg stall on alternative 2. What to do?
d2407a7a
UB
5828(define_insn "*addqi_1"
5829 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5830 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5831 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "TARGET_PARTIAL_REG_STALL
5834 && ix86_binary_operator_ok (PLUS, QImode, operands)"
9b70259d 5835{
d2407a7a 5836 int widen = (which_alternative == 2);
9b70259d
JH
5837 switch (get_attr_type (insn))
5838 {
5839 case TYPE_INCDEC:
9b70259d 5840 if (operands[2] == const1_rtx)
d2407a7a 5841 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
9b70259d 5842 else
d2407a7a 5843 {
7637e42c 5844 gcc_assert (operands[2] == constm1_rtx);
d2407a7a 5845 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7637e42c 5846 }
9b70259d
JH
5847
5848 default:
d079b87f 5849 if (x86_maybe_negate_const_int (&operands[2], QImode))
d2407a7a 5850 {
d2407a7a
UB
5851 if (widen)
5852 return "sub{l}\t{%2, %k0|%k0, %2}";
5853 else
5854 return "sub{b}\t{%2, %0|%0, %2}";
5855 }
5856 if (widen)
5857 return "add{l}\t{%k2, %k0|%k0, %k2}";
5858 else
5859 return "add{b}\t{%2, %0|%0, %2}";
9b70259d 5860 }
0f40f9f7 5861}
9b70259d 5862 [(set (attr "type")
d2407a7a 5863 (if_then_else (match_operand:QI 2 "incdec_operand" "")
9b70259d
JH
5864 (const_string "incdec")
5865 (const_string "alu")))
a952487c
JJ
5866 (set (attr "length_immediate")
5867 (if_then_else
5868 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5869 (const_string "1")
5870 (const_string "*")))
d2407a7a 5871 (set_attr "mode" "QI,QI,SI")])
9b70259d 5872
21667997 5873;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
d2407a7a 5874(define_insn "*addqi_1_lea"
21667997
UB
5875 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5876 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5877 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
d2407a7a
UB
5878 (clobber (reg:CC FLAGS_REG))]
5879 "!TARGET_PARTIAL_REG_STALL
5880 && ix86_binary_operator_ok (PLUS, QImode, operands)"
9b70259d 5881{
21667997
UB
5882 int widen = (which_alternative == 3 || which_alternative == 4);
5883
9b70259d
JH
5884 switch (get_attr_type (insn))
5885 {
d2407a7a
UB
5886 case TYPE_LEA:
5887 return "#";
7d1f0f8a 5888
9b70259d 5889 case TYPE_INCDEC:
7d1f0f8a 5890 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d 5891 if (operands[2] == const1_rtx)
d2407a7a 5892 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
9b70259d 5893 else
d2407a7a 5894 {
7637e42c 5895 gcc_assert (operands[2] == constm1_rtx);
d2407a7a 5896 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7637e42c 5897 }
9b70259d
JH
5898
5899 default:
21667997
UB
5900 /* For most processors, ADD is faster than LEA. These alternatives
5901 were added to use ADD as much as possible. */
5902 if (which_alternative == 2 || which_alternative == 4)
5903 {
5904 rtx tmp;
5905 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5906 }
5907
7d1f0f8a 5908 gcc_assert (rtx_equal_p (operands[0], operands[1]));
d079b87f 5909 if (x86_maybe_negate_const_int (&operands[2], QImode))
d2407a7a 5910 {
d2407a7a
UB
5911 if (widen)
5912 return "sub{l}\t{%2, %k0|%k0, %2}";
5913 else
5914 return "sub{b}\t{%2, %0|%0, %2}";
5915 }
5916 if (widen)
5917 return "add{l}\t{%k2, %k0|%k0, %k2}";
5918 else
5919 return "add{b}\t{%2, %0|%0, %2}";
9b70259d 5920 }
0f40f9f7 5921}
9b70259d 5922 [(set (attr "type")
21667997
UB
5923 (cond [(eq_attr "alternative" "5")
5924 (const_string "lea")
5925 (match_operand:QI 2 "incdec_operand" "")
5926 (const_string "incdec")
5927 ]
5928 (const_string "alu")))
a952487c
JJ
5929 (set (attr "length_immediate")
5930 (if_then_else
5931 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5932 (const_string "1")
5933 (const_string "*")))
21667997 5934 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
9b70259d 5935
d2407a7a
UB
5936(define_insn "*addqi_1_slp"
5937 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5938 (plus:QI (match_dup 0)
5939 (match_operand:QI 1 "general_operand" "qn,qnm")))
5940 (clobber (reg:CC FLAGS_REG))]
5941 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5942 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9b70259d
JH
5943{
5944 switch (get_attr_type (insn))
5945 {
5946 case TYPE_INCDEC:
d2407a7a
UB
5947 if (operands[1] == const1_rtx)
5948 return "inc{b}\t%0";
9b70259d 5949 else
d2407a7a
UB
5950 {
5951 gcc_assert (operands[1] == constm1_rtx);
5952 return "dec{b}\t%0";
7637e42c 5953 }
9b70259d
JH
5954
5955 default:
d079b87f
UB
5956 if (x86_maybe_negate_const_int (&operands[1], QImode))
5957 return "sub{b}\t{%1, %0|%0, %1}";
5958
d2407a7a 5959 return "add{b}\t{%1, %0|%0, %1}";
9b70259d 5960 }
0f40f9f7 5961}
9b70259d 5962 [(set (attr "type")
d2407a7a 5963 (if_then_else (match_operand:QI 1 "incdec_operand" "")
9b70259d 5964 (const_string "incdec")
d2407a7a
UB
5965 (const_string "alu1")))
5966 (set (attr "memory")
5967 (if_then_else (match_operand 1 "memory_operand" "")
5968 (const_string "load")
5969 (const_string "none")))
5970 (set_attr "mode" "QI")])
9b70259d 5971
f1b62c9f
UB
5972;; Convert lea to the lea pattern to avoid flags dependency.
5973(define_split
5974 [(set (match_operand 0 "register_operand" "")
5975 (plus (match_operand 1 "register_operand" "")
5976 (match_operand 2 "nonmemory_operand" "")))
5977 (clobber (reg:CC FLAGS_REG))]
5978 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5979 [(const_int 0)]
5980{
5981 rtx pat;
5982 enum machine_mode mode = GET_MODE (operands[0]);
5983
5984 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5985 may confuse gen_lowpart. */
5986 if (mode != Pmode)
5987 {
5988 operands[1] = gen_lowpart (Pmode, operands[1]);
5989 operands[2] = gen_lowpart (Pmode, operands[2]);
5990 }
5991
5992 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5993
5994 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5995 operands[0] = gen_lowpart (SImode, operands[0]);
5996
5997 if (TARGET_64BIT && mode != Pmode)
5998 pat = gen_rtx_SUBREG (SImode, pat, 0);
5999
6000 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6001 DONE;
6002})
6003
6004;; Convert lea to the lea pattern to avoid flags dependency.
6005;; ??? This pattern handles immediate operands that do not satisfy immediate
6006;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6007(define_split
6008 [(set (match_operand:DI 0 "register_operand" "")
6009 (plus:DI (match_operand:DI 1 "register_operand" "")
6010 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6011 (clobber (reg:CC FLAGS_REG))]
6012 "TARGET_64BIT && reload_completed
6013 && true_regnum (operands[0]) != true_regnum (operands[1])"
6014 [(set (match_dup 0)
cb1b497e 6015 (plus:DI (match_dup 1) (match_dup 2)))])
f1b62c9f
UB
6016
6017;; Convert lea to the lea pattern to avoid flags dependency.
6018(define_split
6019 [(set (match_operand:DI 0 "register_operand" "")
6020 (zero_extend:DI
6021 (plus:SI (match_operand:SI 1 "register_operand" "")
6022 (match_operand:SI 2 "nonmemory_operand" ""))))
6023 (clobber (reg:CC FLAGS_REG))]
6024 "TARGET_64BIT && reload_completed
6025 && ix86_lea_for_add_ok (insn, operands)"
6026 [(set (match_dup 0)
6027 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6028{
6029 operands[1] = gen_lowpart (DImode, operands[1]);
6030 operands[2] = gen_lowpart (DImode, operands[2]);
6031})
6032
d2407a7a 6033(define_insn "*add<mode>_2"
42fabf21 6034 [(set (reg FLAGS_REG)
9b70259d 6035 (compare
ad1f7916
UB
6036 (plus:SWI
6037 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6038 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6300f037 6039 (const_int 0)))
ad1f7916
UB
6040 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6041 (plus:SWI (match_dup 1) (match_dup 2)))]
9b70259d 6042 "ix86_match_ccmode (insn, CCGOCmode)
308e51aa 6043 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9b70259d
JH
6044{
6045 switch (get_attr_type (insn))
6046 {
6047 case TYPE_INCDEC:
9b70259d 6048 if (operands[2] == const1_rtx)
d2407a7a 6049 return "inc{<imodesuffix>}\t%0";
9b70259d 6050 else
7637e42c
NS
6051 {
6052 gcc_assert (operands[2] == constm1_rtx);
d2407a7a 6053 return "dec{<imodesuffix>}\t%0";
7637e42c 6054 }
9b70259d
JH
6055
6056 default:
d079b87f
UB
6057 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6058 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6059
d2407a7a 6060 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
9b70259d 6061 }
0f40f9f7 6062}
9b70259d 6063 [(set (attr "type")
ad1f7916 6064 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
9b70259d
JH
6065 (const_string "incdec")
6066 (const_string "alu")))
a952487c
JJ
6067 (set (attr "length_immediate")
6068 (if_then_else
6069 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6070 (const_string "1")
6071 (const_string "*")))
d2407a7a 6072 (set_attr "mode" "<MODE>")])
9b70259d 6073
d2407a7a
UB
6074;; See comment for addsi_1_zext why we do use nonimmediate_operand
6075(define_insn "*addsi_2_zext"
6076 [(set (reg FLAGS_REG)
6077 (compare
6078 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6079 (match_operand:SI 2 "general_operand" "g"))
6080 (const_int 0)))
6081 (set (match_operand:DI 0 "register_operand" "=r")
6082 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6083 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
308e51aa 6084 && ix86_binary_operator_ok (PLUS, SImode, operands)"
9b70259d
JH
6085{
6086 switch (get_attr_type (insn))
6087 {
9b70259d
JH
6088 case TYPE_INCDEC:
6089 if (operands[2] == const1_rtx)
d2407a7a 6090 return "inc{l}\t%k0";
7637e42c
NS
6091 else
6092 {
6093 gcc_assert (operands[2] == constm1_rtx);
d2407a7a 6094 return "dec{l}\t%k0";
7637e42c 6095 }
9b70259d
JH
6096
6097 default:
d079b87f
UB
6098 if (x86_maybe_negate_const_int (&operands[2], SImode))
6099 return "sub{l}\t{%2, %k0|%k0, %2}";
6100
d2407a7a 6101 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 6102 }
0f40f9f7 6103}
9b70259d 6104 [(set (attr "type")
d2407a7a
UB
6105 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6106 (const_string "incdec")
6107 (const_string "alu")))
a952487c
JJ
6108 (set (attr "length_immediate")
6109 (if_then_else
6110 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6111 (const_string "1")
6112 (const_string "*")))
d2407a7a 6113 (set_attr "mode" "SI")])
9b70259d 6114
d2407a7a 6115(define_insn "*add<mode>_3"
42fabf21 6116 [(set (reg FLAGS_REG)
d2407a7a 6117 (compare
ad1f7916
UB
6118 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6119 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6120 (clobber (match_scratch:SWI 0 "=<r>"))]
7e08e190 6121 "ix86_match_ccmode (insn, CCZmode)
308e51aa 6122 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
d90ffc8d
JH
6123{
6124 switch (get_attr_type (insn))
6125 {
6126 case TYPE_INCDEC:
6127 if (operands[2] == const1_rtx)
d2407a7a 6128 return "inc{<imodesuffix>}\t%0";
7637e42c
NS
6129 else
6130 {
6131 gcc_assert (operands[2] == constm1_rtx);
d2407a7a 6132 return "dec{<imodesuffix>}\t%0";
7637e42c 6133 }
d90ffc8d
JH
6134
6135 default:
d079b87f
UB
6136 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6137 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6138
d2407a7a 6139 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
d90ffc8d 6140 }
0f40f9f7 6141}
d90ffc8d 6142 [(set (attr "type")
ad1f7916 6143 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
d90ffc8d
JH
6144 (const_string "incdec")
6145 (const_string "alu")))
a952487c
JJ
6146 (set (attr "length_immediate")
6147 (if_then_else
6148 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6149 (const_string "1")
6150 (const_string "*")))
d2407a7a 6151 (set_attr "mode" "<MODE>")])
d90ffc8d 6152
d2407a7a
UB
6153;; See comment for addsi_1_zext why we do use nonimmediate_operand
6154(define_insn "*addsi_3_zext"
42fabf21 6155 [(set (reg FLAGS_REG)
d2407a7a
UB
6156 (compare
6157 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6158 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6159 (set (match_operand:DI 0 "register_operand" "=r")
6160 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6161 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
308e51aa 6162 && ix86_binary_operator_ok (PLUS, SImode, operands)"
7e08e190
JH
6163{
6164 switch (get_attr_type (insn))
6165 {
6166 case TYPE_INCDEC:
d2407a7a
UB
6167 if (operands[2] == const1_rtx)
6168 return "inc{l}\t%k0";
7e08e190 6169 else
d2407a7a
UB
6170 {
6171 gcc_assert (operands[2] == constm1_rtx);
6172 return "dec{l}\t%k0";
7637e42c 6173 }
7e08e190
JH
6174
6175 default:
d079b87f
UB
6176 if (x86_maybe_negate_const_int (&operands[2], SImode))
6177 return "sub{l}\t{%2, %k0|%k0, %2}";
6178
d2407a7a 6179 return "add{l}\t{%2, %k0|%k0, %2}";
7e08e190 6180 }
0f40f9f7 6181}
7e08e190 6182 [(set (attr "type")
d2407a7a 6183 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7e08e190
JH
6184 (const_string "incdec")
6185 (const_string "alu")))
93cac287
JJ
6186 (set (attr "length_immediate")
6187 (if_then_else
725fd454 6188 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
93cac287
JJ
6189 (const_string "1")
6190 (const_string "*")))
d2407a7a 6191 (set_attr "mode" "SI")])
d90ffc8d 6192
d2407a7a
UB
6193; For comparisons against 1, -1 and 128, we may generate better code
6194; by converting cmp to add, inc or dec as done by peephole2. This pattern
6195; is matched then. We can't accept general immediate, because for
6196; case of overflows, the result is messed up.
d2407a7a
UB
6197; Also carry flag is reversed compared to cmp, so this conversion is valid
6198; only for comparisons not depending on it.
6199
6200(define_insn "*adddi_4"
6201 [(set (reg FLAGS_REG)
6202 (compare
6203 (match_operand:DI 1 "nonimmediate_operand" "0")
6204 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6205 (clobber (match_scratch:DI 0 "=rm"))]
6206 "TARGET_64BIT
6207 && ix86_match_ccmode (insn, CCGCmode)"
6208{
6209 switch (get_attr_type (insn))
6210 {
6211 case TYPE_INCDEC:
6212 if (operands[2] == constm1_rtx)
6213 return "inc{q}\t%0";
58787064 6214 else
d2407a7a
UB
6215 {
6216 gcc_assert (operands[2] == const1_rtx);
6217 return "dec{q}\t%0";
6218 }
6219
6220 default:
d079b87f
UB
6221 if (x86_maybe_negate_const_int (&operands[2], DImode))
6222 return "add{q}\t{%2, %0|%0, %2}";
6223
6224 return "sub{q}\t{%2, %0|%0, %2}";
58787064 6225 }
0f40f9f7 6226}
58787064 6227 [(set (attr "type")
d2407a7a
UB
6228 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6229 (const_string "incdec")
6230 (const_string "alu")))
a952487c
JJ
6231 (set (attr "length_immediate")
6232 (if_then_else
6233 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6234 (const_string "1")
6235 (const_string "*")))
d2407a7a 6236 (set_attr "mode" "DI")])
58787064 6237
d2407a7a
UB
6238; For comparisons against 1, -1 and 128, we may generate better code
6239; by converting cmp to add, inc or dec as done by peephole2. This pattern
6240; is matched then. We can't accept general immediate, because for
6241; case of overflows, the result is messed up.
d2407a7a
UB
6242; Also carry flag is reversed compared to cmp, so this conversion is valid
6243; only for comparisons not depending on it.
6244
ad1f7916 6245(define_insn "*add<mode>_4"
d2407a7a
UB
6246 [(set (reg FLAGS_REG)
6247 (compare
ad1f7916
UB
6248 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6249 (match_operand:SWI124 2 "const_int_operand" "n")))
6250 (clobber (match_scratch:SWI124 0 "=<r>m"))]
d079b87f 6251 "ix86_match_ccmode (insn, CCGCmode)"
e075ae69 6252{
e075ae69 6253 switch (get_attr_type (insn))
5bc7cd8e 6254 {
e075ae69 6255 case TYPE_INCDEC:
d2407a7a 6256 if (operands[2] == constm1_rtx)
ad1f7916 6257 return "inc{<imodesuffix>}\t%0";
7637e42c 6258 else
d2407a7a
UB
6259 {
6260 gcc_assert (operands[2] == const1_rtx);
ad1f7916 6261 return "dec{<imodesuffix>}\t%0";
7637e42c 6262 }
2f41793e
JH
6263
6264 default:
ad1f7916
UB
6265 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6266 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
d079b87f 6267
ad1f7916 6268 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
2f41793e
JH
6269 }
6270}
6271 [(set (attr "type")
ad1f7916 6272 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
2f41793e 6273 (const_string "incdec")
d2407a7a
UB
6274 (const_string "alu")))
6275 (set (attr "length_immediate")
6276 (if_then_else
6277 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6278 (const_string "1")
6279 (const_string "*")))
ad1f7916 6280 (set_attr "mode" "<MODE>")])
e075ae69 6281
d2407a7a 6282(define_insn "*add<mode>_5"
42fabf21 6283 [(set (reg FLAGS_REG)
d2407a7a 6284 (compare
ad1f7916
UB
6285 (plus:SWI
6286 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6287 (match_operand:SWI 2 "<general_operand>" "<g>"))
d2407a7a 6288 (const_int 0)))
ad1f7916 6289 (clobber (match_scratch:SWI 0 "=<r>"))]
d2407a7a 6290 "ix86_match_ccmode (insn, CCGOCmode)
308e51aa 6291 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
d90ffc8d
JH
6292{
6293 switch (get_attr_type (insn))
6294 {
6295 case TYPE_INCDEC:
6296 if (operands[2] == const1_rtx)
d2407a7a 6297 return "inc{<imodesuffix>}\t%0";
7637e42c
NS
6298 else
6299 {
d2407a7a
UB
6300 gcc_assert (operands[2] == constm1_rtx);
6301 return "dec{<imodesuffix>}\t%0";
7637e42c 6302 }
d90ffc8d
JH
6303
6304 default:
d079b87f
UB
6305 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6306 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6307
d2407a7a 6308 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
d90ffc8d 6309 }
0f40f9f7 6310}
d90ffc8d 6311 [(set (attr "type")
ad1f7916 6312 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
d90ffc8d
JH
6313 (const_string "incdec")
6314 (const_string "alu")))
d2407a7a
UB
6315 (set (attr "length_immediate")
6316 (if_then_else
6317 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6318 (const_string "1")
6319 (const_string "*")))
6320 (set_attr "mode" "<MODE>")])
d90ffc8d 6321
d2407a7a 6322(define_insn "*addqi_ext_1_rex64"
3522082b 6323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6324 (const_int 8)
6325 (const_int 8))
6326 (plus:SI
6327 (zero_extract:SI
6328 (match_operand 1 "ext_register_operand" "0")
6329 (const_int 8)
6330 (const_int 8))
d2407a7a 6331 (match_operand:QI 2 "nonmemory_operand" "Qn")))
8bc527af 6332 (clobber (reg:CC FLAGS_REG))]
d2407a7a 6333 "TARGET_64BIT"
d2836273
JH
6334{
6335 switch (get_attr_type (insn))
6336 {
6337 case TYPE_INCDEC:
6338 if (operands[2] == const1_rtx)
0f40f9f7 6339 return "inc{b}\t%h0";
7637e42c
NS
6340 else
6341 {
ad1f7916 6342 gcc_assert (operands[2] == constm1_rtx);
7637e42c 6343 return "dec{b}\t%h0";
d2407a7a 6344 }
d2836273
JH
6345
6346 default:
0f40f9f7 6347 return "add{b}\t{%2, %h0|%h0, %2}";
d2836273 6348 }
0f40f9f7 6349}
d2836273
JH
6350 [(set (attr "type")
6351 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352 (const_string "incdec")
6353 (const_string "alu")))
725fd454 6354 (set_attr "modrm" "1")
d2836273
JH
6355 (set_attr "mode" "QI")])
6356
d2407a7a 6357(define_insn "addqi_ext_1"
d2836273
JH
6358 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6359 (const_int 8)
6360 (const_int 8))
6361 (plus:SI
6362 (zero_extract:SI
6363 (match_operand 1 "ext_register_operand" "0")
6364 (const_int 8)
6365 (const_int 8))
d2407a7a 6366 (match_operand:QI 2 "general_operand" "Qmn")))
8bc527af 6367 (clobber (reg:CC FLAGS_REG))]
d2407a7a 6368 "!TARGET_64BIT"
e075ae69
RH
6369{
6370 switch (get_attr_type (insn))
6371 {
6372 case TYPE_INCDEC:
6373 if (operands[2] == const1_rtx)
0f40f9f7 6374 return "inc{b}\t%h0";
7637e42c
NS
6375 else
6376 {
ad1f7916 6377 gcc_assert (operands[2] == constm1_rtx);
7637e42c 6378 return "dec{b}\t%h0";
d2407a7a 6379 }
886c62d1 6380
e075ae69 6381 default:
0f40f9f7 6382 return "add{b}\t{%2, %h0|%h0, %2}";
e075ae69 6383 }
0f40f9f7 6384}
e075ae69
RH
6385 [(set (attr "type")
6386 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6387 (const_string "incdec")
6ef67412 6388 (const_string "alu")))
725fd454 6389 (set_attr "modrm" "1")
6ef67412 6390 (set_attr "mode" "QI")])
e075ae69
RH
6391
6392(define_insn "*addqi_ext_2"
d2836273 6393 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6394 (const_int 8)
6395 (const_int 8))
6396 (plus:SI
6397 (zero_extract:SI
6398 (match_operand 1 "ext_register_operand" "%0")
6399 (const_int 8)
6400 (const_int 8))
6401 (zero_extract:SI
d2836273 6402 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
6403 (const_int 8)
6404 (const_int 8))))
8bc527af 6405 (clobber (reg:CC FLAGS_REG))]
e075ae69 6406 ""
0f40f9f7 6407 "add{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
6408 [(set_attr "type" "alu")
6409 (set_attr "mode" "QI")])
886c62d1 6410
d2407a7a
UB
6411;; The lea patterns for non-Pmodes needs to be matched by
6412;; several insns converted to real lea by splitters.
6413
6414(define_insn_and_split "*lea_general_1"
6415 [(set (match_operand 0 "register_operand" "=r")
6416 (plus (plus (match_operand 1 "index_register_operand" "l")
6417 (match_operand 2 "register_operand" "r"))
6418 (match_operand 3 "immediate_operand" "i")))]
6419 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6420 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6421 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6423 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6424 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6425 || GET_MODE (operands[3]) == VOIDmode)"
6426 "#"
6427 "&& reload_completed"
6428 [(const_int 0)]
6429{
6430 rtx pat;
6431 operands[0] = gen_lowpart (SImode, operands[0]);
6432 operands[1] = gen_lowpart (Pmode, operands[1]);
6433 operands[2] = gen_lowpart (Pmode, operands[2]);
6434 operands[3] = gen_lowpart (Pmode, operands[3]);
6435 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6436 operands[3]);
6437 if (Pmode != SImode)
6438 pat = gen_rtx_SUBREG (SImode, pat, 0);
6439 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6440 DONE;
6441}
6442 [(set_attr "type" "lea")
6443 (set_attr "mode" "SI")])
6444
6445(define_insn_and_split "*lea_general_1_zext"
6446 [(set (match_operand:DI 0 "register_operand" "=r")
6447 (zero_extend:DI
6448 (plus:SI (plus:SI
6449 (match_operand:SI 1 "index_register_operand" "l")
6450 (match_operand:SI 2 "register_operand" "r"))
6451 (match_operand:SI 3 "immediate_operand" "i"))))]
6452 "TARGET_64BIT"
6453 "#"
6454 "&& reload_completed"
6455 [(set (match_dup 0)
6456 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6457 (match_dup 2))
6458 (match_dup 3)) 0)))]
6459{
6460 operands[1] = gen_lowpart (Pmode, operands[1]);
6461 operands[2] = gen_lowpart (Pmode, operands[2]);
6462 operands[3] = gen_lowpart (Pmode, operands[3]);
6463}
6464 [(set_attr "type" "lea")
6465 (set_attr "mode" "SI")])
6466
6467(define_insn_and_split "*lea_general_2"
6468 [(set (match_operand 0 "register_operand" "=r")
6469 (plus (mult (match_operand 1 "index_register_operand" "l")
6470 (match_operand 2 "const248_operand" "i"))
6471 (match_operand 3 "nonmemory_operand" "ri")))]
6472 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6473 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6474 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6475 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6476 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6477 || GET_MODE (operands[3]) == VOIDmode)"
6478 "#"
6479 "&& reload_completed"
6480 [(const_int 0)]
6481{
6482 rtx pat;
6483 operands[0] = gen_lowpart (SImode, operands[0]);
6484 operands[1] = gen_lowpart (Pmode, operands[1]);
6485 operands[3] = gen_lowpart (Pmode, operands[3]);
6486 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6487 operands[3]);
6488 if (Pmode != SImode)
6489 pat = gen_rtx_SUBREG (SImode, pat, 0);
6490 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6491 DONE;
6492}
6493 [(set_attr "type" "lea")
6494 (set_attr "mode" "SI")])
6495
6496(define_insn_and_split "*lea_general_2_zext"
6497 [(set (match_operand:DI 0 "register_operand" "=r")
6498 (zero_extend:DI
6499 (plus:SI (mult:SI
6500 (match_operand:SI 1 "index_register_operand" "l")
6501 (match_operand:SI 2 "const248_operand" "n"))
6502 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6503 "TARGET_64BIT"
6504 "#"
6505 "&& reload_completed"
6506 [(set (match_dup 0)
6507 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6508 (match_dup 2))
6509 (match_dup 3)) 0)))]
6510{
6511 operands[1] = gen_lowpart (Pmode, operands[1]);
6512 operands[3] = gen_lowpart (Pmode, operands[3]);
6513}
6514 [(set_attr "type" "lea")
6515 (set_attr "mode" "SI")])
a269a03c 6516
d2407a7a
UB
6517(define_insn_and_split "*lea_general_3"
6518 [(set (match_operand 0 "register_operand" "=r")
6519 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6520 (match_operand 2 "const248_operand" "i"))
6521 (match_operand 3 "register_operand" "r"))
6522 (match_operand 4 "immediate_operand" "i")))]
6523 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6524 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6525 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6526 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6527 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6528 "#"
6529 "&& reload_completed"
6530 [(const_int 0)]
6531{
6532 rtx pat;
6533 operands[0] = gen_lowpart (SImode, operands[0]);
6534 operands[1] = gen_lowpart (Pmode, operands[1]);
6535 operands[3] = gen_lowpart (Pmode, operands[3]);
6536 operands[4] = gen_lowpart (Pmode, operands[4]);
6537 pat = gen_rtx_PLUS (Pmode,
6538 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6539 operands[2]),
6540 operands[3]),
6541 operands[4]);
6542 if (Pmode != SImode)
6543 pat = gen_rtx_SUBREG (SImode, pat, 0);
6544 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6545 DONE;
6546}
6547 [(set_attr "type" "lea")
6548 (set_attr "mode" "SI")])
28356f52 6549
d2407a7a
UB
6550(define_insn_and_split "*lea_general_3_zext"
6551 [(set (match_operand:DI 0 "register_operand" "=r")
6552 (zero_extend:DI
6553 (plus:SI (plus:SI
6554 (mult:SI
6555 (match_operand:SI 1 "index_register_operand" "l")
6556 (match_operand:SI 2 "const248_operand" "n"))
6557 (match_operand:SI 3 "register_operand" "r"))
6558 (match_operand:SI 4 "immediate_operand" "i"))))]
28356f52 6559 "TARGET_64BIT"
d2407a7a
UB
6560 "#"
6561 "&& reload_completed"
6562 [(set (match_dup 0)
6563 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6564 (match_dup 2))
6565 (match_dup 3))
6566 (match_dup 4)) 0)))]
6567{
6568 operands[1] = gen_lowpart (Pmode, operands[1]);
6569 operands[3] = gen_lowpart (Pmode, operands[3]);
6570 operands[4] = gen_lowpart (Pmode, operands[4]);
6571}
6572 [(set_attr "type" "lea")
6573 (set_attr "mode" "SI")])
d2407a7a
UB
6574\f
6575;; Subtract instructions
2ae0f82c 6576
d2407a7a 6577(define_expand "sub<mode>3"
458c00ff
UB
6578 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6579 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6580 (match_operand:SDWIM 2 "<general_operand>" "")))]
9b70259d 6581 ""
d2407a7a 6582 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
9c530261 6583
68bc0874
UB
6584(define_insn_and_split "*sub<dwi>3_doubleword"
6585 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6586 (minus:<DWI>
6587 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6588 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
8bc527af 6589 (clobber (reg:CC FLAGS_REG))]
d2407a7a
UB
6590 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6591 "#"
6592 "reload_completed"
6593 [(parallel [(set (reg:CC FLAGS_REG)
6594 (compare:CC (match_dup 1) (match_dup 2)))
6595 (set (match_dup 0)
68bc0874 6596 (minus:DWIH (match_dup 1) (match_dup 2)))])
e075ae69 6597 (parallel [(set (match_dup 3)
68bc0874 6598 (minus:DWIH
d2407a7a 6599 (match_dup 4)
68bc0874
UB
6600 (plus:DWIH
6601 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
d2407a7a 6602 (match_dup 5))))
8bc527af 6603 (clobber (reg:CC FLAGS_REG))])]
b146446c 6604 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
d2407a7a 6605
d2407a7a
UB
6606(define_insn "*sub<mode>_1"
6607 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6608 (minus:SWI
6609 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6610 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
8bc527af 6611 (clobber (reg:CC FLAGS_REG))]
d2407a7a
UB
6612 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6613 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6ef67412 6614 [(set_attr "type" "alu")
d2407a7a 6615 (set_attr "mode" "<MODE>")])
e075ae69 6616
9b70259d
JH
6617(define_insn "*subsi_1_zext"
6618 [(set (match_operand:DI 0 "register_operand" "=r")
6619 (zero_extend:DI
6620 (minus:SI (match_operand:SI 1 "register_operand" "0")
73f48658 6621 (match_operand:SI 2 "general_operand" "g"))))
8bc527af 6622 (clobber (reg:CC FLAGS_REG))]
9b70259d 6623 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6624 "sub{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
6625 [(set_attr "type" "alu")
6626 (set_attr "mode" "SI")])
6627
d2407a7a
UB
6628(define_insn "*subqi_1_slp"
6629 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6630 (minus:QI (match_dup 0)
6631 (match_operand:QI 1 "general_operand" "qn,qm")))
6632 (clobber (reg:CC FLAGS_REG))]
6633 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6634 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6635 "sub{b}\t{%1, %0|%0, %1}"
6636 [(set_attr "type" "alu1")
6637 (set_attr "mode" "QI")])
6638
6639(define_insn "*sub<mode>_2"
42fabf21 6640 [(set (reg FLAGS_REG)
16189740 6641 (compare
d2407a7a
UB
6642 (minus:SWI
6643 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6644 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
e075ae69 6645 (const_int 0)))
d2407a7a
UB
6646 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6647 (minus:SWI (match_dup 1) (match_dup 2)))]
9076b9c1 6648 "ix86_match_ccmode (insn, CCGOCmode)
d2407a7a
UB
6649 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6650 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
d90ffc8d 6651 [(set_attr "type" "alu")
d2407a7a 6652 (set_attr "mode" "<MODE>")])
d90ffc8d 6653
9b70259d 6654(define_insn "*subsi_2_zext"
42fabf21 6655 [(set (reg FLAGS_REG)
9b70259d
JH
6656 (compare
6657 (minus:SI (match_operand:SI 1 "register_operand" "0")
73f48658 6658 (match_operand:SI 2 "general_operand" "g"))
9b70259d
JH
6659 (const_int 0)))
6660 (set (match_operand:DI 0 "register_operand" "=r")
6661 (zero_extend:DI
6662 (minus:SI (match_dup 1)
6663 (match_dup 2))))]
6664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6666 "sub{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "SI")])
6669
d2407a7a 6670(define_insn "*sub<mode>_3"
42fabf21 6671 [(set (reg FLAGS_REG)
d2407a7a
UB
6672 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6674 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6675 (minus:SWI (match_dup 1) (match_dup 2)))]
16189740 6676 "ix86_match_ccmode (insn, CCmode)
d2407a7a
UB
6677 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6678 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6ef67412 6679 [(set_attr "type" "alu")
d2407a7a 6680 (set_attr "mode" "<MODE>")])
886c62d1 6681
9b70259d 6682(define_insn "*subsi_3_zext"
42fabf21 6683 [(set (reg FLAGS_REG)
10e9fecc 6684 (compare (match_operand:SI 1 "register_operand" "0")
73f48658 6685 (match_operand:SI 2 "general_operand" "g")))
9b70259d
JH
6686 (set (match_operand:DI 0 "register_operand" "=r")
6687 (zero_extend:DI
6688 (minus:SI (match_dup 1)
6689 (match_dup 2))))]
8362f420 6690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
9b70259d 6691 && ix86_binary_operator_ok (MINUS, SImode, operands)"
3dcdd4e4 6692 "sub{l}\t{%2, %1|%1, %2}"
9b70259d 6693 [(set_attr "type" "alu")
d2407a7a 6694 (set_attr "mode" "SI")])
14c27152
UB
6695\f
6696;; Add with carry and subtract with borrow
6697
6698(define_expand "<plusminus_insn><mode>3_carry"
6699 [(parallel
6700 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6701 (plusminus:SWI
6702 (match_operand:SWI 1 "nonimmediate_operand" "")
6703 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6704 [(match_operand 3 "flags_reg_operand" "")
6705 (const_int 0)])
6706 (match_operand:SWI 2 "<general_operand>" ""))))
6707 (clobber (reg:CC FLAGS_REG))])]
a427621f 6708 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
14c27152
UB
6709
6710(define_insn "*<plusminus_insn><mode>3_carry"
6711 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6712 (plusminus:SWI
6713 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6714 (plus:SWI
6715 (match_operator 3 "ix86_carry_flag_operator"
6716 [(reg FLAGS_REG) (const_int 0)])
6717 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6718 (clobber (reg:CC FLAGS_REG))]
6719 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6720 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6721 [(set_attr "type" "alu")
6722 (set_attr "use_carry" "1")
6723 (set_attr "pent_pair" "pu")
6724 (set_attr "mode" "<MODE>")])
e075ae69 6725
14c27152
UB
6726(define_insn "*addsi3_carry_zext"
6727 [(set (match_operand:DI 0 "register_operand" "=r")
6728 (zero_extend:DI
6729 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6730 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6731 [(reg FLAGS_REG) (const_int 0)])
6732 (match_operand:SI 2 "general_operand" "g")))))
6733 (clobber (reg:CC FLAGS_REG))]
6734 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6735 "adc{l}\t{%2, %k0|%k0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "use_carry" "1")
6738 (set_attr "pent_pair" "pu")
6739 (set_attr "mode" "SI")])
6740
6741(define_insn "*subsi3_carry_zext"
6742 [(set (match_operand:DI 0 "register_operand" "=r")
6743 (zero_extend:DI
6744 (minus:SI (match_operand:SI 1 "register_operand" "0")
6745 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6746 [(reg FLAGS_REG) (const_int 0)])
6747 (match_operand:SI 2 "general_operand" "g")))))
6748 (clobber (reg:CC FLAGS_REG))]
6749 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750 "sbb{l}\t{%2, %k0|%k0, %2}"
6751 [(set_attr "type" "alu")
6752 (set_attr "pent_pair" "pu")
6753 (set_attr "mode" "SI")])
6754\f
6755;; Overflow setting add and subtract instructions
6756
6757(define_insn "*add<mode>3_cconly_overflow"
6758 [(set (reg:CCC FLAGS_REG)
6759 (compare:CCC
6760 (plus:SWI
6761 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9aa5922d 6762 (match_operand:SWI 2 "<general_operand>" "<g>"))
14c27152
UB
6763 (match_dup 1)))
6764 (clobber (match_scratch:SWI 0 "=<r>"))]
f1b62c9f 6765 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
14c27152
UB
6766 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6767 [(set_attr "type" "alu")
6768 (set_attr "mode" "<MODE>")])
6769
6770(define_insn "*sub<mode>3_cconly_overflow"
6771 [(set (reg:CCC FLAGS_REG)
6772 (compare:CCC
6773 (minus:SWI
6774 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6775 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6776 (match_dup 0)))]
6777 ""
6778 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6779 [(set_attr "type" "icmp")
6780 (set_attr "mode" "<MODE>")])
2f41793e 6781
d2407a7a
UB
6782(define_insn "*<plusminus_insn><mode>3_cc_overflow"
6783 [(set (reg:CCC FLAGS_REG)
6784 (compare:CCC
6785 (plusminus:SWI
6786 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6787 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6788 (match_dup 1)))
6789 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6790 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6791 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6792 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
d90ffc8d 6793 [(set_attr "type" "alu")
d2407a7a 6794 (set_attr "mode" "<MODE>")])
d90ffc8d 6795
d2407a7a
UB
6796(define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6797 [(set (reg:CCC FLAGS_REG)
6798 (compare:CCC
6799 (plusminus:SI
6800 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6801 (match_operand:SI 2 "general_operand" "g"))
6802 (match_dup 1)))
6803 (set (match_operand:DI 0 "register_operand" "=r")
6804 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6805 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6806 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6ef67412 6807 [(set_attr "type" "alu")
d2407a7a 6808 (set_attr "mode" "SI")])
2ae0f82c 6809
886c62d1
JVA
6810;; The patterns that match these are at the end of this file.
6811
d2407a7a 6812(define_expand "<plusminus_insn>xf3"
4fb21e90 6813 [(set (match_operand:XF 0 "register_operand" "")
d2407a7a
UB
6814 (plusminus:XF
6815 (match_operand:XF 1 "register_operand" "")
6816 (match_operand:XF 2 "register_operand" "")))]
a427621f 6817 "TARGET_80387")
2b589241 6818
d2407a7a 6819(define_expand "<plusminus_insn><mode>3"
00188daa 6820 [(set (match_operand:MODEF 0 "register_operand" "")
d2407a7a
UB
6821 (plusminus:MODEF
6822 (match_operand:MODEF 1 "register_operand" "")
6823 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8ce94e44 6824 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
a427621f 6825 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
886c62d1 6826\f
e075ae69 6827;; Multiply instructions
886c62d1 6828
68bc0874
UB
6829(define_expand "mul<mode>3"
6830 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6831 (mult:SWIM248
6832 (match_operand:SWIM248 1 "register_operand" "")
6833 (match_operand:SWIM248 2 "<general_operand>" "")))
a427621f 6834 (clobber (reg:CC FLAGS_REG))])])
9b70259d 6835
68bc0874
UB
6836(define_expand "mulqi3"
6837 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6838 (mult:QI
6839 (match_operand:QI 1 "register_operand" "")
6840 (match_operand:QI 2 "nonimmediate_operand" "")))
8bc527af 6841 (clobber (reg:CC FLAGS_REG))])]
a427621f 6842 "TARGET_QIMODE_MATH")
d525dfdf 6843
4f3f76e6 6844;; On AMDFAM10
68bc0874
UB
6845;; IMUL reg32/64, reg32/64, imm8 Direct
6846;; IMUL reg32/64, mem32/64, imm8 VectorPath
6847;; IMUL reg32/64, reg32/64, imm32 Direct
6848;; IMUL reg32/64, mem32/64, imm32 VectorPath
6849;; IMUL reg32/64, reg32/64 Direct
6850;; IMUL reg32/64, mem32/64 Direct
6851
6852(define_insn "*mul<mode>3_1"
6853 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6854 (mult:SWI48
6855 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6856 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
8bc527af 6857 (clobber (reg:CC FLAGS_REG))]
7656aee4 6858 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
e075ae69 6859 "@
68bc0874
UB
6860 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6861 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6862 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
e075ae69 6863 [(set_attr "type" "imul")
6ef67412 6864 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
6865 (set (attr "athlon_decode")
6866 (cond [(eq_attr "cpu" "athlon")
6867 (const_string "vector")
6868 (eq_attr "alternative" "1")
6869 (const_string "vector")
6870 (and (eq_attr "alternative" "2")
6871 (match_operand 1 "memory_operand" ""))
6872 (const_string "vector")]
6873 (const_string "direct")))
21efb4d4
HJ
6874 (set (attr "amdfam10_decode")
6875 (cond [(and (eq_attr "alternative" "0,1")
6876 (match_operand 1 "memory_operand" ""))
6877 (const_string "vector")]
4f3f76e6 6878 (const_string "direct")))
68bc0874 6879 (set_attr "mode" "<MODE>")])
886c62d1 6880
9b70259d
JH
6881(define_insn "*mulsi3_1_zext"
6882 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6883 (zero_extend:DI
f56e86bd 6884 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9b70259d 6885 (match_operand:SI 2 "general_operand" "K,i,mr"))))
8bc527af 6886 (clobber (reg:CC FLAGS_REG))]
9b70259d 6887 "TARGET_64BIT
7656aee4 6888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9b70259d 6889 "@
0f40f9f7
ZW
6890 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6891 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6892 imul{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
6893 [(set_attr "type" "imul")
6894 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
6895 (set (attr "athlon_decode")
6896 (cond [(eq_attr "cpu" "athlon")
6897 (const_string "vector")
6898 (eq_attr "alternative" "1")
6899 (const_string "vector")
6900 (and (eq_attr "alternative" "2")
6901 (match_operand 1 "memory_operand" ""))
6902 (const_string "vector")]
6903 (const_string "direct")))
21efb4d4
HJ
6904 (set (attr "amdfam10_decode")
6905 (cond [(and (eq_attr "alternative" "0,1")
6906 (match_operand 1 "memory_operand" ""))
6907 (const_string "vector")]
4f3f76e6 6908 (const_string "direct")))
9b70259d
JH
6909 (set_attr "mode" "SI")])
6910
21efb4d4
HJ
6911;; On AMDFAM10
6912;; IMUL reg16, reg16, imm8 VectorPath
6913;; IMUL reg16, mem16, imm8 VectorPath
6914;; IMUL reg16, reg16, imm16 VectorPath
6915;; IMUL reg16, mem16, imm16 VectorPath
6916;; IMUL reg16, reg16 Direct
6917;; IMUL reg16, mem16 Direct
68bc0874 6918
d525dfdf 6919(define_insn "*mulhi3_1"
6ef67412 6920 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
f56e86bd 6921 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
0edb82cb 6922 (match_operand:HI 2 "general_operand" "K,n,mr")))
8bc527af 6923 (clobber (reg:CC FLAGS_REG))]
68bc0874
UB
6924 "TARGET_HIMODE_MATH
6925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
e075ae69 6926 "@
0f40f9f7
ZW
6927 imul{w}\t{%2, %1, %0|%0, %1, %2}
6928 imul{w}\t{%2, %1, %0|%0, %1, %2}
6929 imul{w}\t{%2, %0|%0, %2}"
6ef67412
JH
6930 [(set_attr "type" "imul")
6931 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
6932 (set (attr "athlon_decode")
6933 (cond [(eq_attr "cpu" "athlon")
6934 (const_string "vector")
6935 (eq_attr "alternative" "1,2")
6936 (const_string "vector")]
6937 (const_string "direct")))
21efb4d4
HJ
6938 (set (attr "amdfam10_decode")
6939 (cond [(eq_attr "alternative" "0,1")
6940 (const_string "vector")]
6941 (const_string "direct")))
6ef67412 6942 (set_attr "mode" "HI")])
886c62d1 6943
21efb4d4
HJ
6944;;On AMDFAM10
6945;; MUL reg8 Direct
6946;; MUL mem8 Direct
6947
558740bf 6948(define_insn "*mulqi3_1"
765a46f9 6949 [(set (match_operand:QI 0 "register_operand" "=a")
558740bf 6950 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
765a46f9 6951 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8bc527af 6952 (clobber (reg:CC FLAGS_REG))]
558740bf 6953 "TARGET_QIMODE_MATH
7656aee4 6954 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 6955 "mul{b}\t%2"
6ef67412
JH
6956 [(set_attr "type" "imul")
6957 (set_attr "length_immediate" "0")
f56e86bd
JH
6958 (set (attr "athlon_decode")
6959 (if_then_else (eq_attr "cpu" "athlon")
6960 (const_string "vector")
6961 (const_string "direct")))
4f3f76e6 6962 (set_attr "amdfam10_decode" "direct")
6ef67412 6963 (set_attr "mode" "QI")])
765a46f9 6964
68bc0874
UB
6965(define_expand "<u>mul<mode><dwi>3"
6966 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6967 (mult:<DWI>
6968 (any_extend:<DWI>
6969 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6970 (any_extend:<DWI>
6971 (match_operand:DWIH 2 "register_operand" ""))))
a427621f 6972 (clobber (reg:CC FLAGS_REG))])])
558740bf 6973
68bc0874 6974(define_expand "<u>mulqihi3"
558740bf 6975 [(parallel [(set (match_operand:HI 0 "register_operand" "")
68bc0874
UB
6976 (mult:HI
6977 (any_extend:HI
6978 (match_operand:QI 1 "nonimmediate_operand" ""))
6979 (any_extend:HI
6980 (match_operand:QI 2 "register_operand" ""))))
8bc527af 6981 (clobber (reg:CC FLAGS_REG))])]
a427621f 6982 "TARGET_QIMODE_MATH")
558740bf 6983
68bc0874
UB
6984(define_insn "*<u>mul<mode><dwi>3_1"
6985 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6986 (mult:<DWI>
6987 (any_extend:<DWI>
6988 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6989 (any_extend:<DWI>
6990 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
8bc527af 6991 (clobber (reg:CC FLAGS_REG))]
68bc0874
UB
6992 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6993 "<sgnprefix>mul{<imodesuffix>}\t%2"
9b70259d
JH
6994 [(set_attr "type" "imul")
6995 (set_attr "length_immediate" "0")
f56e86bd
JH
6996 (set (attr "athlon_decode")
6997 (if_then_else (eq_attr "cpu" "athlon")
6998 (const_string "vector")
6999 (const_string "double")))
21efb4d4 7000 (set_attr "amdfam10_decode" "double")
68bc0874 7001 (set_attr "mode" "<MODE>")])
558740bf 7002
68bc0874
UB
7003(define_insn "*<u>mulqihi3_1"
7004 [(set (match_operand:HI 0 "register_operand" "=a")
7005 (mult:HI
7006 (any_extend:HI
7007 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7008 (any_extend:HI
7009 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8bc527af 7010 (clobber (reg:CC FLAGS_REG))]
68bc0874 7011 "TARGET_QIMODE_MATH
7656aee4 7012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
68bc0874 7013 "<sgnprefix>mul{b}\t%2"
6ef67412
JH
7014 [(set_attr "type" "imul")
7015 (set_attr "length_immediate" "0")
f56e86bd
JH
7016 (set (attr "athlon_decode")
7017 (if_then_else (eq_attr "cpu" "athlon")
7018 (const_string "vector")
68bc0874
UB
7019 (const_string "direct")))
7020 (set_attr "amdfam10_decode" "direct")
7021 (set_attr "mode" "QI")])
2f2a49e8 7022
68bc0874
UB
7023(define_expand "<s>mul<mode>3_highpart"
7024 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7025 (truncate:SWI48
7026 (lshiftrt:<DWI>
7027 (mult:<DWI>
7028 (any_extend:<DWI>
7029 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7030 (any_extend:<DWI>
7031 (match_operand:SWI48 2 "register_operand" "")))
7032 (match_dup 4))))
7033 (clobber (match_scratch:SWI48 3 ""))
8bc527af 7034 (clobber (reg:CC FLAGS_REG))])]
68bc0874
UB
7035 ""
7036 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
558740bf 7037
68bc0874 7038(define_insn "*<s>muldi3_highpart_1"
9b70259d
JH
7039 [(set (match_operand:DI 0 "register_operand" "=d")
7040 (truncate:DI
7041 (lshiftrt:TI
68bc0874
UB
7042 (mult:TI
7043 (any_extend:TI
7044 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7045 (any_extend:TI
7046 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9b70259d 7047 (const_int 64))))
558740bf 7048 (clobber (match_scratch:DI 3 "=1"))
8bc527af 7049 (clobber (reg:CC FLAGS_REG))]
558740bf 7050 "TARGET_64BIT
7656aee4 7051 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
68bc0874 7052 "<sgnprefix>mul{q}\t%2"
9b70259d 7053 [(set_attr "type" "imul")
9b70259d 7054 (set_attr "length_immediate" "0")
f56e86bd
JH
7055 (set (attr "athlon_decode")
7056 (if_then_else (eq_attr "cpu" "athlon")
7057 (const_string "vector")
7058 (const_string "double")))
4f3f76e6 7059 (set_attr "amdfam10_decode" "double")
9b70259d
JH
7060 (set_attr "mode" "DI")])
7061
68bc0874 7062(define_insn "*<s>mulsi3_highpart_1"
2f2a49e8 7063 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
7064 (truncate:SI
7065 (lshiftrt:DI
68bc0874
UB
7066 (mult:DI
7067 (any_extend:DI
7068 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7069 (any_extend:DI
7070 (match_operand:SI 2 "nonimmediate_operand" "rm")))
e075ae69 7071 (const_int 32))))
558740bf 7072 (clobber (match_scratch:SI 3 "=1"))
8bc527af 7073 (clobber (reg:CC FLAGS_REG))]
7656aee4 7074 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
68bc0874 7075 "<sgnprefix>mul{l}\t%2"
32ee7d1d 7076 [(set_attr "type" "imul")
32ee7d1d 7077 (set_attr "length_immediate" "0")
f56e86bd
JH
7078 (set (attr "athlon_decode")
7079 (if_then_else (eq_attr "cpu" "athlon")
7080 (const_string "vector")
7081 (const_string "double")))
21efb4d4 7082 (set_attr "amdfam10_decode" "double")
32ee7d1d
JH
7083 (set_attr "mode" "SI")])
7084
68bc0874 7085(define_insn "*<s>mulsi3_highpart_zext"
32ee7d1d
JH
7086 [(set (match_operand:DI 0 "register_operand" "=d")
7087 (zero_extend:DI (truncate:SI
7088 (lshiftrt:DI
68bc0874 7089 (mult:DI (any_extend:DI
558740bf 7090 (match_operand:SI 1 "nonimmediate_operand" "%a"))
68bc0874 7091 (any_extend:DI
32ee7d1d
JH
7092 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7093 (const_int 32)))))
558740bf 7094 (clobber (match_scratch:SI 3 "=1"))
8bc527af 7095 (clobber (reg:CC FLAGS_REG))]
558740bf 7096 "TARGET_64BIT
7656aee4 7097 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
68bc0874 7098 "<sgnprefix>mul{l}\t%2"
e075ae69 7099 [(set_attr "type" "imul")
6ef67412 7100 (set_attr "length_immediate" "0")
f56e86bd
JH
7101 (set (attr "athlon_decode")
7102 (if_then_else (eq_attr "cpu" "athlon")
7103 (const_string "vector")
7104 (const_string "double")))
21efb4d4 7105 (set_attr "amdfam10_decode" "double")
6ef67412 7106 (set_attr "mode" "SI")])
2f2a49e8 7107
886c62d1
JVA
7108;; The patterns that match these are at the end of this file.
7109
4fb21e90
JVA
7110(define_expand "mulxf3"
7111 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
7112 (mult:XF (match_operand:XF 1 "register_operand" "")
7113 (match_operand:XF 2 "register_operand" "")))]
a427621f 7114 "TARGET_80387")
2b589241 7115
00188daa
UB
7116(define_expand "mul<mode>3"
7117 [(set (match_operand:MODEF 0 "register_operand" "")
7118 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7119 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8ce94e44 7120 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
a427621f 7121 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
886c62d1 7122\f
e075ae69 7123;; Divide instructions
886c62d1 7124
886c62d1
JVA
7125;; The patterns that match these are at the end of this file.
7126
4fb21e90
JVA
7127(define_expand "divxf3"
7128 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
7129 (div:XF (match_operand:XF 1 "register_operand" "")
7130 (match_operand:XF 2 "register_operand" "")))]
a427621f 7131 "TARGET_80387")
2b589241 7132
a78cb986
SC
7133(define_expand "divdf3"
7134 [(set (match_operand:DF 0 "register_operand" "")
7135 (div:DF (match_operand:DF 1 "register_operand" "")
7136 (match_operand:DF 2 "nonimmediate_operand" "")))]
8ce94e44 7137 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
a427621f 7138 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6300f037 7139
886c62d1
JVA
7140(define_expand "divsf3"
7141 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 7142 (div:SF (match_operand:SF 1 "register_operand" "")
886c62d1 7143 (match_operand:SF 2 "nonimmediate_operand" "")))]
8ce94e44
JM
7144 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7145 || TARGET_SSE_MATH"
6b889d89 7146{
18bd082d 7147 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
6b889d89
UB
7148 && flag_finite_math_only && !flag_trapping_math
7149 && flag_unsafe_math_optimizations)
7150 {
7151 ix86_emit_swdivsf (operands[0], operands[1],
7152 operands[2], SFmode);
7153 DONE;
7154 }
7155})
886c62d1 7156\f
9e51149d
UB
7157;; Divmod instructions.
7158
7159(define_expand "divmod<mode>4"
458c00ff
UB
7160 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7161 (div:SWIM248
7162 (match_operand:SWIM248 1 "register_operand" "")
7163 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7164 (set (match_operand:SWIM248 3 "register_operand" "")
7165 (mod:SWIM248 (match_dup 1) (match_dup 2)))
a427621f 7166 (clobber (reg:CC FLAGS_REG))])])
9b70259d 7167
26ec9308
L
7168;; Split with 8bit unsigned divide:
7169;; if (dividend an divisor are in [0-255])
7170;; use 8bit unsigned integer divide
7171;; else
7172;; use original integer divide
7173(define_split
7174 [(set (match_operand:SWI48 0 "register_operand" "")
7175 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7176 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7177 (set (match_operand:SWI48 1 "register_operand" "")
7178 (mod:SWI48 (match_dup 2) (match_dup 3)))
7179 (clobber (reg:CC FLAGS_REG))]
7180 "TARGET_USE_8BIT_IDIV
7181 && TARGET_QIMODE_MATH
7182 && can_create_pseudo_p ()
7183 && !optimize_insn_for_size_p ()"
7184 [(const_int 0)]
7185 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7186
7187(define_insn_and_split "divmod<mode>4_1"
7188 [(set (match_operand:SWI48 0 "register_operand" "=a")
7189 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7190 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7191 (set (match_operand:SWI48 1 "register_operand" "=&d")
7192 (mod:SWI48 (match_dup 2) (match_dup 3)))
7193 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7194 (clobber (reg:CC FLAGS_REG))]
7195 ""
7196 "#"
7197 "reload_completed"
7198 [(parallel [(set (match_dup 1)
7199 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7200 (clobber (reg:CC FLAGS_REG))])
7201 (parallel [(set (match_dup 0)
7202 (div:SWI48 (match_dup 2) (match_dup 3)))
7203 (set (match_dup 1)
7204 (mod:SWI48 (match_dup 2) (match_dup 3)))
7205 (use (match_dup 1))
7206 (clobber (reg:CC FLAGS_REG))])]
7207{
7208 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7209
7210 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7211 operands[4] = operands[2];
7212 else
7213 {
7214 /* Avoid use of cltd in favor of a mov+shift. */
7215 emit_move_insn (operands[1], operands[2]);
7216 operands[4] = operands[1];
7217 }
7218}
7219 [(set_attr "type" "multi")
7220 (set_attr "mode" "<MODE>")])
7221
b3df2256
UB
7222(define_insn_and_split "*divmod<mode>4"
7223 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7224 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7225 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7226 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7227 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7228 (clobber (reg:CC FLAGS_REG))]
7229 ""
7230 "#"
7231 "reload_completed"
7232 [(parallel [(set (match_dup 1)
7233 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7234 (clobber (reg:CC FLAGS_REG))])
7235 (parallel [(set (match_dup 0)
7236 (div:SWIM248 (match_dup 2) (match_dup 3)))
7237 (set (match_dup 1)
7238 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7239 (use (match_dup 1))
7240 (clobber (reg:CC FLAGS_REG))])]
7241{
7242 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7243
7244 if (<MODE>mode != HImode
7245 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7246 operands[4] = operands[2];
7247 else
7248 {
7249 /* Avoid use of cltd in favor of a mov+shift. */
7250 emit_move_insn (operands[1], operands[2]);
7251 operands[4] = operands[1];
7252 }
7253}
7254 [(set_attr "type" "multi")
7255 (set_attr "mode" "<MODE>")])
7256
9e51149d 7257(define_insn "*divmod<mode>4_noext"
458c00ff
UB
7258 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7259 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7260 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7261 (set (match_operand:SWIM248 1 "register_operand" "=d")
7262 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7263 (use (match_operand:SWIM248 4 "register_operand" "1"))
8bc527af 7264 (clobber (reg:CC FLAGS_REG))]
9e51149d
UB
7265 ""
7266 "idiv{<imodesuffix>}\t%3"
9b70259d 7267 [(set_attr "type" "idiv")
9e51149d 7268 (set_attr "mode" "<MODE>")])
9b70259d 7269
b3df2256
UB
7270(define_expand "divmodqi4"
7271 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7272 (div:QI
7273 (match_operand:QI 1 "register_operand" "")
7274 (match_operand:QI 2 "nonimmediate_operand" "")))
7275 (set (match_operand:QI 3 "register_operand" "")
7276 (mod:QI (match_dup 1) (match_dup 2)))
7277 (clobber (reg:CC FLAGS_REG))])]
7278 "TARGET_QIMODE_MATH"
7279{
7280 rtx div, mod, insn;
7281 rtx tmp0, tmp1;
7282
7283 tmp0 = gen_reg_rtx (HImode);
7284 tmp1 = gen_reg_rtx (HImode);
7285
7286 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7287 in AX. */
7288 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7289 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7290
7291 /* Extract remainder from AH. */
7292 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7293 insn = emit_move_insn (operands[3], tmp1);
7294
7295 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7296 set_unique_reg_note (insn, REG_EQUAL, mod);
7297
7298 /* Extract quotient from AL. */
7299 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7300
7301 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7302 set_unique_reg_note (insn, REG_EQUAL, div);
7303
7304 DONE;
7305})
7306
7307;; Divide AX by r/m8, with result stored in
7308;; AL <- Quotient
7309;; AH <- Remainder
7310;; Change div/mod to HImode and extend the second argument to HImode
7311;; so that mode of div/mod matches with mode of arguments. Otherwise
7312;; combine may fail.
7313(define_insn "divmodhiqi3"
7314 [(set (match_operand:HI 0 "register_operand" "=a")
7315 (ior:HI
7316 (ashift:HI
7317 (zero_extend:HI
7318 (truncate:QI
7319 (mod:HI (match_operand:HI 1 "register_operand" "0")
7320 (sign_extend:HI
7321 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7322 (const_int 8))
7323 (zero_extend:HI
7324 (truncate:QI
7325 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7326 (clobber (reg:CC FLAGS_REG))]
7327 "TARGET_QIMODE_MATH"
7328 "idiv{b}\t%2"
7329 [(set_attr "type" "idiv")
7330 (set_attr "mode" "QI")])
7331
9e51149d 7332(define_expand "udivmod<mode>4"
458c00ff
UB
7333 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7334 (udiv:SWIM248
7335 (match_operand:SWIM248 1 "register_operand" "")
7336 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7337 (set (match_operand:SWIM248 3 "register_operand" "")
7338 (umod:SWIM248 (match_dup 1) (match_dup 2)))
a427621f 7339 (clobber (reg:CC FLAGS_REG))])])
9b70259d 7340
26ec9308
L
7341;; Split with 8bit unsigned divide:
7342;; if (dividend an divisor are in [0-255])
7343;; use 8bit unsigned integer divide
7344;; else
7345;; use original integer divide
7346(define_split
7347 [(set (match_operand:SWI48 0 "register_operand" "")
7348 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7349 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7350 (set (match_operand:SWI48 1 "register_operand" "")
7351 (umod:SWI48 (match_dup 2) (match_dup 3)))
7352 (clobber (reg:CC FLAGS_REG))]
7353 "TARGET_USE_8BIT_IDIV
7354 && TARGET_QIMODE_MATH
7355 && can_create_pseudo_p ()
7356 && !optimize_insn_for_size_p ()"
7357 [(const_int 0)]
7358 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7359
7360(define_insn_and_split "udivmod<mode>4_1"
7361 [(set (match_operand:SWI48 0 "register_operand" "=a")
7362 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7363 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7364 (set (match_operand:SWI48 1 "register_operand" "=&d")
7365 (umod:SWI48 (match_dup 2) (match_dup 3)))
7366 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7367 (clobber (reg:CC FLAGS_REG))]
7368 ""
7369 "#"
7370 "reload_completed"
7371 [(set (match_dup 1) (const_int 0))
7372 (parallel [(set (match_dup 0)
7373 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7374 (set (match_dup 1)
7375 (umod:SWI48 (match_dup 2) (match_dup 3)))
7376 (use (match_dup 1))
7377 (clobber (reg:CC FLAGS_REG))])]
7378 ""
7379 [(set_attr "type" "multi")
7380 (set_attr "mode" "<MODE>")])
7381
b3df2256
UB
7382(define_insn_and_split "*udivmod<mode>4"
7383 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7384 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7385 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7386 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7387 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7388 (clobber (reg:CC FLAGS_REG))]
7389 ""
7390 "#"
7391 "reload_completed"
7392 [(set (match_dup 1) (const_int 0))
7393 (parallel [(set (match_dup 0)
7394 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7395 (set (match_dup 1)
7396 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7397 (use (match_dup 1))
7398 (clobber (reg:CC FLAGS_REG))])]
7399 ""
7400 [(set_attr "type" "multi")
7401 (set_attr "mode" "<MODE>")])
7402
9e51149d 7403(define_insn "*udivmod<mode>4_noext"
458c00ff
UB
7404 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7405 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7406 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7407 (set (match_operand:SWIM248 1 "register_operand" "=d")
7408 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7409 (use (match_operand:SWIM248 4 "register_operand" "1"))
8bc527af 7410 (clobber (reg:CC FLAGS_REG))]
458c00ff 7411 ""
9e51149d 7412 "div{<imodesuffix>}\t%3"
e075ae69 7413 [(set_attr "type" "idiv")
9e51149d 7414 (set_attr "mode" "<MODE>")])
e075ae69 7415
b3df2256
UB
7416(define_expand "udivmodqi4"
7417 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7418 (udiv:QI
7419 (match_operand:QI 1 "register_operand" "")
7420 (match_operand:QI 2 "nonimmediate_operand" "")))
7421 (set (match_operand:QI 3 "register_operand" "")
7422 (umod:QI (match_dup 1) (match_dup 2)))
7423 (clobber (reg:CC FLAGS_REG))])]
7424 "TARGET_QIMODE_MATH"
7425{
7426 rtx div, mod, insn;
7427 rtx tmp0, tmp1;
7428
7429 tmp0 = gen_reg_rtx (HImode);
7430 tmp1 = gen_reg_rtx (HImode);
7431
7432 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7433 in AX. */
7434 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7435 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7436
7437 /* Extract remainder from AH. */
7438 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7439 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7440 insn = emit_move_insn (operands[3], tmp1);
7441
7442 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7443 set_unique_reg_note (insn, REG_EQUAL, mod);
7444
7445 /* Extract quotient from AL. */
7446 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7447
7448 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7449 set_unique_reg_note (insn, REG_EQUAL, div);
7450
7451 DONE;
7452})
7453
7454(define_insn "udivmodhiqi3"
7455 [(set (match_operand:HI 0 "register_operand" "=a")
7456 (ior:HI
7457 (ashift:HI
7458 (zero_extend:HI
7459 (truncate:QI
7460 (mod:HI (match_operand:HI 1 "register_operand" "0")
7461 (zero_extend:HI
7462 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7463 (const_int 8))
7464 (zero_extend:HI
7465 (truncate:QI
7466 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7467 (clobber (reg:CC FLAGS_REG))]
7468 "TARGET_QIMODE_MATH"
7469 "div{b}\t%2"
7470 [(set_attr "type" "idiv")
7471 (set_attr "mode" "QI")])
7472
1e5f1716 7473;; We cannot use div/idiv for double division, because it causes
e075ae69
RH
7474;; "division by zero" on the overflow and that's not what we expect
7475;; from truncate. Because true (non truncating) double division is
7476;; never generated, we can't create this insn anyway.
7477;
7478;(define_insn ""
7479; [(set (match_operand:SI 0 "register_operand" "=a")
7480; (truncate:SI
7481; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7482; (zero_extend:DI
7483; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7484; (set (match_operand:SI 3 "register_operand" "=d")
7485; (truncate:SI
7486; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8bc527af 7487; (clobber (reg:CC FLAGS_REG))]
e075ae69 7488; ""
0f40f9f7 7489; "div{l}\t{%2, %0|%0, %2}"
56bab446 7490; [(set_attr "type" "idiv")])
886c62d1 7491\f
e075ae69
RH
7492;;- Logical AND instructions
7493
7494;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7495;; Note that this excludes ah.
7496
9076b9c1 7497(define_expand "testsi_ccno_1"
8bc527af 7498 [(set (reg:CCNO FLAGS_REG)
16189740 7499 (compare:CCNO
9076b9c1
JH
7500 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7501 (match_operand:SI 1 "nonmemory_operand" ""))
a427621f 7502 (const_int 0)))])
16189740 7503
9076b9c1 7504(define_expand "testqi_ccz_1"
8bc527af 7505 [(set (reg:CCZ FLAGS_REG)
9076b9c1
JH
7506 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7507 (match_operand:QI 1 "nonmemory_operand" ""))
a427621f 7508 (const_int 0)))])
16189740 7509
26ec9308
L
7510(define_expand "testdi_ccno_1"
7511 [(set (reg:CCNO FLAGS_REG)
7512 (compare:CCNO
7513 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7514 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7515 (const_int 0)))]
7516 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7517
cf2b99ce
UB
7518(define_insn "*testdi_1"
7519 [(set (reg FLAGS_REG)
7520 (compare
7521 (and:DI
7522 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7523 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7524 (const_int 0)))]
7525 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7526 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7527 "@
7528 test{l}\t{%k1, %k0|%k0, %k1}
7529 test{l}\t{%k1, %k0|%k0, %k1}
7530 test{q}\t{%1, %0|%0, %1}
7531 test{q}\t{%1, %0|%0, %1}
7532 test{q}\t{%1, %0|%0, %1}"
7533 [(set_attr "type" "test")
7534 (set_attr "modrm" "0,1,0,1,1")
7535 (set_attr "mode" "SI,SI,DI,DI,DI")])
7536
88d60956 7537(define_insn "*testqi_1_maybe_si"
93330ea1 7538 [(set (reg FLAGS_REG)
88d60956
RH
7539 (compare
7540 (and:QI
7541 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7542 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7543 (const_int 0)))]
7656aee4 7544 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
88d60956 7545 && ix86_match_ccmode (insn,
7656aee4 7546 CONST_INT_P (operands[1])
88d60956 7547 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
adc88131
JJ
7548{
7549 if (which_alternative == 3)
7550 {
7656aee4 7551 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
adc88131 7552 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
0f40f9f7 7553 return "test{l}\t{%1, %k0|%k0, %1}";
adc88131 7554 }
0f40f9f7
ZW
7555 return "test{b}\t{%1, %0|%0, %1}";
7556}
6ef67412
JH
7557 [(set_attr "type" "test")
7558 (set_attr "modrm" "0,1,1,1")
7559 (set_attr "mode" "QI,QI,QI,SI")
7560 (set_attr "pent_pair" "uv,np,uv,np")])
e075ae69 7561
cf2b99ce 7562(define_insn "*test<mode>_1"
88d60956 7563 [(set (reg FLAGS_REG)
cf2b99ce
UB
7564 (compare
7565 (and:SWI124
7566 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7567 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7568 (const_int 0)))]
7569 "ix86_match_ccmode (insn, CCNOmode)
7570 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7571 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
88d60956
RH
7572 [(set_attr "type" "test")
7573 (set_attr "modrm" "0,1,1")
cf2b99ce 7574 (set_attr "mode" "<MODE>")
88d60956
RH
7575 (set_attr "pent_pair" "uv,np,uv")])
7576
9076b9c1 7577(define_expand "testqi_ext_ccno_0"
8bc527af 7578 [(set (reg:CCNO FLAGS_REG)
9076b9c1 7579 (compare:CCNO
16189740
RH
7580 (and:SI
7581 (zero_extract:SI
9076b9c1 7582 (match_operand 0 "ext_register_operand" "")
16189740
RH
7583 (const_int 8)
7584 (const_int 8))
9076b9c1 7585 (match_operand 1 "const_int_operand" ""))
a427621f 7586 (const_int 0)))])
e075ae69 7587
9076b9c1 7588(define_insn "*testqi_ext_0"
42fabf21 7589 [(set (reg FLAGS_REG)
9076b9c1 7590 (compare
e075ae69
RH
7591 (and:SI
7592 (zero_extract:SI
d2836273 7593 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
7594 (const_int 8)
7595 (const_int 8))
7596 (match_operand 1 "const_int_operand" "n"))
7597 (const_int 0)))]
2f41793e 7598 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7599 "test{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
7600 [(set_attr "type" "test")
7601 (set_attr "mode" "QI")
7602 (set_attr "length_immediate" "1")
725fd454 7603 (set_attr "modrm" "1")
e075ae69
RH
7604 (set_attr "pent_pair" "np")])
7605
cf2b99ce 7606(define_insn "*testqi_ext_1_rex64"
42fabf21 7607 [(set (reg FLAGS_REG)
16189740 7608 (compare
e075ae69
RH
7609 (and:SI
7610 (zero_extract:SI
d2836273 7611 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
7612 (const_int 8)
7613 (const_int 8))
7614 (zero_extend:SI
cf2b99ce 7615 (match_operand:QI 1 "register_operand" "Q")))
e075ae69 7616 (const_int 0)))]
cf2b99ce 7617 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7618 "test{b}\t{%1, %h0|%h0, %1}"
d2836273
JH
7619 [(set_attr "type" "test")
7620 (set_attr "mode" "QI")])
7621
cf2b99ce 7622(define_insn "*testqi_ext_1"
42fabf21 7623 [(set (reg FLAGS_REG)
d2836273
JH
7624 (compare
7625 (and:SI
7626 (zero_extract:SI
7627 (match_operand 0 "ext_register_operand" "Q")
7628 (const_int 8)
7629 (const_int 8))
7630 (zero_extend:SI
cf2b99ce 7631 (match_operand:QI 1 "general_operand" "Qm")))
d2836273 7632 (const_int 0)))]
cf2b99ce 7633 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7634 "test{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
7635 [(set_attr "type" "test")
7636 (set_attr "mode" "QI")])
e075ae69
RH
7637
7638(define_insn "*testqi_ext_2"
42fabf21 7639 [(set (reg FLAGS_REG)
16189740 7640 (compare
e075ae69
RH
7641 (and:SI
7642 (zero_extract:SI
d2836273 7643 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
7644 (const_int 8)
7645 (const_int 8))
7646 (zero_extract:SI
d2836273 7647 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
7648 (const_int 8)
7649 (const_int 8)))
7650 (const_int 0)))]
16189740 7651 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7652 "test{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
7653 [(set_attr "type" "test")
7654 (set_attr "mode" "QI")])
e075ae69 7655
9b70259d 7656(define_insn "*testqi_ext_3_rex64"
42fabf21 7657 [(set (reg FLAGS_REG)
9b70259d
JH
7658 (compare (zero_extract:DI
7659 (match_operand 0 "nonimmediate_operand" "rm")
7660 (match_operand:DI 1 "const_int_operand" "")
7661 (match_operand:DI 2 "const_int_operand" ""))
7662 (const_int 0)))]
1b0c37d7
ZW
7663 "TARGET_64BIT
7664 && ix86_match_ccmode (insn, CCNOmode)
d90ee6be
JJ
7665 && INTVAL (operands[1]) > 0
7666 && INTVAL (operands[2]) >= 0
44cf5b6a
JH
7667 /* Ensure that resulting mask is zero or sign extended operand. */
7668 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7669 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7670 && INTVAL (operands[1]) > 32))
9b70259d
JH
7671 && (GET_MODE (operands[0]) == SImode
7672 || GET_MODE (operands[0]) == DImode
16189740
RH
7673 || GET_MODE (operands[0]) == HImode
7674 || GET_MODE (operands[0]) == QImode)"
e075ae69 7675 "#")
4fce8e83 7676
cf2b99ce
UB
7677;; Combine likes to form bit extractions for some tests. Humor it.
7678(define_insn "*testqi_ext_3"
7679 [(set (reg FLAGS_REG)
7680 (compare (zero_extract:SI
7681 (match_operand 0 "nonimmediate_operand" "rm")
7682 (match_operand:SI 1 "const_int_operand" "")
7683 (match_operand:SI 2 "const_int_operand" ""))
7684 (const_int 0)))]
7685 "ix86_match_ccmode (insn, CCNOmode)
7686 && INTVAL (operands[1]) > 0
7687 && INTVAL (operands[2]) >= 0
7688 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7689 && (GET_MODE (operands[0]) == SImode
7690 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7691 || GET_MODE (operands[0]) == HImode
7692 || GET_MODE (operands[0]) == QImode)"
7693 "#")
7694
e075ae69 7695(define_split
25da5dc7
RH
7696 [(set (match_operand 0 "flags_reg_operand" "")
7697 (match_operator 1 "compare_operator"
7698 [(zero_extract
7699 (match_operand 2 "nonimmediate_operand" "")
7700 (match_operand 3 "const_int_operand" "")
7701 (match_operand 4 "const_int_operand" ""))
7702 (const_int 0)]))]
16189740 7703 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7 7704 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
e075ae69 7705{
25da5dc7
RH
7706 rtx val = operands[2];
7707 HOST_WIDE_INT len = INTVAL (operands[3]);
7708 HOST_WIDE_INT pos = INTVAL (operands[4]);
e075ae69 7709 HOST_WIDE_INT mask;
592188a5 7710 enum machine_mode mode, submode;
886c62d1 7711
25da5dc7 7712 mode = GET_MODE (val);
7656aee4 7713 if (MEM_P (val))
5bc7cd8e 7714 {
e075ae69
RH
7715 /* ??? Combine likes to put non-volatile mem extractions in QImode
7716 no matter the size of the test. So find a mode that works. */
25da5dc7 7717 if (! MEM_VOLATILE_P (val))
e075ae69
RH
7718 {
7719 mode = smallest_mode_for_size (pos + len, MODE_INT);
25da5dc7 7720 val = adjust_address (val, mode, 0);
e075ae69 7721 }
5bc7cd8e 7722 }
25da5dc7
RH
7723 else if (GET_CODE (val) == SUBREG
7724 && (submode = GET_MODE (SUBREG_REG (val)),
592188a5 7725 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
821bdb23
JJ
7726 && pos + len <= GET_MODE_BITSIZE (submode)
7727 && GET_MODE_CLASS (submode) == MODE_INT)
592188a5
RH
7728 {
7729 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7730 mode = submode;
25da5dc7 7731 val = SUBREG_REG (val);
592188a5 7732 }
e075ae69 7733 else if (mode == HImode && pos + len <= 8)
5bc7cd8e 7734 {
e075ae69
RH
7735 /* Small HImode tests can be converted to QImode. */
7736 mode = QImode;
25da5dc7 7737 val = gen_lowpart (QImode, val);
5bc7cd8e
SC
7738 }
7739
d90ee6be
JJ
7740 if (len == HOST_BITS_PER_WIDE_INT)
7741 mask = -1;
7742 else
7743 mask = ((HOST_WIDE_INT)1 << len) - 1;
7744 mask <<= pos;
886c62d1 7745
25da5dc7 7746 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
0f40f9f7 7747})
886c62d1 7748
6c81a490
JH
7749;; Convert HImode/SImode test instructions with immediate to QImode ones.
7750;; i386 does not allow to encode test with 8bit sign extended immediate, so
7751;; this is relatively important trick.
d1f87653 7752;; Do the conversion only post-reload to avoid limiting of the register class
6c81a490
JH
7753;; to QI regs.
7754(define_split
25da5dc7
RH
7755 [(set (match_operand 0 "flags_reg_operand" "")
7756 (match_operator 1 "compare_operator"
7757 [(and (match_operand 2 "register_operand" "")
7758 (match_operand 3 "const_int_operand" ""))
7759 (const_int 0)]))]
2f41793e 7760 "reload_completed
25da5dc7
RH
7761 && QI_REG_P (operands[2])
7762 && GET_MODE (operands[2]) != QImode
6c81a490 7763 && ((ix86_match_ccmode (insn, CCZmode)
25da5dc7 7764 && !(INTVAL (operands[3]) & ~(255 << 8)))
6c81a490 7765 || (ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
7766 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7767 [(set (match_dup 0)
7768 (match_op_dup 1
7769 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7770 (match_dup 3))
7771 (const_int 0)]))]
7772 "operands[2] = gen_lowpart (SImode, operands[2]);
7773 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
6c81a490
JH
7774
7775(define_split
25da5dc7
RH
7776 [(set (match_operand 0 "flags_reg_operand" "")
7777 (match_operator 1 "compare_operator"
7778 [(and (match_operand 2 "nonimmediate_operand" "")
7779 (match_operand 3 "const_int_operand" ""))
7780 (const_int 0)]))]
2f41793e 7781 "reload_completed
25da5dc7
RH
7782 && GET_MODE (operands[2]) != QImode
7783 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
6c81a490 7784 && ((ix86_match_ccmode (insn, CCZmode)
25da5dc7 7785 && !(INTVAL (operands[3]) & ~255))
6c81a490 7786 || (ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
7787 && !(INTVAL (operands[3]) & ~127)))"
7788 [(set (match_dup 0)
7789 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7790 (const_int 0)]))]
7791 "operands[2] = gen_lowpart (QImode, operands[2]);
7792 operands[3] = gen_lowpart (QImode, operands[3]);")
6c81a490 7793
e075ae69
RH
7794;; %%% This used to optimize known byte-wide and operations to memory,
7795;; and sometimes to QImode registers. If this is considered useful,
7796;; it should be done with splitters.
7797
cf2b99ce
UB
7798(define_expand "and<mode>3"
7799 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7800 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7801 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7802 ""
7803 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
9b70259d 7804
cf2b99ce 7805(define_insn "*anddi_1"
9b70259d 7806 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
cf2b99ce
UB
7807 (and:DI
7808 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7809 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8bc527af 7810 (clobber (reg:CC FLAGS_REG))]
9b70259d 7811 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9b70259d
JH
7812{
7813 switch (get_attr_type (insn))
7814 {
7815 case TYPE_IMOVX:
7816 {
7817 enum machine_mode mode;
7818
7656aee4 7819 gcc_assert (CONST_INT_P (operands[2]));
9b70259d
JH
7820 if (INTVAL (operands[2]) == 0xff)
7821 mode = QImode;
9b70259d 7822 else
7637e42c
NS
7823 {
7824 gcc_assert (INTVAL (operands[2]) == 0xffff);
7825 mode = HImode;
7826 }
6300f037 7827
9b70259d
JH
7828 operands[1] = gen_lowpart (mode, operands[1]);
7829 if (mode == QImode)
725fd454 7830 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
9b70259d 7831 else
725fd454 7832 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
9b70259d
JH
7833 }
7834
7835 default:
7637e42c 7836 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d 7837 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 7838 return "and{l}\t{%k2, %k0|%k0, %k2}";
9b70259d 7839 else
0f40f9f7 7840 return "and{q}\t{%2, %0|%0, %2}";
9b70259d 7841 }
0f40f9f7 7842}
9b70259d
JH
7843 [(set_attr "type" "alu,alu,alu,imovx")
7844 (set_attr "length_immediate" "*,*,*,0")
725fd454
JJ
7845 (set (attr "prefix_rex")
7846 (if_then_else
7847 (and (eq_attr "type" "imovx")
7848 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7849 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7850 (const_string "1")
7851 (const_string "*")))
7852 (set_attr "mode" "SI,DI,DI,SI")])
9b70259d 7853
e075ae69
RH
7854(define_insn "*andsi_1"
7855 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7856 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7857 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8bc527af 7858 (clobber (reg:CC FLAGS_REG))]
e075ae69 7859 "ix86_binary_operator_ok (AND, SImode, operands)"
886c62d1 7860{
e075ae69 7861 switch (get_attr_type (insn))
886c62d1 7862 {
e075ae69
RH
7863 case TYPE_IMOVX:
7864 {
7865 enum machine_mode mode;
5bc7cd8e 7866
7656aee4 7867 gcc_assert (CONST_INT_P (operands[2]));
e075ae69
RH
7868 if (INTVAL (operands[2]) == 0xff)
7869 mode = QImode;
e075ae69 7870 else
7637e42c
NS
7871 {
7872 gcc_assert (INTVAL (operands[2]) == 0xffff);
7873 mode = HImode;
7874 }
6300f037 7875
e075ae69
RH
7876 operands[1] = gen_lowpart (mode, operands[1]);
7877 if (mode == QImode)
725fd454 7878 return "movz{bl|x}\t{%1, %0|%0, %1}";
e075ae69 7879 else
725fd454 7880 return "movz{wl|x}\t{%1, %0|%0, %1}";
e075ae69 7881 }
5bc7cd8e 7882
e075ae69 7883 default:
7637e42c 7884 gcc_assert (rtx_equal_p (operands[0], operands[1]));
0f40f9f7 7885 return "and{l}\t{%2, %0|%0, %2}";
886c62d1 7886 }
0f40f9f7 7887}
6ef67412 7888 [(set_attr "type" "alu,alu,imovx")
725fd454
JJ
7889 (set (attr "prefix_rex")
7890 (if_then_else
7891 (and (eq_attr "type" "imovx")
7892 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7893 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7894 (const_string "1")
7895 (const_string "*")))
6ef67412
JH
7896 (set_attr "length_immediate" "*,*,0")
7897 (set_attr "mode" "SI")])
7898
9b70259d
JH
7899;; See comment for addsi_1_zext why we do use nonimmediate_operand
7900(define_insn "*andsi_1_zext"
7901 [(set (match_operand:DI 0 "register_operand" "=r")
7902 (zero_extend:DI
7903 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
73f48658 7904 (match_operand:SI 2 "general_operand" "g"))))
8bc527af 7905 (clobber (reg:CC FLAGS_REG))]
9b70259d 7906 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 7907 "and{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
7908 [(set_attr "type" "alu")
7909 (set_attr "mode" "SI")])
7910
e075ae69
RH
7911(define_insn "*andhi_1"
7912 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7913 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
0edb82cb 7914 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8bc527af 7915 (clobber (reg:CC FLAGS_REG))]
e075ae69 7916 "ix86_binary_operator_ok (AND, HImode, operands)"
886c62d1 7917{
e075ae69 7918 switch (get_attr_type (insn))
886c62d1 7919 {
e075ae69 7920 case TYPE_IMOVX:
7656aee4 7921 gcc_assert (CONST_INT_P (operands[2]));
7637e42c
NS
7922 gcc_assert (INTVAL (operands[2]) == 0xff);
7923 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
886c62d1 7924
e075ae69 7925 default:
7637e42c 7926 gcc_assert (rtx_equal_p (operands[0], operands[1]));
886c62d1 7927
0f40f9f7 7928 return "and{w}\t{%2, %0|%0, %2}";
5bc7cd8e 7929 }
0f40f9f7 7930}
6ef67412
JH
7931 [(set_attr "type" "alu,alu,imovx")
7932 (set_attr "length_immediate" "*,*,0")
725fd454
JJ
7933 (set (attr "prefix_rex")
7934 (if_then_else
7935 (and (eq_attr "type" "imovx")
7936 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7937 (const_string "1")
7938 (const_string "*")))
6ef67412 7939 (set_attr "mode" "HI,HI,SI")])
5bc7cd8e 7940
e075ae69
RH
7941;; %%% Potential partial reg stall on alternative 2. What to do?
7942(define_insn "*andqi_1"
7c6b971d 7943 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 7944 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
0edb82cb 7945 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8bc527af 7946 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
7947 "ix86_binary_operator_ok (AND, QImode, operands)"
7948 "@
0f40f9f7
ZW
7949 and{b}\t{%2, %0|%0, %2}
7950 and{b}\t{%2, %0|%0, %2}
7951 and{l}\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
7952 [(set_attr "type" "alu")
7953 (set_attr "mode" "QI,QI,SI")])
e075ae69 7954
a1b8572c
JH
7955(define_insn "*andqi_1_slp"
7956 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7957 (and:QI (match_dup 0)
0edb82cb 7958 (match_operand:QI 1 "general_operand" "qn,qmn")))
8bc527af 7959 (clobber (reg:CC FLAGS_REG))]
cf2b99ce 7960 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 7961 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 7962 "and{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
7963 [(set_attr "type" "alu1")
7964 (set_attr "mode" "QI")])
7965
cf2b99ce
UB
7966(define_split
7967 [(set (match_operand 0 "register_operand" "")
7968 (and (match_dup 0)
7969 (const_int -65536)))
7970 (clobber (reg:CC FLAGS_REG))]
7971 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7972 || optimize_function_for_size_p (cfun)"
7973 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7974 "operands[1] = gen_lowpart (HImode, operands[0]);")
7975
7976(define_split
7977 [(set (match_operand 0 "ext_register_operand" "")
7978 (and (match_dup 0)
7979 (const_int -256)))
7980 (clobber (reg:CC FLAGS_REG))]
7981 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7982 && reload_completed"
7983 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7984 "operands[1] = gen_lowpart (QImode, operands[0]);")
7985
7986(define_split
7987 [(set (match_operand 0 "ext_register_operand" "")
7988 (and (match_dup 0)
7989 (const_int -65281)))
7990 (clobber (reg:CC FLAGS_REG))]
7991 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7992 && reload_completed"
7993 [(parallel [(set (zero_extract:SI (match_dup 0)
7994 (const_int 8)
7995 (const_int 8))
7996 (xor:SI
7997 (zero_extract:SI (match_dup 0)
7998 (const_int 8)
7999 (const_int 8))
8000 (zero_extract:SI (match_dup 0)
8001 (const_int 8)
8002 (const_int 8))))
8003 (clobber (reg:CC FLAGS_REG))])]
8004 "operands[0] = gen_lowpart (SImode, operands[0]);")
8005
8006(define_insn "*anddi_2"
8007 [(set (reg FLAGS_REG)
8008 (compare
8009 (and:DI
8010 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8011 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8012 (const_int 0)))
8013 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8014 (and:DI (match_dup 1) (match_dup 2)))]
8015 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8016 && ix86_binary_operator_ok (AND, DImode, operands)"
8017 "@
8018 and{l}\t{%k2, %k0|%k0, %k2}
8019 and{q}\t{%2, %0|%0, %2}
8020 and{q}\t{%2, %0|%0, %2}"
8021 [(set_attr "type" "alu")
8022 (set_attr "mode" "SI,DI,DI")])
8023
88d60956 8024(define_insn "*andqi_2_maybe_si"
42fabf21 8025 [(set (reg FLAGS_REG)
16189740 8026 (compare (and:QI
cf2b99ce
UB
8027 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8028 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
16189740 8029 (const_int 0)))
e075ae69
RH
8030 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8031 (and:QI (match_dup 1) (match_dup 2)))]
88d60956
RH
8032 "ix86_binary_operator_ok (AND, QImode, operands)
8033 && ix86_match_ccmode (insn,
7656aee4 8034 CONST_INT_P (operands[2])
88d60956 8035 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
adc88131
JJ
8036{
8037 if (which_alternative == 2)
8038 {
7656aee4 8039 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
adc88131 8040 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
0f40f9f7 8041 return "and{l}\t{%2, %k0|%k0, %2}";
adc88131 8042 }
0f40f9f7
ZW
8043 return "and{b}\t{%2, %0|%0, %2}";
8044}
6ef67412
JH
8045 [(set_attr "type" "alu")
8046 (set_attr "mode" "QI,QI,SI")])
e075ae69 8047
cf2b99ce 8048(define_insn "*and<mode>_2"
88d60956 8049 [(set (reg FLAGS_REG)
cf2b99ce
UB
8050 (compare (and:SWI124
8051 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8052 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
88d60956 8053 (const_int 0)))
cf2b99ce
UB
8054 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8055 (and:SWI124 (match_dup 1) (match_dup 2)))]
88d60956 8056 "ix86_match_ccmode (insn, CCNOmode)
cf2b99ce
UB
8057 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8058 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
88d60956 8059 [(set_attr "type" "alu")
cf2b99ce 8060 (set_attr "mode" "<MODE>")])
88d60956 8061
cf2b99ce
UB
8062;; See comment for addsi_1_zext why we do use nonimmediate_operand
8063(define_insn "*andsi_2_zext"
42fabf21 8064 [(set (reg FLAGS_REG)
cf2b99ce
UB
8065 (compare (and:SI
8066 (match_operand:SI 1 "nonimmediate_operand" "%0")
8067 (match_operand:SI 2 "general_operand" "g"))
8068 (const_int 0)))
8069 (set (match_operand:DI 0 "register_operand" "=r")
8070 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8071 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8072 && ix86_binary_operator_ok (AND, SImode, operands)"
8073 "and{l}\t{%2, %k0|%k0, %2}"
8074 [(set_attr "type" "alu")
8075 (set_attr "mode" "SI")])
8076
8077(define_insn "*andqi_2_slp"
8078 [(set (reg FLAGS_REG)
8079 (compare (and:QI
8080 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
0edb82cb 8081 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
a1b8572c
JH
8082 (const_int 0)))
8083 (set (strict_low_part (match_dup 0))
8084 (and:QI (match_dup 0) (match_dup 1)))]
cf2b99ce 8085 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1b245ade 8086 && ix86_match_ccmode (insn, CCNOmode)
7656aee4 8087 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 8088 "and{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8089 [(set_attr "type" "alu1")
8090 (set_attr "mode" "QI")])
8091
e075ae69
RH
8092;; ??? A bug in recog prevents it from recognizing a const_int as an
8093;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8094;; for a QImode operand, which of course failed.
e075ae69 8095(define_insn "andqi_ext_0"
d2836273 8096 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8097 (const_int 8)
8098 (const_int 8))
6300f037 8099 (and:SI
e075ae69
RH
8100 (zero_extract:SI
8101 (match_operand 1 "ext_register_operand" "0")
8102 (const_int 8)
8103 (const_int 8))
8104 (match_operand 2 "const_int_operand" "n")))
8bc527af 8105 (clobber (reg:CC FLAGS_REG))]
2f41793e 8106 ""
0f40f9f7 8107 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8108 [(set_attr "type" "alu")
8109 (set_attr "length_immediate" "1")
725fd454 8110 (set_attr "modrm" "1")
6ef67412 8111 (set_attr "mode" "QI")])
e075ae69
RH
8112
8113;; Generated by peephole translating test to and. This shows up
8114;; often in fp comparisons.
e075ae69 8115(define_insn "*andqi_ext_0_cc"
42fabf21 8116 [(set (reg FLAGS_REG)
16189740 8117 (compare
e075ae69
RH
8118 (and:SI
8119 (zero_extract:SI
084e679a 8120 (match_operand 1 "ext_register_operand" "0")
3522082b 8121 (const_int 8)
e075ae69
RH
8122 (const_int 8))
8123 (match_operand 2 "const_int_operand" "n"))
8124 (const_int 0)))
d2836273 8125 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8126 (const_int 8)
8127 (const_int 8))
6300f037 8128 (and:SI
e075ae69
RH
8129 (zero_extract:SI
8130 (match_dup 1)
8131 (const_int 8)
8132 (const_int 8))
8133 (match_dup 2)))]
2f41793e 8134 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8135 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8136 [(set_attr "type" "alu")
8137 (set_attr "length_immediate" "1")
725fd454 8138 (set_attr "modrm" "1")
6ef67412 8139 (set_attr "mode" "QI")])
e075ae69 8140
cf2b99ce 8141(define_insn "*andqi_ext_1_rex64"
d2836273 8142 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8143 (const_int 8)
8144 (const_int 8))
6300f037 8145 (and:SI
e075ae69
RH
8146 (zero_extract:SI
8147 (match_operand 1 "ext_register_operand" "0")
8148 (const_int 8)
8149 (const_int 8))
8150 (zero_extend:SI
cf2b99ce 8151 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 8152 (clobber (reg:CC FLAGS_REG))]
cf2b99ce 8153 "TARGET_64BIT"
0f40f9f7 8154 "and{b}\t{%2, %h0|%h0, %2}"
d2836273
JH
8155 [(set_attr "type" "alu")
8156 (set_attr "length_immediate" "0")
8157 (set_attr "mode" "QI")])
8158
cf2b99ce 8159(define_insn "*andqi_ext_1"
d2836273
JH
8160 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8161 (const_int 8)
8162 (const_int 8))
6300f037 8163 (and:SI
d2836273
JH
8164 (zero_extract:SI
8165 (match_operand 1 "ext_register_operand" "0")
8166 (const_int 8)
8167 (const_int 8))
8168 (zero_extend:SI
cf2b99ce 8169 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 8170 (clobber (reg:CC FLAGS_REG))]
cf2b99ce 8171 "!TARGET_64BIT"
0f40f9f7 8172 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8173 [(set_attr "type" "alu")
8174 (set_attr "length_immediate" "0")
8175 (set_attr "mode" "QI")])
e075ae69
RH
8176
8177(define_insn "*andqi_ext_2"
d2836273 8178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8179 (const_int 8)
8180 (const_int 8))
8181 (and:SI
8182 (zero_extract:SI
8183 (match_operand 1 "ext_register_operand" "%0")
8184 (const_int 8)
8185 (const_int 8))
8186 (zero_extract:SI
d2836273 8187 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
8188 (const_int 8)
8189 (const_int 8))))
8bc527af 8190 (clobber (reg:CC FLAGS_REG))]
e075ae69 8191 ""
0f40f9f7 8192 "and{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
8193 [(set_attr "type" "alu")
8194 (set_attr "length_immediate" "0")
8195 (set_attr "mode" "QI")])
2f41793e
JH
8196
8197;; Convert wide AND instructions with immediate operand to shorter QImode
8198;; equivalents when possible.
d1f87653 8199;; Don't do the splitting with memory operands, since it introduces risk
2f41793e
JH
8200;; of memory mismatch stalls. We may want to do the splitting for optimizing
8201;; for size, but that can (should?) be handled by generic code instead.
8202(define_split
8203 [(set (match_operand 0 "register_operand" "")
8204 (and (match_operand 1 "register_operand" "")
8205 (match_operand 2 "const_int_operand" "")))
8bc527af 8206 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8207 "reload_completed
8208 && QI_REG_P (operands[0])
3debdc1e 8209 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2f41793e
JH
8210 && !(~INTVAL (operands[2]) & ~(255 << 8))
8211 && GET_MODE (operands[0]) != QImode"
8212 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8213 (and:SI (zero_extract:SI (match_dup 1)
8214 (const_int 8) (const_int 8))
8215 (match_dup 2)))
8bc527af 8216 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8217 "operands[0] = gen_lowpart (SImode, operands[0]);
8218 operands[1] = gen_lowpart (SImode, operands[1]);
8219 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8220
8221;; Since AND can be encoded with sign extended immediate, this is only
8222;; profitable when 7th bit is not set.
8223(define_split
8224 [(set (match_operand 0 "register_operand" "")
8225 (and (match_operand 1 "general_operand" "")
8226 (match_operand 2 "const_int_operand" "")))
8bc527af 8227 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8228 "reload_completed
8229 && ANY_QI_REG_P (operands[0])
3debdc1e 8230 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2f41793e
JH
8231 && !(~INTVAL (operands[2]) & ~255)
8232 && !(INTVAL (operands[2]) & 128)
8233 && GET_MODE (operands[0]) != QImode"
8234 [(parallel [(set (strict_low_part (match_dup 0))
8235 (and:QI (match_dup 1)
8236 (match_dup 2)))
8bc527af 8237 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8238 "operands[0] = gen_lowpart (QImode, operands[0]);
8239 operands[1] = gen_lowpart (QImode, operands[1]);
8240 operands[2] = gen_lowpart (QImode, operands[2]);")
886c62d1 8241\f
c8427064 8242;; Logical inclusive and exclusive OR instructions
57dbca5e 8243
e075ae69
RH
8244;; %%% This used to optimize known byte-wide and operations to memory.
8245;; If this is considered useful, it should be done with splitters.
8246
c8427064 8247(define_expand "<code><mode>3"
cf2b99ce 8248 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
c8427064
UB
8249 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8250 (match_operand:SWIM 2 "<general_operand>" "")))]
cf2b99ce 8251 ""
c8427064 8252 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9b70259d 8253
c8427064 8254(define_insn "*<code><mode>_1"
cf2b99ce 8255 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
c8427064
UB
8256 (any_or:SWI248
8257 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8258 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8bc527af 8259 (clobber (reg:CC FLAGS_REG))]
c8427064 8260 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
4a5528cc 8261 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9b70259d 8262 [(set_attr "type" "alu")
cf2b99ce 8263 (set_attr "mode" "<MODE>")])
e075ae69 8264
cf2b99ce 8265;; %%% Potential partial reg stall on alternative 2. What to do?
c8427064 8266(define_insn "*<code>qi_1"
cf2b99ce 8267 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
c8427064
UB
8268 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8269 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8bc527af 8270 (clobber (reg:CC FLAGS_REG))]
c8427064 8271 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
cf2b99ce 8272 "@
4a5528cc
UB
8273 <logic>{b}\t{%2, %0|%0, %2}
8274 <logic>{b}\t{%2, %0|%0, %2}
8275 <logic>{l}\t{%k2, %k0|%k0, %k2}"
6ef67412 8276 [(set_attr "type" "alu")
cf2b99ce 8277 (set_attr "mode" "QI,QI,SI")])
e075ae69 8278
9b70259d 8279;; See comment for addsi_1_zext why we do use nonimmediate_operand
c8427064 8280(define_insn "*<code>si_1_zext"
a6783d12 8281 [(set (match_operand:DI 0 "register_operand" "=r")
9b70259d 8282 (zero_extend:DI
c8427064
UB
8283 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8284 (match_operand:SI 2 "general_operand" "g"))))
8bc527af 8285 (clobber (reg:CC FLAGS_REG))]
c8427064 8286 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
4a5528cc 8287 "<logic>{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8288 [(set_attr "type" "alu")
8289 (set_attr "mode" "SI")])
8290
c8427064 8291(define_insn "*<code>si_1_zext_imm"
a6783d12 8292 [(set (match_operand:DI 0 "register_operand" "=r")
c8427064
UB
8293 (any_or:DI
8294 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8295 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8bc527af 8296 (clobber (reg:CC FLAGS_REG))]
c8427064 8297 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
4a5528cc 8298 "<logic>{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8299 [(set_attr "type" "alu")
8300 (set_attr "mode" "SI")])
8301
c8427064 8302(define_insn "*<code>qi_1_slp"
cf2b99ce 8303 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
c8427064
UB
8304 (any_or:QI (match_dup 0)
8305 (match_operand:QI 1 "general_operand" "qmn,qn")))
cf2b99ce
UB
8306 (clobber (reg:CC FLAGS_REG))]
8307 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8308 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4a5528cc 8309 "<logic>{b}\t{%1, %0|%0, %1}"
cf2b99ce
UB
8310 [(set_attr "type" "alu1")
8311 (set_attr "mode" "QI")])
8312
c8427064 8313(define_insn "*<code><mode>_2"
42fabf21 8314 [(set (reg FLAGS_REG)
c8427064 8315 (compare (any_or:SWI
cf2b99ce
UB
8316 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8317 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
16189740 8318 (const_int 0)))
cf2b99ce 8319 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
c8427064 8320 (any_or:SWI (match_dup 1) (match_dup 2)))]
16189740 8321 "ix86_match_ccmode (insn, CCNOmode)
c8427064 8322 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
4a5528cc 8323 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6ef67412 8324 [(set_attr "type" "alu")
cf2b99ce 8325 (set_attr "mode" "<MODE>")])
e075ae69 8326
9b70259d
JH
8327;; See comment for addsi_1_zext why we do use nonimmediate_operand
8328;; ??? Special case for immediate operand is missing - it is tricky.
c8427064 8329(define_insn "*<code>si_2_zext"
42fabf21 8330 [(set (reg FLAGS_REG)
c8427064
UB
8331 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8332 (match_operand:SI 2 "general_operand" "g"))
9b70259d
JH
8333 (const_int 0)))
8334 (set (match_operand:DI 0 "register_operand" "=r")
c8427064 8335 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9b70259d 8336 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
c8427064 8337 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
4a5528cc 8338 "<logic>{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8339 [(set_attr "type" "alu")
8340 (set_attr "mode" "SI")])
8341
c8427064 8342(define_insn "*<code>si_2_zext_imm"
42fabf21 8343 [(set (reg FLAGS_REG)
c8427064 8344 (compare (any_or:SI
cf2b99ce
UB
8345 (match_operand:SI 1 "nonimmediate_operand" "%0")
8346 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9b70259d
JH
8347 (const_int 0)))
8348 (set (match_operand:DI 0 "register_operand" "=r")
c8427064 8349 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9b70259d 8350 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
c8427064 8351 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
4a5528cc 8352 "<logic>{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8353 [(set_attr "type" "alu")
8354 (set_attr "mode" "SI")])
8355
c8427064 8356(define_insn "*<code>qi_2_slp"
42fabf21 8357 [(set (reg FLAGS_REG)
c8427064
UB
8358 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8359 (match_operand:QI 1 "general_operand" "qmn,qn"))
a1b8572c
JH
8360 (const_int 0)))
8361 (set (strict_low_part (match_dup 0))
c8427064 8362 (any_or:QI (match_dup 0) (match_dup 1)))]
cf2b99ce 8363 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1b245ade 8364 && ix86_match_ccmode (insn, CCNOmode)
7656aee4 8365 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4a5528cc 8366 "<logic>{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8367 [(set_attr "type" "alu1")
8368 (set_attr "mode" "QI")])
8369
c8427064 8370(define_insn "*<code><mode>_3"
42fabf21 8371 [(set (reg FLAGS_REG)
c8427064 8372 (compare (any_or:SWI
cf2b99ce
UB
8373 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8374 (match_operand:SWI 2 "<general_operand>" "<g>"))
d90ffc8d 8375 (const_int 0)))
cf2b99ce 8376 (clobber (match_scratch:SWI 0 "=<r>"))]
d90ffc8d 8377 "ix86_match_ccmode (insn, CCNOmode)
0fb2f9b1 8378 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4a5528cc 8379 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
d90ffc8d 8380 [(set_attr "type" "alu")
cf2b99ce 8381 (set_attr "mode" "<MODE>")])
d90ffc8d 8382
c8427064 8383(define_insn "*<code>qi_ext_0"
2f41793e
JH
8384 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8385 (const_int 8)
8386 (const_int 8))
c8427064 8387 (any_or:SI
2f41793e
JH
8388 (zero_extract:SI
8389 (match_operand 1 "ext_register_operand" "0")
8390 (const_int 8)
8391 (const_int 8))
8392 (match_operand 2 "const_int_operand" "n")))
8bc527af 8393 (clobber (reg:CC FLAGS_REG))]
cf2b99ce 8394 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
4a5528cc 8395 "<logic>{b}\t{%2, %h0|%h0, %2}"
2f41793e
JH
8396 [(set_attr "type" "alu")
8397 (set_attr "length_immediate" "1")
725fd454 8398 (set_attr "modrm" "1")
2f41793e
JH
8399 (set_attr "mode" "QI")])
8400
c8427064 8401(define_insn "*<code>qi_ext_1_rex64"
2f41793e
JH
8402 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8403 (const_int 8)
8404 (const_int 8))
c8427064 8405 (any_or:SI
2f41793e
JH
8406 (zero_extract:SI
8407 (match_operand 1 "ext_register_operand" "0")
8408 (const_int 8)
8409 (const_int 8))
8410 (zero_extend:SI
cf2b99ce 8411 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 8412 (clobber (reg:CC FLAGS_REG))]
cf2b99ce 8413 "TARGET_64BIT
3debdc1e 8414 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
4a5528cc 8415 "<logic>{b}\t{%2, %h0|%h0, %2}"
2f41793e
JH
8416 [(set_attr "type" "alu")
8417 (set_attr "length_immediate" "0")
8418 (set_attr "mode" "QI")])
8419
c8427064 8420(define_insn "*<code>qi_ext_1"
2f41793e
JH
8421 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8422 (const_int 8)
8423 (const_int 8))
c8427064 8424 (any_or:SI
2f41793e
JH
8425 (zero_extract:SI
8426 (match_operand 1 "ext_register_operand" "0")
8427 (const_int 8)
8428 (const_int 8))
8429 (zero_extend:SI
cf2b99ce 8430 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 8431 (clobber (reg:CC FLAGS_REG))]
cf2b99ce 8432 "!TARGET_64BIT
3debdc1e 8433 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
4a5528cc 8434 "<logic>{b}\t{%2, %h0|%h0, %2}"
2f41793e
JH
8435 [(set_attr "type" "alu")
8436 (set_attr "length_immediate" "0")
8437 (set_attr "mode" "QI")])
8438
c8427064 8439(define_insn "*<code>qi_ext_2"
2f41793e
JH
8440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8441 (const_int 8)
8442 (const_int 8))
c8427064 8443 (any_or:SI
2f41793e
JH
8444 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8445 (const_int 8)
8446 (const_int 8))
8447 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8448 (const_int 8)
8449 (const_int 8))))
8bc527af 8450 (clobber (reg:CC FLAGS_REG))]
cf2b99ce 8451 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
4a5528cc 8452 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
2f41793e
JH
8453 [(set_attr "type" "alu")
8454 (set_attr "length_immediate" "0")
8455 (set_attr "mode" "QI")])
8456
8457(define_split
8458 [(set (match_operand 0 "register_operand" "")
c8427064
UB
8459 (any_or (match_operand 1 "register_operand" "")
8460 (match_operand 2 "const_int_operand" "")))
8bc527af 8461 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8462 "reload_completed
8463 && QI_REG_P (operands[0])
3debdc1e 8464 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2f41793e
JH
8465 && !(INTVAL (operands[2]) & ~(255 << 8))
8466 && GET_MODE (operands[0]) != QImode"
8467 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
c8427064
UB
8468 (any_or:SI (zero_extract:SI (match_dup 1)
8469 (const_int 8) (const_int 8))
8470 (match_dup 2)))
8bc527af 8471 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8472 "operands[0] = gen_lowpart (SImode, operands[0]);
8473 operands[1] = gen_lowpart (SImode, operands[1]);
8474 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8475
8476;; Since OR can be encoded with sign extended immediate, this is only
8477;; profitable when 7th bit is set.
8478(define_split
8479 [(set (match_operand 0 "register_operand" "")
c8427064
UB
8480 (any_or (match_operand 1 "general_operand" "")
8481 (match_operand 2 "const_int_operand" "")))
8bc527af 8482 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8483 "reload_completed
8484 && ANY_QI_REG_P (operands[0])
3debdc1e 8485 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2f41793e
JH
8486 && !(INTVAL (operands[2]) & ~255)
8487 && (INTVAL (operands[2]) & 128)
8488 && GET_MODE (operands[0]) != QImode"
8489 [(parallel [(set (strict_low_part (match_dup 0))
c8427064
UB
8490 (any_or:QI (match_dup 1)
8491 (match_dup 2)))
8bc527af 8492 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8493 "operands[0] = gen_lowpart (QImode, operands[0]);
8494 operands[1] = gen_lowpart (QImode, operands[1]);
8495 operands[2] = gen_lowpart (QImode, operands[2]);")
e075ae69 8496
cf2b99ce
UB
8497(define_expand "xorqi_cc_ext_1"
8498 [(parallel [
8499 (set (reg:CCNO FLAGS_REG)
8500 (compare:CCNO
8501 (xor:SI
8502 (zero_extract:SI
8503 (match_operand 1 "ext_register_operand" "")
8504 (const_int 8)
8505 (const_int 8))
8506 (match_operand:QI 2 "general_operand" ""))
8507 (const_int 0)))
8508 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8509 (const_int 8)
8510 (const_int 8))
8511 (xor:SI
8512 (zero_extract:SI
8513 (match_dup 1)
8514 (const_int 8)
8515 (const_int 8))
a427621f 8516 (match_dup 2)))])])
d90ffc8d 8517
cf2b99ce 8518(define_insn "*xorqi_cc_ext_1_rex64"
42fabf21 8519 [(set (reg FLAGS_REG)
9076b9c1 8520 (compare
e075ae69
RH
8521 (xor:SI
8522 (zero_extract:SI
8523 (match_operand 1 "ext_register_operand" "0")
8524 (const_int 8)
8525 (const_int 8))
cf2b99ce 8526 (match_operand:QI 2 "nonmemory_operand" "Qn"))
e075ae69 8527 (const_int 0)))
cf2b99ce 8528 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8529 (const_int 8)
8530 (const_int 8))
6300f037 8531 (xor:SI
cf2b99ce
UB
8532 (zero_extract:SI
8533 (match_dup 1)
8534 (const_int 8)
8535 (const_int 8))
e075ae69 8536 (match_dup 2)))]
cf2b99ce 8537 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8538 "xor{b}\t{%2, %h0|%h0, %2}"
d2836273 8539 [(set_attr "type" "alu")
725fd454 8540 (set_attr "modrm" "1")
d2836273
JH
8541 (set_attr "mode" "QI")])
8542
cf2b99ce 8543(define_insn "*xorqi_cc_ext_1"
42fabf21 8544 [(set (reg FLAGS_REG)
d2836273
JH
8545 (compare
8546 (xor:SI
8547 (zero_extract:SI
8548 (match_operand 1 "ext_register_operand" "0")
8549 (const_int 8)
8550 (const_int 8))
cf2b99ce 8551 (match_operand:QI 2 "general_operand" "qmn"))
d2836273 8552 (const_int 0)))
cf2b99ce 8553 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
d2836273
JH
8554 (const_int 8)
8555 (const_int 8))
6300f037 8556 (xor:SI
cf2b99ce
UB
8557 (zero_extract:SI
8558 (match_dup 1)
8559 (const_int 8)
8560 (const_int 8))
d2836273 8561 (match_dup 2)))]
cf2b99ce 8562 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8563 "xor{b}\t{%2, %h0|%h0, %2}"
6ef67412 8564 [(set_attr "type" "alu")
725fd454 8565 (set_attr "modrm" "1")
6ef67412 8566 (set_attr "mode" "QI")])
e075ae69
RH
8567\f
8568;; Negation instructions
57dbca5e 8569
14c27152
UB
8570(define_expand "neg<mode>2"
8571 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8572 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
06a964de 8573 ""
14c27152 8574 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
886c62d1 8575
14c27152
UB
8576(define_insn_and_split "*neg<dwi>2_doubleword"
8577 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8578 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8bc527af 8579 (clobber (reg:CC FLAGS_REG))]
14c27152
UB
8580 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8581 "#"
8582 "reload_completed"
e075ae69 8583 [(parallel
8bc527af 8584 [(set (reg:CCZ FLAGS_REG)
14c27152
UB
8585 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8586 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
e075ae69 8587 (parallel
c2b814b9 8588 [(set (match_dup 2)
14c27152
UB
8589 (plus:DWIH (match_dup 3)
8590 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8591 (const_int 0))))
8bc527af 8592 (clobber (reg:CC FLAGS_REG))])
e075ae69 8593 (parallel
c2b814b9 8594 [(set (match_dup 2)
14c27152 8595 (neg:DWIH (match_dup 2)))
8bc527af 8596 (clobber (reg:CC FLAGS_REG))])]
b146446c 8597 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
06a964de 8598
14c27152
UB
8599(define_insn "*neg<mode>2_1"
8600 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8601 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8bc527af 8602 (clobber (reg:CC FLAGS_REG))]
14c27152
UB
8603 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8604 "neg{<imodesuffix>}\t%0"
6ef67412 8605 [(set_attr "type" "negnot")
14c27152 8606 (set_attr "mode" "<MODE>")])
e075ae69 8607
9b70259d
JH
8608;; Combine is quite creative about this pattern.
8609(define_insn "*negsi2_1_zext"
8610 [(set (match_operand:DI 0 "register_operand" "=r")
14c27152
UB
8611 (lshiftrt:DI
8612 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8613 (const_int 32)))
8614 (const_int 32)))
8bc527af 8615 (clobber (reg:CC FLAGS_REG))]
9b70259d 8616 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 8617 "neg{l}\t%k0"
9b70259d
JH
8618 [(set_attr "type" "negnot")
8619 (set_attr "mode" "SI")])
8620
16189740
RH
8621;; The problem with neg is that it does not perform (compare x 0),
8622;; it really performs (compare 0 x), which leaves us with the zero
8623;; flag being the only useful item.
e075ae69 8624
14c27152 8625(define_insn "*neg<mode>2_cmpz"
8bc527af 8626 [(set (reg:CCZ FLAGS_REG)
14c27152
UB
8627 (compare:CCZ
8628 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8629 (const_int 0)))
8630 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8631 (neg:SWI (match_dup 1)))]
8632 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8633 "neg{<imodesuffix>}\t%0"
6ef67412 8634 [(set_attr "type" "negnot")
14c27152 8635 (set_attr "mode" "<MODE>")])
886c62d1 8636
9b70259d 8637(define_insn "*negsi2_cmpz_zext"
8bc527af 8638 [(set (reg:CCZ FLAGS_REG)
14c27152
UB
8639 (compare:CCZ
8640 (lshiftrt:DI
8641 (neg:DI (ashift:DI
8642 (match_operand:DI 1 "register_operand" "0")
8643 (const_int 32)))
8644 (const_int 32))
8645 (const_int 0)))
9b70259d
JH
8646 (set (match_operand:DI 0 "register_operand" "=r")
8647 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8648 (const_int 32)))
8649 (const_int 32)))]
8650 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 8651 "neg{l}\t%k0"
9b70259d
JH
8652 [(set_attr "type" "negnot")
8653 (set_attr "mode" "SI")])
8654
06a964de 8655;; Changing of sign for FP values is doable using integer unit too.
1ce485ec 8656
6dd18eb1 8657(define_expand "<code><mode>2"
6b761851 8658 [(set (match_operand:X87MODEF 0 "register_operand" "")
6dd18eb1 8659 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
6b761851 8660 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6dd18eb1 8661 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
b3298882 8662
6b761851
UB
8663(define_insn "*absneg<mode>2_mixed"
8664 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8665 (match_operator:MODEF 3 "absneg_operator"
8666 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8667 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8bc527af 8668 (clobber (reg:CC FLAGS_REG))]
6b761851 8669 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
141e454b
JH
8670 "#")
8671
6b761851
UB
8672(define_insn "*absneg<mode>2_sse"
8673 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8674 (match_operator:MODEF 3 "absneg_operator"
8675 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8676 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8bc527af 8677 (clobber (reg:CC FLAGS_REG))]
6b761851 8678 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
b3298882
JH
8679 "#")
8680
6b761851
UB
8681(define_insn "*absneg<mode>2_i387"
8682 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8683 (match_operator:X87MODEF 3 "absneg_operator"
8684 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
7cacf53e 8685 (use (match_operand 2 "" ""))
8bc527af 8686 (clobber (reg:CC FLAGS_REG))]
6b761851 8687 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7cacf53e
RH
8688 "#")
8689
6dd18eb1 8690(define_expand "<code>tf2"
6b761851 8691 [(set (match_operand:TF 0 "register_operand" "")
6dd18eb1 8692 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
5bb77598 8693 "TARGET_SSE2"
6dd18eb1 8694 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
edc5bbcd
UB
8695
8696(define_insn "*absnegtf2_sse"
6b761851 8697 [(set (match_operand:TF 0 "register_operand" "=x,x")
edc5bbcd 8698 (match_operator:TF 3 "absneg_operator"
6b761851
UB
8699 [(match_operand:TF 1 "register_operand" "0,x")]))
8700 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
edc5bbcd 8701 (clobber (reg:CC FLAGS_REG))]
5bb77598 8702 "TARGET_SSE2"
edc5bbcd
UB
8703 "#")
8704
7cacf53e 8705;; Splitters for fp abs and neg.
b3298882 8706
141e454b 8707(define_split
7cacf53e
RH
8708 [(set (match_operand 0 "fp_register_operand" "")
8709 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8710 (use (match_operand 2 "" ""))
8bc527af 8711 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
8712 "reload_completed"
8713 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
141e454b 8714
b3298882 8715(define_split
7cacf53e
RH
8716 [(set (match_operand 0 "register_operand" "")
8717 (match_operator 3 "absneg_operator"
8718 [(match_operand 1 "register_operand" "")]))
8719 (use (match_operand 2 "nonimmediate_operand" ""))
8bc527af 8720 (clobber (reg:CC FLAGS_REG))]
b3298882 8721 "reload_completed && SSE_REG_P (operands[0])"
7cacf53e 8722 [(set (match_dup 0) (match_dup 3))]
b3298882 8723{
7cacf53e
RH
8724 enum machine_mode mode = GET_MODE (operands[0]);
8725 enum machine_mode vmode = GET_MODE (operands[2]);
8726 rtx tmp;
6300f037 8727
7cacf53e
RH
8728 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8729 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
b3298882
JH
8730 if (operands_match_p (operands[0], operands[2]))
8731 {
b3298882
JH
8732 tmp = operands[1];
8733 operands[1] = operands[2];
8734 operands[2] = tmp;
8735 }
7cacf53e
RH
8736 if (GET_CODE (operands[3]) == ABS)
8737 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8738 else
8739 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8740 operands[3] = tmp;
0f40f9f7 8741})
06a964de 8742
1ce485ec 8743(define_split
7cacf53e
RH
8744 [(set (match_operand:SF 0 "register_operand" "")
8745 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8746 (use (match_operand:V4SF 2 "" ""))
8bc527af 8747 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
8748 "reload_completed"
8749 [(parallel [(set (match_dup 0) (match_dup 1))
8750 (clobber (reg:CC FLAGS_REG))])]
6300f037 8751{
7cacf53e
RH
8752 rtx tmp;
8753 operands[0] = gen_lowpart (SImode, operands[0]);
8754 if (GET_CODE (operands[1]) == ABS)
8755 {
8756 tmp = gen_int_mode (0x7fffffff, SImode);
8757 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8758 }
8759 else
8760 {
8761 tmp = gen_int_mode (0x80000000, SImode);
8762 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8763 }
8764 operands[1] = tmp;
8765})
1ce485ec
JH
8766
8767(define_split
7cacf53e
RH
8768 [(set (match_operand:DF 0 "register_operand" "")
8769 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8770 (use (match_operand 2 "" ""))
8bc527af 8771 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
8772 "reload_completed"
8773 [(parallel [(set (match_dup 0) (match_dup 1))
8bc527af 8774 (clobber (reg:CC FLAGS_REG))])]
7cacf53e
RH
8775{
8776 rtx tmp;
8777 if (TARGET_64BIT)
8778 {
8779 tmp = gen_lowpart (DImode, operands[0]);
8780 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8781 operands[0] = tmp;
2b589241 8782
7cacf53e
RH
8783 if (GET_CODE (operands[1]) == ABS)
8784 tmp = const0_rtx;
8785 else
8786 tmp = gen_rtx_NOT (DImode, tmp);
8787 }
8788 else
8789 {
8790 operands[0] = gen_highpart (SImode, operands[0]);
8791 if (GET_CODE (operands[1]) == ABS)
8792 {
8793 tmp = gen_int_mode (0x7fffffff, SImode);
8794 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8795 }
8796 else
8797 {
8798 tmp = gen_int_mode (0x80000000, SImode);
8799 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8800 }
8801 }
8802 operands[1] = tmp;
8803})
1ce485ec
JH
8804
8805(define_split
7cacf53e
RH
8806 [(set (match_operand:XF 0 "register_operand" "")
8807 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8808 (use (match_operand 2 "" ""))
8bc527af 8809 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
8810 "reload_completed"
8811 [(parallel [(set (match_dup 0) (match_dup 1))
8812 (clobber (reg:CC FLAGS_REG))])]
8813{
8814 rtx tmp;
8815 operands[0] = gen_rtx_REG (SImode,
8816 true_regnum (operands[0])
8817 + (TARGET_64BIT ? 1 : 2));
8818 if (GET_CODE (operands[1]) == ABS)
8819 {
8820 tmp = GEN_INT (0x7fff);
8821 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8822 }
8823 else
8824 {
8825 tmp = GEN_INT (0x8000);
8826 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8827 }
8828 operands[1] = tmp;
8829})
1ce485ec 8830
6300f037 8831;; Conditionalize these after reload. If they match before reload, we
1ce485ec
JH
8832;; lose the clobber and ability to use integer instructions.
8833
6dd18eb1 8834(define_insn "*<code><mode>2_1"
6b761851 8835 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6dd18eb1 8836 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
6b761851 8837 "TARGET_80387
6dd18eb1
UB
8838 && (reload_completed
8839 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
4a5528cc 8840 "f<absneg_mnemonic>"
7cacf53e 8841 [(set_attr "type" "fsgn")
6b761851 8842 (set_attr "mode" "<MODE>")])
4fb21e90 8843
6dd18eb1 8844(define_insn "*<code>extendsfdf2"
886c62d1 8845 [(set (match_operand:DF 0 "register_operand" "=f")
6dd18eb1
UB
8846 (absneg:DF (float_extend:DF
8847 (match_operand:SF 1 "register_operand" "0"))))]
7cacf53e 8848 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4a5528cc 8849 "f<absneg_mnemonic>"
6ef67412
JH
8850 [(set_attr "type" "fsgn")
8851 (set_attr "mode" "DF")])
4fb21e90 8852
6dd18eb1 8853(define_insn "*<code>extendsfxf2"
4fb21e90 8854 [(set (match_operand:XF 0 "register_operand" "=f")
6dd18eb1
UB
8855 (absneg:XF (float_extend:XF
8856 (match_operand:SF 1 "register_operand" "0"))))]
f8a1ebc6 8857 "TARGET_80387"
4a5528cc 8858 "f<absneg_mnemonic>"
6ef67412
JH
8859 [(set_attr "type" "fsgn")
8860 (set_attr "mode" "XF")])
a199fdd6 8861
6dd18eb1 8862(define_insn "*<code>extenddfxf2"
58733f96 8863 [(set (match_operand:XF 0 "register_operand" "=f")
6dd18eb1 8864 (absneg:XF (float_extend:XF
4a5528cc 8865 (match_operand:DF 1 "register_operand" "0"))))]
2b589241 8866 "TARGET_80387"
4a5528cc 8867 "f<absneg_mnemonic>"
2b589241
JH
8868 [(set_attr "type" "fsgn")
8869 (set_attr "mode" "XF")])
edc5bbcd
UB
8870
8871;; Copysign instructions
8872
3abcb3a7 8873(define_mode_iterator CSGNMODE [SF DF TF])
edc5bbcd
UB
8874(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8875
8876(define_expand "copysign<mode>3"
8877 [(match_operand:CSGNMODE 0 "register_operand" "")
8878 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8879 (match_operand:CSGNMODE 2 "register_operand" "")]
8880 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5bb77598 8881 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
cb1b497e 8882 "ix86_expand_copysign (operands); DONE;")
edc5bbcd
UB
8883
8884(define_insn_and_split "copysign<mode>3_const"
8885 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8886 (unspec:CSGNMODE
8887 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8888 (match_operand:CSGNMODE 2 "register_operand" "0")
8889 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8890 UNSPEC_COPYSIGN))]
8891 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5bb77598 8892 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
edc5bbcd
UB
8893 "#"
8894 "&& reload_completed"
8895 [(const_int 0)]
cb1b497e 8896 "ix86_split_copysign_const (operands); DONE;")
edc5bbcd
UB
8897
8898(define_insn "copysign<mode>3_var"
8899 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8900 (unspec:CSGNMODE
8901 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8902 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8903 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8904 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8905 UNSPEC_COPYSIGN))
8906 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8907 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5bb77598 8908 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
edc5bbcd
UB
8909 "#")
8910
8911(define_split
8912 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8913 (unspec:CSGNMODE
8914 [(match_operand:CSGNMODE 2 "register_operand" "")
8915 (match_operand:CSGNMODE 3 "register_operand" "")
8916 (match_operand:<CSGNVMODE> 4 "" "")
8917 (match_operand:<CSGNVMODE> 5 "" "")]
8918 UNSPEC_COPYSIGN))
8919 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8920 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5bb77598 8921 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
edc5bbcd
UB
8922 && reload_completed"
8923 [(const_int 0)]
cb1b497e 8924 "ix86_split_copysign_var (operands); DONE;")
886c62d1 8925\f
e075ae69 8926;; One complement instructions
886c62d1 8927
14c27152
UB
8928(define_expand "one_cmpl<mode>2"
8929 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8930 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8931 ""
8932 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9b70259d 8933
14c27152
UB
8934(define_insn "*one_cmpl<mode>2_1"
8935 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8936 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8937 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8938 "not{<imodesuffix>}\t%0"
9b70259d 8939 [(set_attr "type" "negnot")
14c27152 8940 (set_attr "mode" "<MODE>")])
06a964de 8941
14c27152
UB
8942;; %%% Potential partial reg stall on alternative 1. What to do?
8943(define_insn "*one_cmplqi2_1"
8944 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8945 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8946 "ix86_unary_operator_ok (NOT, QImode, operands)"
8947 "@
8948 not{b}\t%0
8949 not{l}\t%k0"
6ef67412 8950 [(set_attr "type" "negnot")
14c27152 8951 (set_attr "mode" "QI,SI")])
bb524860 8952
9b70259d
JH
8953;; ??? Currently never generated - xor is used instead.
8954(define_insn "*one_cmplsi2_1_zext"
8955 [(set (match_operand:DI 0 "register_operand" "=r")
14c27152
UB
8956 (zero_extend:DI
8957 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9b70259d 8958 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
0f40f9f7 8959 "not{l}\t%k0"
9b70259d
JH
8960 [(set_attr "type" "negnot")
8961 (set_attr "mode" "SI")])
8962
14c27152 8963(define_insn "*one_cmpl<mode>2_2"
42fabf21 8964 [(set (reg FLAGS_REG)
14c27152 8965 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
16189740 8966 (const_int 0)))
14c27152
UB
8967 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8968 (not:SWI (match_dup 1)))]
16189740 8969 "ix86_match_ccmode (insn, CCNOmode)
14c27152 8970 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
e075ae69 8971 "#"
6ef67412 8972 [(set_attr "type" "alu1")
14c27152 8973 (set_attr "mode" "<MODE>")])
e075ae69
RH
8974
8975(define_split
25da5dc7
RH
8976 [(set (match_operand 0 "flags_reg_operand" "")
8977 (match_operator 2 "compare_operator"
14c27152 8978 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
25da5dc7 8979 (const_int 0)]))
14c27152
UB
8980 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8981 (not:SWI (match_dup 3)))]
16189740 8982 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7 8983 [(parallel [(set (match_dup 0)
14c27152 8984 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
25da5dc7
RH
8985 (const_int 0)]))
8986 (set (match_dup 1)
cb1b497e 8987 (xor:SWI (match_dup 3) (const_int -1)))])])
886c62d1 8988
9b70259d
JH
8989;; ??? Currently never generated - xor is used instead.
8990(define_insn "*one_cmplsi2_2_zext"
42fabf21 8991 [(set (reg FLAGS_REG)
9b70259d
JH
8992 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8993 (const_int 0)))
8994 (set (match_operand:DI 0 "register_operand" "=r")
8995 (zero_extend:DI (not:SI (match_dup 1))))]
8996 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8997 && ix86_unary_operator_ok (NOT, SImode, operands)"
8998 "#"
8999 [(set_attr "type" "alu1")
9000 (set_attr "mode" "SI")])
9001
9002(define_split
25da5dc7
RH
9003 [(set (match_operand 0 "flags_reg_operand" "")
9004 (match_operator 2 "compare_operator"
9005 [(not:SI (match_operand:SI 3 "register_operand" ""))
9006 (const_int 0)]))
9007 (set (match_operand:DI 1 "register_operand" "")
9008 (zero_extend:DI (not:SI (match_dup 3))))]
9b70259d 9009 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
9010 [(parallel [(set (match_dup 0)
9011 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9012 (const_int 0)]))
9013 (set (match_dup 1)
cb1b497e 9014 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
886c62d1 9015\f
d72ebc16 9016;; Shift instructions
886c62d1
JVA
9017
9018;; DImode shifts are implemented using the i386 "shift double" opcode,
9019;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9020;; is variable, then the count is in %cl and the "imm" operand is dropped
9021;; from the assembler input.
e075ae69 9022;;
886c62d1
JVA
9023;; This instruction shifts the target reg/mem as usual, but instead of
9024;; shifting in zeros, bits are shifted in from reg operand. If the insn
9025;; is a left shift double, bits are taken from the high order bits of
9026;; reg, else if the insn is a shift right double, bits are taken from the
9027;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9028;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
e075ae69 9029;;
886c62d1
JVA
9030;; Since sh[lr]d does not change the `reg' operand, that is done
9031;; separately, making all shifts emit pairs of shift double and normal
9032;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9033;; support a 63 bit shift, each shift where the count is in a reg expands
f58acb67 9034;; to a pair of shifts, a branch, a shift by 32 and a label.
e075ae69 9035;;
886c62d1
JVA
9036;; If the shift count is a constant, we need never emit more than one
9037;; shift pair, instead using moves and sign extension for counts greater
9038;; than 31.
9039
014753cc
UB
9040(define_expand "ashl<mode>3"
9041 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9042 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9043 (match_operand:QI 2 "nonmemory_operand" "")))]
9044 ""
9045 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
28356f52 9046
ef0f4a03 9047(define_insn "*ashl<mode>3_doubleword"
014753cc
UB
9048 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9049 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9050 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
28356f52 9051 (clobber (reg:CC FLAGS_REG))]
ef0f4a03 9052 ""
28356f52 9053 "#"
ef0f4a03
UB
9054 [(set_attr "type" "multi")])
9055
9056(define_split
9057 [(set (match_operand:DWI 0 "register_operand" "")
9058 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9059 (match_operand:QI 2 "nonmemory_operand" "")))
9060 (clobber (reg:CC FLAGS_REG))]
014753cc
UB
9061 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9062 [(const_int 0)]
ef0f4a03 9063 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
28356f52 9064
014753cc
UB
9065;; By default we don't ask for a scratch register, because when DWImode
9066;; values are manipulated, registers are already at a premium. But if
9067;; we have one handy, we won't turn it away.
9068
934f2a96 9069(define_peephole2
014753cc
UB
9070 [(match_scratch:DWIH 3 "r")
9071 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9072 (ashift:<DWI>
9073 (match_operand:<DWI> 1 "nonmemory_operand" "")
9074 (match_operand:QI 2 "nonmemory_operand" "")))
934f2a96
UB
9075 (clobber (reg:CC FLAGS_REG))])
9076 (match_dup 3)]
014753cc 9077 "TARGET_CMOVE"
28356f52 9078 [(const_int 0)]
014753cc 9079 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
28356f52
JB
9080
9081(define_insn "x86_64_shld"
934f2a96 9082 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
28356f52 9083 (ior:DI (ashift:DI (match_dup 0)
934f2a96
UB
9084 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9085 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
28356f52
JB
9086 (minus:QI (const_int 64) (match_dup 2)))))
9087 (clobber (reg:CC FLAGS_REG))]
9088 "TARGET_64BIT"
934f2a96 9089 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
28356f52
JB
9090 [(set_attr "type" "ishift")
9091 (set_attr "prefix_0f" "1")
9092 (set_attr "mode" "DI")
21efb4d4 9093 (set_attr "athlon_decode" "vector")
4f3f76e6 9094 (set_attr "amdfam10_decode" "vector")])
28356f52 9095
014753cc
UB
9096(define_insn "x86_shld"
9097 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9098 (ior:SI (ashift:SI (match_dup 0)
9099 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9100 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9101 (minus:QI (const_int 32) (match_dup 2)))))
9102 (clobber (reg:CC FLAGS_REG))]
9103 ""
9104 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9105 [(set_attr "type" "ishift")
9106 (set_attr "prefix_0f" "1")
9107 (set_attr "mode" "SI")
9108 (set_attr "pent_pair" "np")
9109 (set_attr "athlon_decode" "vector")
9110 (set_attr "amdfam10_decode" "vector")])
9111
9112(define_expand "x86_shift<mode>_adj_1"
28356f52
JB
9113 [(set (reg:CCZ FLAGS_REG)
9114 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
014753cc 9115 (match_dup 4))
28356f52 9116 (const_int 0)))
014753cc
UB
9117 (set (match_operand:SWI48 0 "register_operand" "")
9118 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9119 (match_operand:SWI48 1 "register_operand" "")
9120 (match_dup 0)))
28356f52 9121 (set (match_dup 1)
014753cc
UB
9122 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9123 (match_operand:SWI48 3 "register_operand" "r")
9124 (match_dup 1)))]
9125 "TARGET_CMOVE"
9126 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
28356f52 9127
014753cc
UB
9128(define_expand "x86_shift<mode>_adj_2"
9129 [(use (match_operand:SWI48 0 "register_operand" ""))
9130 (use (match_operand:SWI48 1 "register_operand" ""))
72ea2555 9131 (use (match_operand:QI 2 "register_operand" ""))]
014753cc 9132 ""
72ea2555
UB
9133{
9134 rtx label = gen_label_rtx ();
9135 rtx tmp;
9136
014753cc
UB
9137 emit_insn (gen_testqi_ccz_1 (operands[2],
9138 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
72ea2555
UB
9139
9140 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9141 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9142 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9143 gen_rtx_LABEL_REF (VOIDmode, label),
9144 pc_rtx);
9145 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9146 JUMP_LABEL (tmp) = label;
9147
9148 emit_move_insn (operands[0], operands[1]);
9149 ix86_expand_clear (operands[1]);
9150
9151 emit_label (label);
9152 LABEL_NUSES (label) = 1;
9153
9154 DONE;
9155})
9156
014753cc
UB
9157(define_insn "*ashl<mode>3_1"
9158 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9159 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9160 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
8bc527af 9161 (clobber (reg:CC FLAGS_REG))]
014753cc 9162 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
371bc54b
JH
9163{
9164 switch (get_attr_type (insn))
9165 {
719938ae
UB
9166 case TYPE_LEA:
9167 return "#";
9168
371bc54b 9169 case TYPE_ALU:
7637e42c
NS
9170 gcc_assert (operands[2] == const1_rtx);
9171 gcc_assert (rtx_equal_p (operands[0], operands[1]));
014753cc 9172 return "add{<imodesuffix>}\t%0, %0";
371bc54b 9173
371bc54b 9174 default:
719938ae
UB
9175 if (operands[2] == const1_rtx
9176 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
014753cc 9177 return "sal{<imodesuffix>}\t%0";
371bc54b 9178 else
014753cc 9179 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
371bc54b 9180 }
0f40f9f7 9181}
371bc54b
JH
9182 [(set (attr "type")
9183 (cond [(eq_attr "alternative" "1")
9184 (const_string "lea")
9185 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9186 (const_int 0))
9187 (match_operand 0 "register_operand" ""))
9188 (match_operand 2 "const1_operand" ""))
9189 (const_string "alu")
9190 ]
9191 (const_string "ishift")))
a952487c
JJ
9192 (set (attr "length_immediate")
9193 (if_then_else
9194 (ior (eq_attr "type" "alu")
9195 (and (eq_attr "type" "ishift")
9196 (and (match_operand 2 "const1_operand" "")
9197 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9198 (const_int 0)))))
9199 (const_string "0")
9200 (const_string "*")))
014753cc 9201 (set_attr "mode" "<MODE>")])
371bc54b 9202
014753cc
UB
9203(define_insn "*ashlsi3_1_zext"
9204 [(set (match_operand:DI 0 "register_operand" "=r,r")
9205 (zero_extend:DI
9206 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9207 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
8bc527af 9208 (clobber (reg:CC FLAGS_REG))]
014753cc 9209 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
371bc54b
JH
9210{
9211 switch (get_attr_type (insn))
9212 {
719938ae
UB
9213 case TYPE_LEA:
9214 return "#";
9215
371bc54b 9216 case TYPE_ALU:
7637e42c 9217 gcc_assert (operands[2] == const1_rtx);
014753cc
UB
9218 return "add{l}\t%k0, %k0";
9219
371bc54b 9220 default:
719938ae
UB
9221 if (operands[2] == const1_rtx
9222 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
014753cc 9223 return "sal{l}\t%k0";
371bc54b 9224 else
014753cc 9225 return "sal{l}\t{%2, %k0|%k0, %2}";
371bc54b 9226 }
0f40f9f7 9227}
371bc54b 9228 [(set (attr "type")
014753cc
UB
9229 (cond [(eq_attr "alternative" "1")
9230 (const_string "lea")
9231 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9232 (const_int 0))
371bc54b
JH
9233 (match_operand 2 "const1_operand" ""))
9234 (const_string "alu")
9235 ]
9236 (const_string "ishift")))
a952487c
JJ
9237 (set (attr "length_immediate")
9238 (if_then_else
9239 (ior (eq_attr "type" "alu")
9240 (and (eq_attr "type" "ishift")
9241 (and (match_operand 2 "const1_operand" "")
9242 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9243 (const_int 0)))))
9244 (const_string "0")
9245 (const_string "*")))
014753cc 9246 (set_attr "mode" "SI")])
371bc54b 9247
014753cc
UB
9248(define_insn "*ashlhi3_1"
9249 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9250 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9251 (match_operand:QI 2 "nonmemory_operand" "cI")))
9252 (clobber (reg:CC FLAGS_REG))]
9253 "TARGET_PARTIAL_REG_STALL
9254 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
f42684d5
UB
9255{
9256 switch (get_attr_type (insn))
9257 {
9258 case TYPE_ALU:
9259 gcc_assert (operands[2] == const1_rtx);
014753cc 9260 return "add{w}\t%0, %0";
f42684d5
UB
9261
9262 default:
719938ae
UB
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
014753cc 9265 return "sal{w}\t%0";
f42684d5 9266 else
014753cc 9267 return "sal{w}\t{%2, %0|%0, %2}";
f42684d5
UB
9268 }
9269}
9270 [(set (attr "type")
9271 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9272 (const_int 0))
9273 (match_operand 0 "register_operand" ""))
9274 (match_operand 2 "const1_operand" ""))
9275 (const_string "alu")
9276 ]
9277 (const_string "ishift")))
a952487c
JJ
9278 (set (attr "length_immediate")
9279 (if_then_else
9280 (ior (eq_attr "type" "alu")
9281 (and (eq_attr "type" "ishift")
9282 (and (match_operand 2 "const1_operand" "")
9283 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9284 (const_int 0)))))
9285 (const_string "0")
9286 (const_string "*")))
014753cc 9287 (set_attr "mode" "HI")])
d525dfdf 9288
014753cc
UB
9289(define_insn "*ashlhi3_1_lea"
9290 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9291 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
e075ae69 9292 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8bc527af 9293 (clobber (reg:CC FLAGS_REG))]
014753cc
UB
9294 "!TARGET_PARTIAL_REG_STALL
9295 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
2ae0f82c 9296{
e075ae69
RH
9297 switch (get_attr_type (insn))
9298 {
e075ae69 9299 case TYPE_LEA:
0f40f9f7 9300 return "#";
719938ae 9301
014753cc
UB
9302 case TYPE_ALU:
9303 gcc_assert (operands[2] == const1_rtx);
9304 return "add{w}\t%0, %0";
2ae0f82c 9305
e075ae69 9306 default:
719938ae
UB
9307 if (operands[2] == const1_rtx
9308 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
014753cc 9309 return "sal{w}\t%0";
e075ae69 9310 else
014753cc 9311 return "sal{w}\t{%2, %0|%0, %2}";
e075ae69 9312 }
0f40f9f7 9313}
e075ae69
RH
9314 [(set (attr "type")
9315 (cond [(eq_attr "alternative" "1")
9316 (const_string "lea")
9317 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9318 (const_int 0))
9319 (match_operand 0 "register_operand" ""))
9320 (match_operand 2 "const1_operand" ""))
9321 (const_string "alu")
9322 ]
6ef67412 9323 (const_string "ishift")))
a952487c
JJ
9324 (set (attr "length_immediate")
9325 (if_then_else
9326 (ior (eq_attr "type" "alu")
9327 (and (eq_attr "type" "ishift")
9328 (and (match_operand 2 "const1_operand" "")
9329 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9330 (const_int 0)))))
9331 (const_string "0")
9332 (const_string "*")))
014753cc 9333 (set_attr "mode" "HI,SI")])
e075ae69 9334
014753cc
UB
9335(define_insn "*ashlqi3_1"
9336 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9337 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9338 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
8bc527af 9339 (clobber (reg:CC FLAGS_REG))]
014753cc
UB
9340 "TARGET_PARTIAL_REG_STALL
9341 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
58787064 9342{
014753cc
UB
9343 switch (get_attr_type (insn))
9344 {
9345 case TYPE_ALU:
9346 gcc_assert (operands[2] == const1_rtx);
9347 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9348 return "add{l}\t%k0, %k0";
9349 else
9350 return "add{b}\t%0, %0";
f42684d5
UB
9351
9352 default:
719938ae
UB
9353 if (operands[2] == const1_rtx
9354 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
014753cc
UB
9355 {
9356 if (get_attr_mode (insn) == MODE_SI)
719938ae 9357 return "sal{l}\t%k0";
014753cc
UB
9358 else
9359 return "sal{b}\t%0";
9360 }
f42684d5 9361 else
014753cc
UB
9362 {
9363 if (get_attr_mode (insn) == MODE_SI)
9364 return "sal{l}\t{%2, %k0|%k0, %2}";
9365 else
9366 return "sal{b}\t{%2, %0|%0, %2}";
9367 }
f42684d5
UB
9368 }
9369}
9370 [(set (attr "type")
9371 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9372 (const_int 0))
9373 (match_operand 0 "register_operand" ""))
9374 (match_operand 2 "const1_operand" ""))
9375 (const_string "alu")
9376 ]
9377 (const_string "ishift")))
a952487c
JJ
9378 (set (attr "length_immediate")
9379 (if_then_else
9380 (ior (eq_attr "type" "alu")
9381 (and (eq_attr "type" "ishift")
9382 (and (match_operand 2 "const1_operand" "")
9383 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9384 (const_int 0)))))
9385 (const_string "0")
9386 (const_string "*")))
014753cc 9387 (set_attr "mode" "QI,SI")])
d525dfdf 9388
e075ae69 9389;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
9390(define_insn "*ashlqi3_1_lea"
9391 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9a9286af 9392 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
91f9a498 9393 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8bc527af 9394 (clobber (reg:CC FLAGS_REG))]
58787064
JH
9395 "!TARGET_PARTIAL_REG_STALL
9396 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
58787064
JH
9397{
9398 switch (get_attr_type (insn))
9399 {
9400 case TYPE_LEA:
0f40f9f7 9401 return "#";
719938ae 9402
58787064 9403 case TYPE_ALU:
7637e42c 9404 gcc_assert (operands[2] == const1_rtx);
1a06f5fe 9405 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
a23132e1 9406 return "add{l}\t%k0, %k0";
58787064 9407 else
a23132e1 9408 return "add{b}\t%0, %0";
58787064
JH
9409
9410 default:
719938ae
UB
9411 if (operands[2] == const1_rtx
9412 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
58787064
JH
9413 {
9414 if (get_attr_mode (insn) == MODE_SI)
719938ae 9415 return "sal{l}\t%k0";
58787064 9416 else
0f40f9f7 9417 return "sal{b}\t%0";
58787064
JH
9418 }
9419 else
9420 {
9421 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 9422 return "sal{l}\t{%2, %k0|%k0, %2}";
58787064 9423 else
0f40f9f7 9424 return "sal{b}\t{%2, %0|%0, %2}";
58787064
JH
9425 }
9426 }
0f40f9f7 9427}
58787064
JH
9428 [(set (attr "type")
9429 (cond [(eq_attr "alternative" "2")
9430 (const_string "lea")
9431 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9432 (const_int 0))
9433 (match_operand 0 "register_operand" ""))
9434 (match_operand 2 "const1_operand" ""))
9435 (const_string "alu")
9436 ]
9437 (const_string "ishift")))
a952487c
JJ
9438 (set (attr "length_immediate")
9439 (if_then_else
9440 (ior (eq_attr "type" "alu")
9441 (and (eq_attr "type" "ishift")
9442 (and (match_operand 2 "const1_operand" "")
9443 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9444 (const_int 0)))))
9445 (const_string "0")
9446 (const_string "*")))
58787064
JH
9447 (set_attr "mode" "QI,SI,SI")])
9448
3f529c2c
UB
9449(define_insn "*ashlqi3_1_slp"
9450 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9451 (ashift:QI (match_dup 0)
9452 (match_operand:QI 1 "nonmemory_operand" "cI")))
9453 (clobber (reg:CC FLAGS_REG))]
9454 "(optimize_function_for_size_p (cfun)
9455 || !TARGET_PARTIAL_FLAG_REG_STALL
9456 || (operands[1] == const1_rtx
9457 && (TARGET_SHIFT1
9458 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9459{
9460 switch (get_attr_type (insn))
9461 {
9462 case TYPE_ALU:
9463 gcc_assert (operands[1] == const1_rtx);
9464 return "add{b}\t%0, %0";
9465
9466 default:
9467 if (operands[1] == const1_rtx
9468 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9469 return "sal{b}\t%0";
9470 else
9471 return "sal{b}\t{%1, %0|%0, %1}";
9472 }
9473}
9474 [(set (attr "type")
9475 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9476 (const_int 0))
9477 (match_operand 0 "register_operand" ""))
9478 (match_operand 1 "const1_operand" ""))
9479 (const_string "alu")
9480 ]
9481 (const_string "ishift1")))
9482 (set (attr "length_immediate")
9483 (if_then_else
9484 (ior (eq_attr "type" "alu")
9485 (and (eq_attr "type" "ishift1")
9486 (and (match_operand 1 "const1_operand" "")
9487 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9488 (const_int 0)))))
9489 (const_string "0")
9490 (const_string "*")))
9491 (set_attr "mode" "QI")])
9492
014753cc
UB
9493;; Convert lea to the lea pattern to avoid flags dependency.
9494(define_split
9495 [(set (match_operand 0 "register_operand" "")
9496 (ashift (match_operand 1 "index_register_operand" "")
9497 (match_operand:QI 2 "const_int_operand" "")))
9498 (clobber (reg:CC FLAGS_REG))]
9499 "reload_completed
f1b62c9f 9500 && true_regnum (operands[0]) != true_regnum (operands[1])"
014753cc
UB
9501 [(const_int 0)]
9502{
9503 rtx pat;
9504 enum machine_mode mode = GET_MODE (operands[0]);
9505
014753cc
UB
9506 if (mode != Pmode)
9507 operands[1] = gen_lowpart (Pmode, operands[1]);
9508 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9509
9510 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
f1b62c9f
UB
9511
9512 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9513 operands[0] = gen_lowpart (SImode, operands[0]);
9514
9515 if (TARGET_64BIT && mode != Pmode)
014753cc 9516 pat = gen_rtx_SUBREG (SImode, pat, 0);
f1b62c9f 9517
014753cc
UB
9518 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9519 DONE;
9520})
9521
f1b62c9f
UB
9522;; Convert lea to the lea pattern to avoid flags dependency.
9523(define_split
9524 [(set (match_operand:DI 0 "register_operand" "")
9525 (zero_extend:DI
9526 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9527 (match_operand:QI 2 "const_int_operand" ""))))
9528 (clobber (reg:CC FLAGS_REG))]
9529 "TARGET_64BIT && reload_completed
9530 && true_regnum (operands[0]) != true_regnum (operands[1])"
9531 [(set (match_dup 0)
9532 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9533{
9534 operands[1] = gen_lowpart (DImode, operands[1]);
9535 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9536})
9537
014753cc
UB
9538;; This pattern can't accept a variable shift count, since shifts by
9539;; zero don't affect the flags. We assume that shifts by constant
9540;; zero are optimized away.
9541(define_insn "*ashl<mode>3_cmp"
9542 [(set (reg FLAGS_REG)
9543 (compare
9544 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9545 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9546 (const_int 0)))
9547 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9548 (ashift:SWI (match_dup 1) (match_dup 2)))]
9549 "(optimize_function_for_size_p (cfun)
9550 || !TARGET_PARTIAL_FLAG_REG_STALL
9551 || (operands[2] == const1_rtx
9552 && (TARGET_SHIFT1
9553 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9554 && ix86_match_ccmode (insn, CCGOCmode)
9555 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
886c62d1 9556{
e075ae69
RH
9557 switch (get_attr_type (insn))
9558 {
9559 case TYPE_ALU:
7637e42c 9560 gcc_assert (operands[2] == const1_rtx);
014753cc 9561 return "add{<imodesuffix>}\t%0, %0";
886c62d1 9562
e075ae69 9563 default:
014753cc
UB
9564 if (operands[2] == const1_rtx
9565 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9566 return "sal{<imodesuffix>}\t%0";
e075ae69 9567 else
014753cc 9568 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
e075ae69 9569 }
0f40f9f7 9570}
e075ae69
RH
9571 [(set (attr "type")
9572 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9573 (const_int 0))
9574 (match_operand 0 "register_operand" ""))
9575 (match_operand 2 "const1_operand" ""))
9576 (const_string "alu")
9577 ]
6ef67412 9578 (const_string "ishift")))
a952487c
JJ
9579 (set (attr "length_immediate")
9580 (if_then_else
9581 (ior (eq_attr "type" "alu")
9582 (and (eq_attr "type" "ishift")
9583 (and (match_operand 2 "const1_operand" "")
9584 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9585 (const_int 0)))))
9586 (const_string "0")
9587 (const_string "*")))
014753cc 9588 (set_attr "mode" "<MODE>")])
e075ae69 9589
014753cc 9590(define_insn "*ashlsi3_cmp_zext"
42fabf21 9591 [(set (reg FLAGS_REG)
16189740 9592 (compare
014753cc 9593 (ashift:SI (match_operand:SI 1 "register_operand" "0")
ef719a44 9594 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 9595 (const_int 0)))
014753cc
UB
9596 (set (match_operand:DI 0 "register_operand" "=r")
9597 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9598 "TARGET_64BIT
9599 && (optimize_function_for_size_p (cfun)
9600 || !TARGET_PARTIAL_FLAG_REG_STALL
9601 || (operands[2] == const1_rtx
9602 && (TARGET_SHIFT1
9603 || TARGET_DOUBLE_WITH_ADD)))
d5d5d289 9604 && ix86_match_ccmode (insn, CCGOCmode)
014753cc 9605 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
886c62d1 9606{
e075ae69
RH
9607 switch (get_attr_type (insn))
9608 {
9609 case TYPE_ALU:
7637e42c 9610 gcc_assert (operands[2] == const1_rtx);
014753cc 9611 return "add{l}\t%k0, %k0";
e075ae69
RH
9612
9613 default:
014753cc
UB
9614 if (operands[2] == const1_rtx
9615 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9616 return "sal{l}\t%k0";
e075ae69 9617 else
014753cc 9618 return "sal{l}\t{%2, %k0|%k0, %2}";
e075ae69 9619 }
0f40f9f7 9620}
e075ae69 9621 [(set (attr "type")
014753cc
UB
9622 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9623 (const_int 0))
e075ae69
RH
9624 (match_operand 2 "const1_operand" ""))
9625 (const_string "alu")
9626 ]
6ef67412 9627 (const_string "ishift")))
a952487c
JJ
9628 (set (attr "length_immediate")
9629 (if_then_else
9630 (ior (eq_attr "type" "alu")
9631 (and (eq_attr "type" "ishift")
9632 (and (match_operand 2 "const1_operand" "")
9633 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9634 (const_int 0)))))
9635 (const_string "0")
9636 (const_string "*")))
014753cc 9637 (set_attr "mode" "SI")])
886c62d1 9638
014753cc 9639(define_insn "*ashl<mode>3_cconly"
f42684d5
UB
9640 [(set (reg FLAGS_REG)
9641 (compare
014753cc
UB
9642 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9643 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
f42684d5 9644 (const_int 0)))
014753cc 9645 (clobber (match_scratch:SWI 0 "=<r>"))]
3debdc1e 9646 "(optimize_function_for_size_p (cfun)
d5d5d289
L
9647 || !TARGET_PARTIAL_FLAG_REG_STALL
9648 || (operands[2] == const1_rtx
9649 && (TARGET_SHIFT1
9650 || TARGET_DOUBLE_WITH_ADD)))
9651 && ix86_match_ccmode (insn, CCGOCmode)
014753cc 9652 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
f42684d5
UB
9653{
9654 switch (get_attr_type (insn))
9655 {
9656 case TYPE_ALU:
9657 gcc_assert (operands[2] == const1_rtx);
014753cc 9658 return "add{<imodesuffix>}\t%0, %0";
f42684d5
UB
9659
9660 default:
014753cc
UB
9661 if (operands[2] == const1_rtx
9662 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9663 return "sal{<imodesuffix>}\t%0";
f42684d5 9664 else
014753cc 9665 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
f42684d5
UB
9666 }
9667}
9668 [(set (attr "type")
9669 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9670 (const_int 0))
9671 (match_operand 0 "register_operand" ""))
9672 (match_operand 2 "const1_operand" ""))
9673 (const_string "alu")
9674 ]
9675 (const_string "ishift")))
a952487c
JJ
9676 (set (attr "length_immediate")
9677 (if_then_else
9678 (ior (eq_attr "type" "alu")
9679 (and (eq_attr "type" "ishift")
9680 (and (match_operand 2 "const1_operand" "")
9681 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9682 (const_int 0)))))
9683 (const_string "0")
9684 (const_string "*")))
014753cc 9685 (set_attr "mode" "<MODE>")])
f42684d5 9686
d72ebc16 9687;; See comment above `ashl<mode>3' about how this works.
886c62d1 9688
d72ebc16 9689(define_expand "<shiftrt_insn><mode>3"
27431d88 9690 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
d72ebc16
UB
9691 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9692 (match_operand:QI 2 "nonmemory_operand" "")))]
27431d88 9693 ""
d72ebc16 9694 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
28356f52 9695
d72ebc16 9696(define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
27431d88 9697 [(set (match_operand:DWI 0 "register_operand" "=r")
d72ebc16
UB
9698 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9699 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
28356f52 9700 (clobber (reg:CC FLAGS_REG))]
27431d88 9701 ""
28356f52 9702 "#"
27431d88
UB
9703 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9704 [(const_int 0)]
d72ebc16 9705 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
28356f52
JB
9706 [(set_attr "type" "multi")])
9707
27431d88
UB
9708;; By default we don't ask for a scratch register, because when DWImode
9709;; values are manipulated, registers are already at a premium. But if
9710;; we have one handy, we won't turn it away.
9711
934f2a96 9712(define_peephole2
27431d88
UB
9713 [(match_scratch:DWIH 3 "r")
9714 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
d72ebc16 9715 (any_shiftrt:<DWI>
27431d88
UB
9716 (match_operand:<DWI> 1 "register_operand" "")
9717 (match_operand:QI 2 "nonmemory_operand" "")))
934f2a96
UB
9718 (clobber (reg:CC FLAGS_REG))])
9719 (match_dup 3)]
27431d88 9720 "TARGET_CMOVE"
28356f52 9721 [(const_int 0)]
d72ebc16 9722 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
28356f52
JB
9723
9724(define_insn "x86_64_shrd"
934f2a96 9725 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
28356f52 9726 (ior:DI (ashiftrt:DI (match_dup 0)
934f2a96
UB
9727 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9728 (ashift:DI (match_operand:DI 1 "register_operand" "r")
28356f52
JB
9729 (minus:QI (const_int 64) (match_dup 2)))))
9730 (clobber (reg:CC FLAGS_REG))]
9731 "TARGET_64BIT"
934f2a96 9732 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
28356f52
JB
9733 [(set_attr "type" "ishift")
9734 (set_attr "prefix_0f" "1")
9735 (set_attr "mode" "DI")
21efb4d4 9736 (set_attr "athlon_decode" "vector")
4f3f76e6 9737 (set_attr "amdfam10_decode" "vector")])
28356f52 9738
27431d88
UB
9739(define_insn "x86_shrd"
9740 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9741 (ior:SI (ashiftrt:SI (match_dup 0)
9742 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9743 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9744 (minus:QI (const_int 32) (match_dup 2)))))
9745 (clobber (reg:CC FLAGS_REG))]
72ea2555 9746 ""
27431d88
UB
9747 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9748 [(set_attr "type" "ishift")
9749 (set_attr "prefix_0f" "1")
656ef6bb 9750 (set_attr "mode" "SI")
27431d88 9751 (set_attr "pent_pair" "np")
656ef6bb
UB
9752 (set_attr "athlon_decode" "vector")
9753 (set_attr "amdfam10_decode" "vector")])
72ea2555 9754
27431d88 9755(define_insn "ashrdi3_cvt"
371bc54b
JH
9756 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9757 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
27431d88 9758 (match_operand:QI 2 "const_int_operand" "")))
8bc527af 9759 (clobber (reg:CC FLAGS_REG))]
93330ea1 9760 "TARGET_64BIT && INTVAL (operands[2]) == 63
3debdc1e 9761 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
371bc54b
JH
9762 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9763 "@
9764 {cqto|cqo}
0f40f9f7 9765 sar{q}\t{%2, %0|%0, %2}"
371bc54b
JH
9766 [(set_attr "type" "imovx,ishift")
9767 (set_attr "prefix_0f" "0,*")
9768 (set_attr "length_immediate" "0,*")
9769 (set_attr "modrm" "0,1")
9770 (set_attr "mode" "DI")])
9771
9200ac72
UB
9772(define_insn "ashrsi3_cvt"
9773 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9774 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9775 (match_operand:QI 2 "const_int_operand" "")))
8bc527af 9776 (clobber (reg:CC FLAGS_REG))]
9200ac72 9777 "INTVAL (operands[2]) == 31
27431d88
UB
9778 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9779 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
371bc54b 9780 "@
27431d88 9781 {cltd|cdq}
9200ac72 9782 sar{l}\t{%2, %0|%0, %2}"
27431d88
UB
9783 [(set_attr "type" "imovx,ishift")
9784 (set_attr "prefix_0f" "0,*")
9785 (set_attr "length_immediate" "0,*")
9786 (set_attr "modrm" "0,1")
9787 (set_attr "mode" "SI")])
886c62d1 9788
9200ac72
UB
9789(define_insn "*ashrsi3_cvt_zext"
9790 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9791 (zero_extend:DI
9792 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9793 (match_operand:QI 2 "const_int_operand" ""))))
8bc527af 9794 (clobber (reg:CC FLAGS_REG))]
9200ac72 9795 "TARGET_64BIT && INTVAL (operands[2]) == 31
27431d88
UB
9796 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9797 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9798 "@
9799 {cltd|cdq}
9200ac72 9800 sar{l}\t{%2, %k0|%k0, %2}"
27431d88
UB
9801 [(set_attr "type" "imovx,ishift")
9802 (set_attr "prefix_0f" "0,*")
9803 (set_attr "length_immediate" "0,*")
9804 (set_attr "modrm" "0,1")
6ef67412 9805 (set_attr "mode" "SI")])
e075ae69 9806
27431d88
UB
9807(define_expand "x86_shift<mode>_adj_3"
9808 [(use (match_operand:SWI48 0 "register_operand" ""))
9809 (use (match_operand:SWI48 1 "register_operand" ""))
e075ae69
RH
9810 (use (match_operand:QI 2 "register_operand" ""))]
9811 ""
886c62d1 9812{
e075ae69
RH
9813 rtx label = gen_label_rtx ();
9814 rtx tmp;
9815
27431d88
UB
9816 emit_insn (gen_testqi_ccz_1 (operands[2],
9817 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
e075ae69 9818
16189740 9819 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
9820 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9821 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9822 gen_rtx_LABEL_REF (VOIDmode, label),
9823 pc_rtx);
9824 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9825 JUMP_LABEL (tmp) = label;
9826
9827 emit_move_insn (operands[0], operands[1]);
27431d88
UB
9828 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9829 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
e075ae69
RH
9830 emit_label (label);
9831 LABEL_NUSES (label) = 1;
9832
9833 DONE;
0f40f9f7 9834})
886c62d1 9835
d72ebc16 9836(define_insn "*<shiftrt_insn><mode>3_1"
9200ac72 9837 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
d72ebc16
UB
9838 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9839 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
8bc527af 9840 (clobber (reg:CC FLAGS_REG))]
d72ebc16 9841 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9200ac72 9842{
719938ae
UB
9843 if (operands[2] == const1_rtx
9844 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
d72ebc16 9845 return "<shiftrt>{<imodesuffix>}\t%0";
9200ac72 9846 else
d72ebc16 9847 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9200ac72 9848}
6ef67412 9849 [(set_attr "type" "ishift")
9200ac72
UB
9850 (set (attr "length_immediate")
9851 (if_then_else
9852 (and (match_operand 2 "const1_operand" "")
9853 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9854 (const_int 0)))
9855 (const_string "0")
9856 (const_string "*")))
9857 (set_attr "mode" "<MODE>")])
886c62d1 9858
d72ebc16 9859(define_insn "*<shiftrt_insn>si3_1_zext"
9200ac72 9860 [(set (match_operand:DI 0 "register_operand" "=r")
371bc54b 9861 (zero_extend:DI
d72ebc16
UB
9862 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9863 (match_operand:QI 2 "nonmemory_operand" "cI"))))
8bc527af 9864 (clobber (reg:CC FLAGS_REG))]
d72ebc16 9865 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9200ac72 9866{
719938ae
UB
9867 if (operands[2] == const1_rtx
9868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
d72ebc16 9869 return "<shiftrt>{l}\t%k0";
9200ac72 9870 else
d72ebc16 9871 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9200ac72 9872}
6ef67412 9873 [(set_attr "type" "ishift")
9200ac72
UB
9874 (set (attr "length_immediate")
9875 (if_then_else
9876 (and (match_operand 2 "const1_operand" "")
9877 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9878 (const_int 0)))
9879 (const_string "0")
9880 (const_string "*")))
9881 (set_attr "mode" "SI")])
886c62d1 9882
d72ebc16 9883(define_insn "*<shiftrt_insn>qi3_1_slp"
9200ac72 9884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
d72ebc16
UB
9885 (any_shiftrt:QI (match_dup 0)
9886 (match_operand:QI 1 "nonmemory_operand" "cI")))
8bc527af 9887 (clobber (reg:CC FLAGS_REG))]
9200ac72
UB
9888 "(optimize_function_for_size_p (cfun)
9889 || !TARGET_PARTIAL_REG_STALL
9890 || (operands[1] == const1_rtx
9891 && TARGET_SHIFT1))"
9892{
719938ae
UB
9893 if (operands[1] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
d72ebc16 9895 return "<shiftrt>{b}\t%0";
9200ac72 9896 else
d72ebc16 9897 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9200ac72 9898}
1b245ade 9899 [(set_attr "type" "ishift1")
9200ac72
UB
9900 (set (attr "length_immediate")
9901 (if_then_else
9902 (and (match_operand 1 "const1_operand" "")
9903 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9904 (const_int 0)))
9905 (const_string "0")
9906 (const_string "*")))
2f41793e
JH
9907 (set_attr "mode" "QI")])
9908
8bad7136
JL
9909;; This pattern can't accept a variable shift count, since shifts by
9910;; zero don't affect the flags. We assume that shifts by constant
9911;; zero are optimized away.
d72ebc16 9912(define_insn "*<shiftrt_insn><mode>3_cmp"
f42684d5
UB
9913 [(set (reg FLAGS_REG)
9914 (compare
d72ebc16
UB
9915 (any_shiftrt:SWI
9916 (match_operand:SWI 1 "nonimmediate_operand" "0")
9917 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
f42684d5 9918 (const_int 0)))
9200ac72 9919 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
d72ebc16 9920 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9200ac72
UB
9921 "(optimize_function_for_size_p (cfun)
9922 || !TARGET_PARTIAL_FLAG_REG_STALL
9923 || (operands[2] == const1_rtx
9924 && TARGET_SHIFT1))
d5d5d289 9925 && ix86_match_ccmode (insn, CCGOCmode)
d72ebc16 9926 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9200ac72
UB
9927{
9928 if (operands[2] == const1_rtx
9929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
d72ebc16 9930 return "<shiftrt>{<imodesuffix>}\t%0";
9200ac72 9931 else
d72ebc16 9932 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9200ac72 9933}
f42684d5 9934 [(set_attr "type" "ishift")
9200ac72
UB
9935 (set (attr "length_immediate")
9936 (if_then_else
9937 (and (match_operand 2 "const1_operand" "")
9938 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9939 (const_int 0)))
9940 (const_string "0")
9941 (const_string "*")))
9942 (set_attr "mode" "<MODE>")])
f42684d5 9943
d72ebc16 9944(define_insn "*<shiftrt_insn>si3_cmp_zext"
42fabf21 9945 [(set (reg FLAGS_REG)
16189740 9946 (compare
d72ebc16
UB
9947 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 9949 (const_int 0)))
9200ac72 9950 (set (match_operand:DI 0 "register_operand" "=r")
d72ebc16 9951 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9200ac72
UB
9952 "TARGET_64BIT
9953 && (optimize_function_for_size_p (cfun)
9954 || !TARGET_PARTIAL_FLAG_REG_STALL
9955 || (operands[2] == const1_rtx
9956 && TARGET_SHIFT1))
d5d5d289 9957 && ix86_match_ccmode (insn, CCGOCmode)
d72ebc16 9958 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9200ac72
UB
9959{
9960 if (operands[2] == const1_rtx
9961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
d72ebc16 9962 return "<shiftrt>{l}\t%k0";
9200ac72 9963 else
d72ebc16 9964 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9200ac72 9965}
6ef67412 9966 [(set_attr "type" "ishift")
9200ac72
UB
9967 (set (attr "length_immediate")
9968 (if_then_else
9969 (and (match_operand 2 "const1_operand" "")
9970 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9971 (const_int 0)))
9972 (const_string "0")
9973 (const_string "*")))
9974 (set_attr "mode" "SI")])
f42684d5 9975
d72ebc16 9976(define_insn "*<shiftrt_insn><mode>3_cconly"
f42684d5
UB
9977 [(set (reg FLAGS_REG)
9978 (compare
d72ebc16
UB
9979 (any_shiftrt:SWI
9980 (match_operand:SWI 1 "nonimmediate_operand" "0")
9981 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
f42684d5 9982 (const_int 0)))
59caab22 9983 (clobber (match_scratch:SWI 0 "=<r>"))]
9200ac72
UB
9984 "(optimize_function_for_size_p (cfun)
9985 || !TARGET_PARTIAL_FLAG_REG_STALL
9986 || (operands[2] == const1_rtx
9987 && TARGET_SHIFT1))
d5d5d289 9988 && ix86_match_ccmode (insn, CCGOCmode)
d72ebc16 9989 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9200ac72
UB
9990{
9991 if (operands[2] == const1_rtx
9992 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
d72ebc16 9993 return "<shiftrt>{<imodesuffix>}\t%0";
9200ac72 9994 else
d72ebc16 9995 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9200ac72 9996}
f42684d5 9997 [(set_attr "type" "ishift")
9200ac72
UB
9998 (set (attr "length_immediate")
9999 (if_then_else
10000 (and (match_operand 2 "const1_operand" "")
10001 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10002 (const_int 0)))
10003 (const_string "0")
10004 (const_string "*")))
10005 (set_attr "mode" "<MODE>")])
886c62d1 10006\f
e075ae69 10007;; Rotate instructions
886c62d1 10008
e0db9cc6
UB
10009(define_expand "<rotate_insn>ti3"
10010 [(set (match_operand:TI 0 "register_operand" "")
10011 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10012 (match_operand:QI 2 "nonmemory_operand" "")))]
10013 "TARGET_64BIT"
10014{
10015 if (const_1_to_63_operand (operands[2], VOIDmode))
10016 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10017 (operands[0], operands[1], operands[2]));
10018 else
10019 FAIL;
10020
10021 DONE;
10022})
10023
10024(define_expand "<rotate_insn>di3"
0f8594ee 10025 [(set (match_operand:DI 0 "shiftdi_operand" "")
e0db9cc6
UB
10026 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10027 (match_operand:QI 2 "nonmemory_operand" "")))]
0f8594ee
MM
10028 ""
10029{
10030 if (TARGET_64BIT)
e0db9cc6
UB
10031 ix86_expand_binary_operator (<CODE>, DImode, operands);
10032 else if (const_1_to_31_operand (operands[2], VOIDmode))
10033 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10034 (operands[0], operands[1], operands[2]));
10035 else
0f8594ee 10036 FAIL;
e0db9cc6 10037
0f8594ee
MM
10038 DONE;
10039})
371bc54b 10040
e0db9cc6
UB
10041(define_expand "<rotate_insn><mode>3"
10042 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10043 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10044 (match_operand:QI 2 "nonmemory_operand" "")))]
10045 ""
10046 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10047
10048;; Implement rotation using two double-precision
10049;; shift instructions and a scratch register.
10050
10051(define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10052 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10053 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10054 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
0f8594ee 10055 (clobber (reg:CC FLAGS_REG))
e0db9cc6 10056 (clobber (match_scratch:DWIH 3 "=&r"))]
6300f037 10057 ""
e0db9cc6
UB
10058 "#"
10059 "reload_completed"
0f8594ee
MM
10060 [(set (match_dup 3) (match_dup 4))
10061 (parallel
10062 [(set (match_dup 4)
e0db9cc6
UB
10063 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10064 (lshiftrt:DWIH (match_dup 5)
10065 (minus:QI (match_dup 6) (match_dup 2)))))
0f8594ee
MM
10066 (clobber (reg:CC FLAGS_REG))])
10067 (parallel
10068 [(set (match_dup 5)
e0db9cc6
UB
10069 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10070 (lshiftrt:DWIH (match_dup 3)
10071 (minus:QI (match_dup 6) (match_dup 2)))))
0f8594ee 10072 (clobber (reg:CC FLAGS_REG))])]
0f8594ee 10073{
e0db9cc6
UB
10074 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10075
b146446c 10076 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
0f8594ee 10077})
6300f037 10078
e0db9cc6
UB
10079(define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10080 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10081 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10082 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
0f8594ee 10083 (clobber (reg:CC FLAGS_REG))
e0db9cc6 10084 (clobber (match_scratch:DWIH 3 "=&r"))]
0f8594ee 10085 ""
e0db9cc6
UB
10086 "#"
10087 "reload_completed"
0f8594ee
MM
10088 [(set (match_dup 3) (match_dup 4))
10089 (parallel
10090 [(set (match_dup 4)
e0db9cc6
UB
10091 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10092 (ashift:DWIH (match_dup 5)
10093 (minus:QI (match_dup 6) (match_dup 2)))))
0f8594ee
MM
10094 (clobber (reg:CC FLAGS_REG))])
10095 (parallel
10096 [(set (match_dup 5)
e0db9cc6
UB
10097 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10098 (ashift:DWIH (match_dup 3)
10099 (minus:QI (match_dup 6) (match_dup 2)))))
0f8594ee 10100 (clobber (reg:CC FLAGS_REG))])]
e0db9cc6
UB
10101{
10102 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
371bc54b 10103
b146446c 10104 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
e0db9cc6 10105})
d525dfdf 10106
e0db9cc6
UB
10107(define_insn "*<rotate_insn><mode>3_1"
10108 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10109 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10110 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
8bc527af 10111 (clobber (reg:CC FLAGS_REG))]
e0db9cc6
UB
10112 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10113{
719938ae
UB
10114 if (operands[2] == const1_rtx
10115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
e0db9cc6
UB
10116 return "<rotate>{<imodesuffix>}\t%0";
10117 else
10118 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10119}
890d52e8 10120 [(set_attr "type" "rotate")
e0db9cc6
UB
10121 (set (attr "length_immediate")
10122 (if_then_else
10123 (and (match_operand 2 "const1_operand" "")
10124 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10125 (const_int 0)))
10126 (const_string "0")
10127 (const_string "*")))
10128 (set_attr "mode" "<MODE>")])
8bad7136 10129
e0db9cc6 10130(define_insn "*<rotate_insn>si3_1_zext"
371bc54b
JH
10131 [(set (match_operand:DI 0 "register_operand" "=r")
10132 (zero_extend:DI
e0db9cc6
UB
10133 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10134 (match_operand:QI 2 "nonmemory_operand" "cI"))))
8bc527af 10135 (clobber (reg:CC FLAGS_REG))]
e0db9cc6
UB
10136 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10137{
719938ae
UB
10138 if (operands[2] == const1_rtx
10139 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
e0db9cc6
UB
10140 return "<rotate>{l}\t%k0";
10141 else
10142 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10143}
890d52e8 10144 [(set_attr "type" "rotate")
e0db9cc6
UB
10145 (set (attr "length_immediate")
10146 (if_then_else
10147 (and (match_operand 2 "const1_operand" "")
10148 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10149 (const_int 0)))
10150 (const_string "0")
10151 (const_string "*")))
371bc54b
JH
10152 (set_attr "mode" "SI")])
10153
e0db9cc6
UB
10154(define_insn "*<rotate_insn>qi3_1_slp"
10155 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10156 (any_rotate:QI (match_dup 0)
10157 (match_operand:QI 1 "nonmemory_operand" "cI")))
8bc527af 10158 (clobber (reg:CC FLAGS_REG))]
e0db9cc6
UB
10159 "(optimize_function_for_size_p (cfun)
10160 || !TARGET_PARTIAL_REG_STALL
10161 || (operands[1] == const1_rtx
10162 && TARGET_SHIFT1))"
10163{
719938ae
UB
10164 if (operands[1] == const1_rtx
10165 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
e0db9cc6
UB
10166 return "<rotate>{b}\t%0";
10167 else
10168 return "<rotate>{b}\t{%1, %0|%0, %1}";
10169}
10170 [(set_attr "type" "rotate1")
10171 (set (attr "length_immediate")
10172 (if_then_else
10173 (and (match_operand 1 "const1_operand" "")
10174 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10175 (const_int 0)))
10176 (const_string "0")
10177 (const_string "*")))
10178 (set_attr "mode" "QI")])
a199fdd6 10179
fa681e39
UB
10180(define_split
10181 [(set (match_operand:HI 0 "register_operand" "")
e0db9cc6 10182 (any_rotate:HI (match_dup 0) (const_int 8)))
fa681e39 10183 (clobber (reg:CC FLAGS_REG))]
e0db9cc6
UB
10184 "reload_completed
10185 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
fa681e39
UB
10186 [(parallel [(set (strict_low_part (match_dup 0))
10187 (bswap:HI (match_dup 0)))
cb1b497e 10188 (clobber (reg:CC FLAGS_REG))])])
e075ae69
RH
10189\f
10190;; Bit set / bit test instructions
a199fdd6 10191
e075ae69
RH
10192(define_expand "extv"
10193 [(set (match_operand:SI 0 "register_operand" "")
10194 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
f7acbf4c
RS
10195 (match_operand:SI 2 "const8_operand" "")
10196 (match_operand:SI 3 "const8_operand" "")))]
e075ae69 10197 ""
e075ae69
RH
10198{
10199 /* Handle extractions from %ah et al. */
10200 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10201 FAIL;
a199fdd6 10202
e075ae69
RH
10203 /* From mips.md: extract_bit_field doesn't verify that our source
10204 matches the predicate, so check it again here. */
6e62a38d 10205 if (! ext_register_operand (operands[1], VOIDmode))
e075ae69 10206 FAIL;
0f40f9f7 10207})
a199fdd6 10208
e075ae69
RH
10209(define_expand "extzv"
10210 [(set (match_operand:SI 0 "register_operand" "")
10211 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
f7acbf4c
RS
10212 (match_operand:SI 2 "const8_operand" "")
10213 (match_operand:SI 3 "const8_operand" "")))]
e075ae69 10214 ""
e075ae69
RH
10215{
10216 /* Handle extractions from %ah et al. */
10217 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10218 FAIL;
a199fdd6 10219
e075ae69
RH
10220 /* From mips.md: extract_bit_field doesn't verify that our source
10221 matches the predicate, so check it again here. */
6e62a38d 10222 if (! ext_register_operand (operands[1], VOIDmode))
e075ae69 10223 FAIL;
0f40f9f7 10224})
a199fdd6 10225
e075ae69 10226(define_expand "insv"
044b3892 10227 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
f7acbf4c
RS
10228 (match_operand 1 "const8_operand" "")
10229 (match_operand 2 "const8_operand" ""))
044b3892 10230 (match_operand 3 "register_operand" ""))]
e075ae69 10231 ""
e075ae69 10232{
9aa5922d
UB
10233 rtx (*gen_mov_insv_1) (rtx, rtx);
10234
f7acbf4c 10235 /* Handle insertions to %ah et al. */
e075ae69
RH
10236 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10237 FAIL;
a199fdd6 10238
e075ae69
RH
10239 /* From mips.md: insert_bit_field doesn't verify that our source
10240 matches the predicate, so check it again here. */
6e62a38d 10241 if (! ext_register_operand (operands[0], VOIDmode))
e075ae69 10242 FAIL;
044b3892 10243
9aa5922d
UB
10244 gen_mov_insv_1 = (TARGET_64BIT
10245 ? gen_movdi_insv_1 : gen_movsi_insv_1);
044b3892 10246
9aa5922d 10247 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
044b3892 10248 DONE;
0f40f9f7 10249})
e075ae69
RH
10250
10251;; %%% bts, btr, btc, bt.
7cacf53e
RH
10252;; In general these instructions are *slow* when applied to memory,
10253;; since they enforce atomic operation. When applied to registers,
10254;; it depends on the cpu implementation. They're never faster than
10255;; the corresponding and/ior/xor operations, so with 32-bit there's
10256;; no point. But in 64-bit, we can't hold the relevant immediates
10257;; within the instruction itself, so operating on bits in the high
10258;; 32-bits of a register becomes easier.
10259;;
10260;; These are slow on Nocona, but fast on Athlon64. We do require the use
10261;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10262;; negdf respectively, so they can never be disabled entirely.
10263
10264(define_insn "*btsq"
ad4f9e7e 10265 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
7cacf53e 10266 (const_int 1)
ad4f9e7e 10267 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
10268 (const_int 1))
10269 (clobber (reg:CC FLAGS_REG))]
10270 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
33ee5810 10271 "bts{q}\t{%1, %0|%0, %1}"
a952487c 10272 [(set_attr "type" "alu1")
725fd454
JJ
10273 (set_attr "prefix_0f" "1")
10274 (set_attr "mode" "DI")])
7cacf53e
RH
10275
10276(define_insn "*btrq"
ad4f9e7e 10277 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
7cacf53e 10278 (const_int 1)
ad4f9e7e 10279 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
10280 (const_int 0))
10281 (clobber (reg:CC FLAGS_REG))]
10282 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
33ee5810 10283 "btr{q}\t{%1, %0|%0, %1}"
a952487c 10284 [(set_attr "type" "alu1")
725fd454
JJ
10285 (set_attr "prefix_0f" "1")
10286 (set_attr "mode" "DI")])
7cacf53e
RH
10287
10288(define_insn "*btcq"
ad4f9e7e 10289 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
7cacf53e 10290 (const_int 1)
ad4f9e7e 10291 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
10292 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10293 (clobber (reg:CC FLAGS_REG))]
10294 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
33ee5810 10295 "btc{q}\t{%1, %0|%0, %1}"
a952487c 10296 [(set_attr "type" "alu1")
725fd454
JJ
10297 (set_attr "prefix_0f" "1")
10298 (set_attr "mode" "DI")])
7cacf53e
RH
10299
10300;; Allow Nocona to avoid these instructions if a register is available.
10301
10302(define_peephole2
10303 [(match_scratch:DI 2 "r")
10304 (parallel [(set (zero_extract:DI
ad4f9e7e 10305 (match_operand:DI 0 "register_operand" "")
7cacf53e 10306 (const_int 1)
ad4f9e7e 10307 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
10308 (const_int 1))
10309 (clobber (reg:CC FLAGS_REG))])]
10310 "TARGET_64BIT && !TARGET_USE_BT"
10311 [(const_int 0)]
10312{
10313 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10314 rtx op1;
10315
10316 if (HOST_BITS_PER_WIDE_INT >= 64)
10317 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10318 else if (i < HOST_BITS_PER_WIDE_INT)
10319 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10320 else
10321 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10322
10323 op1 = immed_double_const (lo, hi, DImode);
10324 if (i >= 31)
10325 {
10326 emit_move_insn (operands[2], op1);
10327 op1 = operands[2];
10328 }
10329
10330 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10331 DONE;
10332})
10333
10334(define_peephole2
10335 [(match_scratch:DI 2 "r")
10336 (parallel [(set (zero_extract:DI
ad4f9e7e 10337 (match_operand:DI 0 "register_operand" "")
7cacf53e 10338 (const_int 1)
ad4f9e7e 10339 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
10340 (const_int 0))
10341 (clobber (reg:CC FLAGS_REG))])]
10342 "TARGET_64BIT && !TARGET_USE_BT"
10343 [(const_int 0)]
10344{
10345 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10346 rtx op1;
10347
10348 if (HOST_BITS_PER_WIDE_INT >= 64)
10349 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10350 else if (i < HOST_BITS_PER_WIDE_INT)
10351 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10352 else
10353 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10354
10355 op1 = immed_double_const (~lo, ~hi, DImode);
10356 if (i >= 32)
10357 {
10358 emit_move_insn (operands[2], op1);
10359 op1 = operands[2];
10360 }
10361
10362 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10363 DONE;
10364})
10365
10366(define_peephole2
10367 [(match_scratch:DI 2 "r")
10368 (parallel [(set (zero_extract:DI
ad4f9e7e 10369 (match_operand:DI 0 "register_operand" "")
7cacf53e 10370 (const_int 1)
ad4f9e7e 10371 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
10372 (not:DI (zero_extract:DI
10373 (match_dup 0) (const_int 1) (match_dup 1))))
10374 (clobber (reg:CC FLAGS_REG))])]
10375 "TARGET_64BIT && !TARGET_USE_BT"
10376 [(const_int 0)]
10377{
10378 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10379 rtx op1;
10380
10381 if (HOST_BITS_PER_WIDE_INT >= 64)
10382 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10383 else if (i < HOST_BITS_PER_WIDE_INT)
10384 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10385 else
10386 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10387
10388 op1 = immed_double_const (lo, hi, DImode);
10389 if (i >= 31)
10390 {
10391 emit_move_insn (operands[2], op1);
10392 op1 = operands[2];
10393 }
10394
10395 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10396 DONE;
10397})
33ee5810 10398
4a81b412 10399(define_insn "*bt<mode>"
33ee5810
UB
10400 [(set (reg:CCC FLAGS_REG)
10401 (compare:CCC
4a81b412
UB
10402 (zero_extract:SWI48
10403 (match_operand:SWI48 0 "register_operand" "r")
33ee5810 10404 (const_int 1)
4a81b412 10405 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
33ee5810 10406 (const_int 0)))]
3debdc1e 10407 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
4a81b412 10408 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
a952487c 10409 [(set_attr "type" "alu1")
725fd454 10410 (set_attr "prefix_0f" "1")
4a81b412 10411 (set_attr "mode" "<MODE>")])
886c62d1
JVA
10412\f
10413;; Store-flag instructions.
10414
c572e5ba
JVA
10415;; For all sCOND expanders, also expand the compare or test insn that
10416;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10417
b09ee6aa
UB
10418(define_insn_and_split "*setcc_di_1"
10419 [(set (match_operand:DI 0 "register_operand" "=q")
10420 (match_operator:DI 1 "ix86_comparison_operator"
10421 [(reg FLAGS_REG) (const_int 0)]))]
10422 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10423 "#"
10424 "&& reload_completed"
10425 [(set (match_dup 2) (match_dup 1))
10426 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10427{
10428 PUT_MODE (operands[1], QImode);
10429 operands[2] = gen_lowpart (QImode, operands[0]);
10430})
10431
10432(define_insn_and_split "*setcc_si_1_and"
10433 [(set (match_operand:SI 0 "register_operand" "=q")
10434 (match_operator:SI 1 "ix86_comparison_operator"
10435 [(reg FLAGS_REG) (const_int 0)]))
10436 (clobber (reg:CC FLAGS_REG))]
10437 "!TARGET_PARTIAL_REG_STALL
10438 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10439 "#"
10440 "&& reload_completed"
10441 [(set (match_dup 2) (match_dup 1))
10442 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10443 (clobber (reg:CC FLAGS_REG))])]
10444{
10445 PUT_MODE (operands[1], QImode);
10446 operands[2] = gen_lowpart (QImode, operands[0]);
10447})
10448
10449(define_insn_and_split "*setcc_si_1_movzbl"
10450 [(set (match_operand:SI 0 "register_operand" "=q")
10451 (match_operator:SI 1 "ix86_comparison_operator"
10452 [(reg FLAGS_REG) (const_int 0)]))]
10453 "!TARGET_PARTIAL_REG_STALL
10454 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10455 "#"
10456 "&& reload_completed"
10457 [(set (match_dup 2) (match_dup 1))
10458 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10459{
10460 PUT_MODE (operands[1], QImode);
10461 operands[2] = gen_lowpart (QImode, operands[0]);
10462})
10463
b09ee6aa 10464(define_insn "*setcc_qi"
a269a03c 10465 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9076b9c1 10466 (match_operator:QI 1 "ix86_comparison_operator"
42fabf21 10467 [(reg FLAGS_REG) (const_int 0)]))]
e075ae69 10468 ""
0f40f9f7 10469 "set%C1\t%0"
6ef67412
JH
10470 [(set_attr "type" "setcc")
10471 (set_attr "mode" "QI")])
a269a03c 10472
b09ee6aa 10473(define_insn "*setcc_qi_slp"
e075ae69 10474 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9076b9c1 10475 (match_operator:QI 1 "ix86_comparison_operator"
42fabf21 10476 [(reg FLAGS_REG) (const_int 0)]))]
e075ae69 10477 ""
0f40f9f7 10478 "set%C1\t%0"
6ef67412
JH
10479 [(set_attr "type" "setcc")
10480 (set_attr "mode" "QI")])
e075ae69 10481
10978207 10482;; In general it is not safe to assume too much about CCmode registers,
6300f037 10483;; so simplify-rtx stops when it sees a second one. Under certain
10978207
RH
10484;; conditions this is safe on x86, so help combine not create
10485;;
10486;; seta %al
10487;; testb %al, %al
10488;; sete %al
10489
6300f037 10490(define_split
10978207
RH
10491 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10492 (ne:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 10493 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
10494 (const_int 0)))]
10495 ""
10496 [(set (match_dup 0) (match_dup 1))]
cb1b497e 10497 "PUT_MODE (operands[1], QImode);")
10978207 10498
6300f037 10499(define_split
10978207
RH
10500 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10501 (ne:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 10502 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
10503 (const_int 0)))]
10504 ""
10505 [(set (match_dup 0) (match_dup 1))]
cb1b497e 10506 "PUT_MODE (operands[1], QImode);")
10978207 10507
6300f037 10508(define_split
10978207
RH
10509 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10510 (eq:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 10511 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
10512 (const_int 0)))]
10513 ""
10514 [(set (match_dup 0) (match_dup 1))]
10515{
10516 rtx new_op1 = copy_rtx (operands[1]);
10517 operands[1] = new_op1;
10518 PUT_MODE (new_op1, QImode);
3c5cb3e4
KH
10519 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10520 GET_MODE (XEXP (new_op1, 0))));
10978207
RH
10521
10522 /* Make sure that (a) the CCmode we have for the flags is strong
10523 enough for the reversed compare or (b) we have a valid FP compare. */
10524 if (! ix86_comparison_operator (new_op1, VOIDmode))
10525 FAIL;
10526})
10527
6300f037 10528(define_split
10978207
RH
10529 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10530 (eq:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 10531 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
10532 (const_int 0)))]
10533 ""
10534 [(set (match_dup 0) (match_dup 1))]
10535{
10536 rtx new_op1 = copy_rtx (operands[1]);
10537 operands[1] = new_op1;
10538 PUT_MODE (new_op1, QImode);
3c5cb3e4
KH
10539 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10540 GET_MODE (XEXP (new_op1, 0))));
10978207
RH
10541
10542 /* Make sure that (a) the CCmode we have for the flags is strong
10543 enough for the reversed compare or (b) we have a valid FP compare. */
10544 if (! ix86_comparison_operator (new_op1, VOIDmode))
10545 FAIL;
10546})
10547
a46d1d38
JH
10548;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10549;; subsequent logical operations are used to imitate conditional moves.
10550;; 0xffffffff is NaN, but not in normalized form, so we can't represent
ab8efbd8 10551;; it directly.
a46d1d38 10552
95879c72
L
10553(define_insn "*avx_setcc<mode>"
10554 [(set (match_operand:MODEF 0 "register_operand" "=x")
10555 (match_operator:MODEF 1 "avx_comparison_float_operator"
10556 [(match_operand:MODEF 2 "register_operand" "x")
10557 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10558 "TARGET_AVX"
10559 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10560 [(set_attr "type" "ssecmp")
10561 (set_attr "prefix" "vex")
725fd454 10562 (set_attr "length_immediate" "1")
95879c72
L
10563 (set_attr "mode" "<MODE>")])
10564
d6023b50
UB
10565(define_insn "*sse_setcc<mode>"
10566 [(set (match_operand:MODEF 0 "register_operand" "=x")
10567 (match_operator:MODEF 1 "sse_comparison_operator"
10568 [(match_operand:MODEF 2 "register_operand" "0")
10569 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
5c1a2bb1 10570 "SSE_FLOAT_MODE_P (<MODE>mode)"
d6023b50 10571 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
3d34cd91 10572 [(set_attr "type" "ssecmp")
725fd454 10573 (set_attr "length_immediate" "1")
d6023b50 10574 (set_attr "mode" "<MODE>")])
886c62d1
JVA
10575\f
10576;; Basic conditional jump instructions.
10577;; We ignore the overflow flag for signed branch instructions.
10578
e075ae69
RH
10579(define_insn "*jcc_1"
10580 [(set (pc)
9076b9c1 10581 (if_then_else (match_operator 1 "ix86_comparison_operator"
42fabf21 10582 [(reg FLAGS_REG) (const_int 0)])
6ef67412 10583 (label_ref (match_operand 0 "" ""))
e075ae69
RH
10584 (pc)))]
10585 ""
0f40f9f7 10586 "%+j%C1\t%l0"
e075ae69 10587 [(set_attr "type" "ibr")
c7375e61 10588 (set_attr "modrm" "0")
efcc7037 10589 (set (attr "length")
6ef67412 10590 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 10591 (const_int -126))
6ef67412 10592 (lt (minus (match_dup 0) (pc))
db1077d3 10593 (const_int 128)))
efcc7037
JH
10594 (const_int 2)
10595 (const_int 6)))])
e075ae69
RH
10596
10597(define_insn "*jcc_2"
10598 [(set (pc)
9076b9c1 10599 (if_then_else (match_operator 1 "ix86_comparison_operator"
42fabf21 10600 [(reg FLAGS_REG) (const_int 0)])
e075ae69 10601 (pc)
6ef67412 10602 (label_ref (match_operand 0 "" ""))))]
e075ae69 10603 ""
0f40f9f7 10604 "%+j%c1\t%l0"
e075ae69 10605 [(set_attr "type" "ibr")
c7375e61 10606 (set_attr "modrm" "0")
efcc7037 10607 (set (attr "length")
6ef67412 10608 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 10609 (const_int -126))
6ef67412 10610 (lt (minus (match_dup 0) (pc))
db1077d3 10611 (const_int 128)))
efcc7037
JH
10612 (const_int 2)
10613 (const_int 6)))])
e075ae69 10614
592188a5 10615;; In general it is not safe to assume too much about CCmode registers,
6300f037 10616;; so simplify-rtx stops when it sees a second one. Under certain
592188a5
RH
10617;; conditions this is safe on x86, so help combine not create
10618;;
10619;; seta %al
10620;; testb %al, %al
10621;; je Lfoo
10622
6300f037 10623(define_split
592188a5
RH
10624 [(set (pc)
10625 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
42fabf21 10626 [(reg FLAGS_REG) (const_int 0)])
592188a5
RH
10627 (const_int 0))
10628 (label_ref (match_operand 1 "" ""))
10629 (pc)))]
10630 ""
10631 [(set (pc)
10632 (if_then_else (match_dup 0)
10633 (label_ref (match_dup 1))
10634 (pc)))]
cb1b497e 10635 "PUT_MODE (operands[0], VOIDmode);")
6300f037
EC
10636
10637(define_split
592188a5
RH
10638 [(set (pc)
10639 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
42fabf21 10640 [(reg FLAGS_REG) (const_int 0)])
592188a5
RH
10641 (const_int 0))
10642 (label_ref (match_operand 1 "" ""))
10643 (pc)))]
10644 ""
10645 [(set (pc)
10646 (if_then_else (match_dup 0)
10647 (label_ref (match_dup 1))
10648 (pc)))]
10649{
10650 rtx new_op0 = copy_rtx (operands[0]);
10651 operands[0] = new_op0;
10652 PUT_MODE (new_op0, VOIDmode);
3c5cb3e4
KH
10653 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10654 GET_MODE (XEXP (new_op0, 0))));
592188a5
RH
10655
10656 /* Make sure that (a) the CCmode we have for the flags is strong
10657 enough for the reversed compare or (b) we have a valid FP compare. */
10658 if (! ix86_comparison_operator (new_op0, VOIDmode))
10659 FAIL;
10660})
10661
4a81b412
UB
10662;; zero_extend in SImode is correct also for DImode, since this is what combine
10663;; pass generates from shift insn with QImode operand. Actually, the mode
10664;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
33ee5810
UB
10665;; appropriate modulo of the bit offset value.
10666
4a81b412 10667(define_insn_and_split "*jcc_bt<mode>"
33ee5810
UB
10668 [(set (pc)
10669 (if_then_else (match_operator 0 "bt_comparison_operator"
4a81b412
UB
10670 [(zero_extract:SWI48
10671 (match_operand:SWI48 1 "register_operand" "r")
33ee5810
UB
10672 (const_int 1)
10673 (zero_extend:SI
10674 (match_operand:QI 2 "register_operand" "r")))
10675 (const_int 0)])
10676 (label_ref (match_operand 3 "" ""))
b7f58d5d
UB
10677 (pc)))
10678 (clobber (reg:CC FLAGS_REG))]
4a81b412 10679 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
33ee5810
UB
10680 "#"
10681 "&& 1"
10682 [(set (reg:CCC FLAGS_REG)
10683 (compare:CCC
4a81b412 10684 (zero_extract:SWI48
33ee5810
UB
10685 (match_dup 1)
10686 (const_int 1)
10687 (match_dup 2))
10688 (const_int 0)))
10689 (set (pc)
10690 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10691 (label_ref (match_dup 3))
10692 (pc)))]
10693{
4a81b412 10694 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
33ee5810
UB
10695
10696 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10697})
10698
4a81b412
UB
10699;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10700;; also for DImode, this is what combine produces.
f638261a 10701(define_insn_and_split "*jcc_bt<mode>_mask"
88b9490b
UB
10702 [(set (pc)
10703 (if_then_else (match_operator 0 "bt_comparison_operator"
4a81b412
UB
10704 [(zero_extract:SWI48
10705 (match_operand:SWI48 1 "register_operand" "r")
88b9490b
UB
10706 (const_int 1)
10707 (and:SI
10708 (match_operand:SI 2 "register_operand" "r")
10709 (match_operand:SI 3 "const_int_operand" "n")))])
10710 (label_ref (match_operand 4 "" ""))
b7f58d5d
UB
10711 (pc)))
10712 (clobber (reg:CC FLAGS_REG))]
4a81b412
UB
10713 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10714 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10715 == GET_MODE_BITSIZE (<MODE>mode)-1"
88b9490b
UB
10716 "#"
10717 "&& 1"
10718 [(set (reg:CCC FLAGS_REG)
10719 (compare:CCC
4a81b412 10720 (zero_extract:SWI48
88b9490b
UB
10721 (match_dup 1)
10722 (const_int 1)
10723 (match_dup 2))
10724 (const_int 0)))
10725 (set (pc)
10726 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10727 (label_ref (match_dup 4))
10728 (pc)))]
10729{
4a81b412 10730 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
88b9490b
UB
10731
10732 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10733})
10734
33ee5810
UB
10735(define_insn_and_split "*jcc_btsi_1"
10736 [(set (pc)
10737 (if_then_else (match_operator 0 "bt_comparison_operator"
10738 [(and:SI
10739 (lshiftrt:SI
10740 (match_operand:SI 1 "register_operand" "r")
10741 (match_operand:QI 2 "register_operand" "r"))
10742 (const_int 1))
10743 (const_int 0)])
10744 (label_ref (match_operand 3 "" ""))
b7f58d5d
UB
10745 (pc)))
10746 (clobber (reg:CC FLAGS_REG))]
3debdc1e 10747 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
33ee5810
UB
10748 "#"
10749 "&& 1"
10750 [(set (reg:CCC FLAGS_REG)
10751 (compare:CCC
10752 (zero_extract:SI
10753 (match_dup 1)
10754 (const_int 1)
10755 (match_dup 2))
10756 (const_int 0)))
10757 (set (pc)
10758 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10759 (label_ref (match_dup 3))
10760 (pc)))]
10761{
10762 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10763
10764 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10765})
10766
88b9490b
UB
10767;; avoid useless masking of bit offset operand
10768(define_insn_and_split "*jcc_btsi_mask_1"
10769 [(set (pc)
10770 (if_then_else
10771 (match_operator 0 "bt_comparison_operator"
10772 [(and:SI
10773 (lshiftrt:SI
10774 (match_operand:SI 1 "register_operand" "r")
10775 (subreg:QI
10776 (and:SI
10777 (match_operand:SI 2 "register_operand" "r")
10778 (match_operand:SI 3 "const_int_operand" "n")) 0))
10779 (const_int 1))
10780 (const_int 0)])
10781 (label_ref (match_operand 4 "" ""))
b7f58d5d
UB
10782 (pc)))
10783 (clobber (reg:CC FLAGS_REG))]
3debdc1e 10784 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
88b9490b
UB
10785 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10786 "#"
10787 "&& 1"
10788 [(set (reg:CCC FLAGS_REG)
10789 (compare:CCC
10790 (zero_extract:SI
10791 (match_dup 1)
10792 (const_int 1)
10793 (match_dup 2))
10794 (const_int 0)))
10795 (set (pc)
10796 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10797 (label_ref (match_dup 4))
10798 (pc)))]
10799 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10800
0948ccb2
PB
10801;; Define combination compare-and-branch fp compare instructions to help
10802;; combine.
0644b628 10803
dedd9d05 10804(define_insn "*fp_jcc_1_387"
3a3677ff 10805 [(set (pc)
0948ccb2 10806 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
3a3677ff
RH
10807 [(match_operand 1 "register_operand" "f")
10808 (match_operand 2 "nonimmediate_operand" "fm")])
10809 (label_ref (match_operand 3 "" ""))
10810 (pc)))
8bc527af
SB
10811 (clobber (reg:CCFP FPSR_REG))
10812 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
10813 (clobber (match_scratch:HI 4 "=a"))]
10814 "TARGET_80387
10815 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 10816 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb 10817 && SELECT_CC_MODE (GET_CODE (operands[0]),
03598dea 10818 operands[1], operands[2]) == CCFPmode
0948ccb2 10819 && !TARGET_CMOVE"
3a3677ff
RH
10820 "#")
10821
dedd9d05 10822(define_insn "*fp_jcc_1r_387"
3a3677ff 10823 [(set (pc)
0948ccb2 10824 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
3a3677ff
RH
10825 [(match_operand 1 "register_operand" "f")
10826 (match_operand 2 "nonimmediate_operand" "fm")])
10827 (pc)
10828 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
10829 (clobber (reg:CCFP FPSR_REG))
10830 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
10831 (clobber (match_scratch:HI 4 "=a"))]
10832 "TARGET_80387
10833 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 10834 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb 10835 && SELECT_CC_MODE (GET_CODE (operands[0]),
03598dea 10836 operands[1], operands[2]) == CCFPmode
0948ccb2 10837 && !TARGET_CMOVE"
3a3677ff
RH
10838 "#")
10839
dedd9d05 10840(define_insn "*fp_jcc_2_387"
3a3677ff 10841 [(set (pc)
0948ccb2 10842 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
3a3677ff
RH
10843 [(match_operand 1 "register_operand" "f")
10844 (match_operand 2 "register_operand" "f")])
10845 (label_ref (match_operand 3 "" ""))
10846 (pc)))
8bc527af
SB
10847 (clobber (reg:CCFP FPSR_REG))
10848 (clobber (reg:CCFP FLAGS_REG))
3a3677ff 10849 (clobber (match_scratch:HI 4 "=a"))]
27ac40e2 10850 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea 10851 && GET_MODE (operands[1]) == GET_MODE (operands[2])
0948ccb2 10852 && !TARGET_CMOVE"
3a3677ff
RH
10853 "#")
10854
dedd9d05 10855(define_insn "*fp_jcc_2r_387"
3a3677ff 10856 [(set (pc)
0948ccb2 10857 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
3a3677ff
RH
10858 [(match_operand 1 "register_operand" "f")
10859 (match_operand 2 "register_operand" "f")])
10860 (pc)
10861 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
10862 (clobber (reg:CCFP FPSR_REG))
10863 (clobber (reg:CCFP FLAGS_REG))
3a3677ff 10864 (clobber (match_scratch:HI 4 "=a"))]
27ac40e2 10865 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea 10866 && GET_MODE (operands[1]) == GET_MODE (operands[2])
0948ccb2 10867 && !TARGET_CMOVE"
3a3677ff
RH
10868 "#")
10869
dedd9d05 10870(define_insn "*fp_jcc_3_387"
45c8c47f 10871 [(set (pc)
0948ccb2 10872 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
45c8c47f 10873 [(match_operand 1 "register_operand" "f")
0edb82cb 10874 (match_operand 2 "const0_operand" "")])
45c8c47f
UB
10875 (label_ref (match_operand 3 "" ""))
10876 (pc)))
10877 (clobber (reg:CCFP FPSR_REG))
10878 (clobber (reg:CCFP FLAGS_REG))
10879 (clobber (match_scratch:HI 4 "=a"))]
27ac40e2 10880 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
17153653 10881 && GET_MODE (operands[1]) == GET_MODE (operands[2])
45c8c47f
UB
10882 && SELECT_CC_MODE (GET_CODE (operands[0]),
10883 operands[1], operands[2]) == CCFPmode
0948ccb2 10884 && !TARGET_CMOVE"
45c8c47f
UB
10885 "#")
10886
3a3677ff
RH
10887(define_split
10888 [(set (pc)
0948ccb2 10889 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
3a3677ff
RH
10890 [(match_operand 1 "register_operand" "")
10891 (match_operand 2 "nonimmediate_operand" "")])
10892 (match_operand 3 "" "")
10893 (match_operand 4 "" "")))
8bc527af
SB
10894 (clobber (reg:CCFP FPSR_REG))
10895 (clobber (reg:CCFP FLAGS_REG))]
3a3677ff 10896 "reload_completed"
9e7adcb3 10897 [(const_int 0)]
3a3677ff 10898{
03598dea 10899 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
7c82106f 10900 operands[3], operands[4], NULL_RTX, NULL_RTX);
9e7adcb3 10901 DONE;
0f40f9f7 10902})
3a3677ff
RH
10903
10904(define_split
10905 [(set (pc)
0948ccb2 10906 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
3a3677ff 10907 [(match_operand 1 "register_operand" "")
45c8c47f 10908 (match_operand 2 "general_operand" "")])
3a3677ff
RH
10909 (match_operand 3 "" "")
10910 (match_operand 4 "" "")))
8bc527af
SB
10911 (clobber (reg:CCFP FPSR_REG))
10912 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
10913 (clobber (match_scratch:HI 5 "=a"))]
10914 "reload_completed"
45c8c47f 10915 [(const_int 0)]
3a3677ff 10916{
03598dea 10917 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
7c82106f
UB
10918 operands[3], operands[4], operands[5], NULL_RTX);
10919 DONE;
10920})
10921
dedd9d05
UB
10922;; The order of operands in *fp_jcc_4_387 is forced by combine in
10923;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10924;; with a precedence over other operators and is always put in the first
10925;; place. Swap condition and operands to match ficom instruction.
10926
10927(define_insn "*fp_jcc_4_<mode>_387"
10928 [(set (pc)
10929 (if_then_else
10930 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10931 [(match_operator 1 "float_operator"
10932 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10933 (match_operand 3 "register_operand" "f,f")])
10934 (label_ref (match_operand 4 "" ""))
10935 (pc)))
10936 (clobber (reg:CCFP FPSR_REG))
10937 (clobber (reg:CCFP FLAGS_REG))
10938 (clobber (match_scratch:HI 5 "=a,a"))]
10939 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10940 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10941 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10942 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10943 && !TARGET_CMOVE"
10944 "#")
10945
7c82106f
UB
10946(define_split
10947 [(set (pc)
dedd9d05
UB
10948 (if_then_else
10949 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10950 [(match_operator 1 "float_operator"
10951 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10952 (match_operand 3 "register_operand" "")])
7c82106f
UB
10953 (match_operand 4 "" "")
10954 (match_operand 5 "" "")))
10955 (clobber (reg:CCFP FPSR_REG))
10956 (clobber (reg:CCFP FLAGS_REG))
10957 (clobber (match_scratch:HI 6 "=a"))]
10958 "reload_completed"
10959 [(const_int 0)]
10960{
10961 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
6a0447ba 10962
7c82106f
UB
10963 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10964 operands[3], operands[7],
10965 operands[4], operands[5], operands[6], NULL_RTX);
10966 DONE;
10967})
10968
10969;; %%% Kill this when reload knows how to do it.
10970(define_split
10971 [(set (pc)
dedd9d05
UB
10972 (if_then_else
10973 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10974 [(match_operator 1 "float_operator"
10975 [(match_operand:X87MODEI12 2 "register_operand" "")])
10976 (match_operand 3 "register_operand" "")])
7c82106f
UB
10977 (match_operand 4 "" "")
10978 (match_operand 5 "" "")))
10979 (clobber (reg:CCFP FPSR_REG))
10980 (clobber (reg:CCFP FLAGS_REG))
10981 (clobber (match_scratch:HI 6 "=a"))]
10982 "reload_completed"
10983 [(const_int 0)]
10984{
10985 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10986 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
6a0447ba 10987
7c82106f
UB
10988 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10989 operands[3], operands[7],
10990 operands[4], operands[5], operands[6], operands[2]);
9e7adcb3 10991 DONE;
0f40f9f7 10992})
886c62d1
JVA
10993\f
10994;; Unconditional and other jump instructions
10995
10996(define_insn "jump"
10997 [(set (pc)
10998 (label_ref (match_operand 0 "" "")))]
10999 ""
0f40f9f7 11000 "jmp\t%l0"
c7375e61 11001 [(set_attr "type" "ibr")
efcc7037
JH
11002 (set (attr "length")
11003 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 11004 (const_int -126))
efcc7037 11005 (lt (minus (match_dup 0) (pc))
db1077d3 11006 (const_int 128)))
efcc7037
JH
11007 (const_int 2)
11008 (const_int 5)))
c7375e61 11009 (set_attr "modrm" "0")])
886c62d1 11010
14f73b5a 11011(define_expand "indirect_jump"
00188daa 11012 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
886c62d1 11013 ""
14f73b5a
JH
11014 "")
11015
11016(define_insn "*indirect_jump"
c4fe74e0
UB
11017 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11018 ""
0f40f9f7 11019 "jmp\t%A0"
6ef67412
JH
11020 [(set_attr "type" "ibr")
11021 (set_attr "length_immediate" "0")])
4801403e 11022
90675921 11023(define_expand "tablejump"
00188daa 11024 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
90675921
RH
11025 (use (label_ref (match_operand 1 "" "")))])]
11026 ""
11027{
66edd3b4
RH
11028 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11029 relative. Convert the relative address to an absolute address. */
90675921
RH
11030 if (flag_pic)
11031 {
66edd3b4
RH
11032 rtx op0, op1;
11033 enum rtx_code code;
11034
170bdaba
RS
11035 /* We can't use @GOTOFF for text labels on VxWorks;
11036 see gotoff_operand. */
11037 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
66edd3b4
RH
11038 {
11039 code = PLUS;
11040 op0 = operands[0];
11041 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11042 }
b069de3b 11043 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
f88c65f7 11044 {
66edd3b4
RH
11045 code = PLUS;
11046 op0 = operands[0];
11047 op1 = pic_offset_table_rtx;
f88c65f7 11048 }
6eb791fc
JH
11049 else
11050 {
66edd3b4
RH
11051 code = MINUS;
11052 op0 = pic_offset_table_rtx;
11053 op1 = operands[0];
6eb791fc 11054 }
66edd3b4 11055
c16576e6 11056 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
66edd3b4 11057 OPTAB_DIRECT);
90675921 11058 }
0f40f9f7 11059})
2bb7a0f5 11060
90675921 11061(define_insn "*tablejump_1"
c4fe74e0 11062 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14f73b5a 11063 (use (label_ref (match_operand 1 "" "")))]
c4fe74e0 11064 ""
0f40f9f7 11065 "jmp\t%A0"
6ef67412
JH
11066 [(set_attr "type" "ibr")
11067 (set_attr "length_immediate" "0")])
e075ae69 11068\f
c50e5bc0
RH
11069;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11070
11071(define_peephole2
42fabf21 11072 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
c50e5bc0
RH
11073 (set (match_operand:QI 1 "register_operand" "")
11074 (match_operator:QI 2 "ix86_comparison_operator"
42fabf21 11075 [(reg FLAGS_REG) (const_int 0)]))
c50e5bc0
RH
11076 (set (match_operand 3 "q_regs_operand" "")
11077 (zero_extend (match_dup 1)))]
646ded90
RH
11078 "(peep2_reg_dead_p (3, operands[1])
11079 || operands_match_p (operands[1], operands[3]))
c50e5bc0 11080 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
646ded90
RH
11081 [(set (match_dup 4) (match_dup 0))
11082 (set (strict_low_part (match_dup 5))
11083 (match_dup 2))]
11084{
ff680eb1 11085 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
1e2115dc 11086 operands[5] = gen_lowpart (QImode, operands[3]);
a8bac9ab 11087 ix86_expand_clear (operands[3]);
646ded90
RH
11088})
11089
11090;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11091
11092(define_peephole2
42fabf21 11093 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
646ded90
RH
11094 (set (match_operand:QI 1 "register_operand" "")
11095 (match_operator:QI 2 "ix86_comparison_operator"
42fabf21 11096 [(reg FLAGS_REG) (const_int 0)]))
646ded90
RH
11097 (parallel [(set (match_operand 3 "q_regs_operand" "")
11098 (zero_extend (match_dup 1)))
8bc527af 11099 (clobber (reg:CC FLAGS_REG))])]
646ded90
RH
11100 "(peep2_reg_dead_p (3, operands[1])
11101 || operands_match_p (operands[1], operands[3]))
11102 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11103 [(set (match_dup 4) (match_dup 0))
c50e5bc0
RH
11104 (set (strict_low_part (match_dup 5))
11105 (match_dup 2))]
646ded90 11106{
ff680eb1 11107 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
1e2115dc 11108 operands[5] = gen_lowpart (QImode, operands[3]);
a8bac9ab 11109 ix86_expand_clear (operands[3]);
646ded90 11110})
e075ae69
RH
11111\f
11112;; Call instructions.
2bb7a0f5 11113
cbbf65e0
RH
11114;; The predicates normally associated with named expanders are not properly
11115;; checked for calls. This is a bug in the generic code, but it isn't that
11116;; easy to fix. Ignore it for now and be prepared to fix things up.
2bb7a0f5 11117
8410737a
UB
11118;; P6 processors will jump to the address after the decrement when %esp
11119;; is used as a call operand, so they will execute return address as a code.
11120;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11121
886c62d1
JVA
11122;; Call subroutine returning no value.
11123
2bb7a0f5 11124(define_expand "call_pop"
cbbf65e0
RH
11125 [(parallel [(call (match_operand:QI 0 "" "")
11126 (match_operand:SI 1 "" ""))
8bc527af
SB
11127 (set (reg:SI SP_REG)
11128 (plus:SI (reg:SI SP_REG)
cbbf65e0 11129 (match_operand:SI 3 "" "")))])]
1e07edd3 11130 "!TARGET_64BIT"
2bb7a0f5 11131{
0f032845
UB
11132 ix86_expand_call (NULL, operands[0], operands[1],
11133 operands[2], operands[3], 0);
0e07aff3 11134 DONE;
0f40f9f7 11135})
2bb7a0f5 11136
94bb5d0c 11137(define_insn "*call_pop_0"
e1ff012c 11138 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
94bb5d0c 11139 (match_operand:SI 1 "" ""))
0f032845
UB
11140 (set (reg:SI SP_REG)
11141 (plus:SI (reg:SI SP_REG)
11142 (match_operand:SI 2 "immediate_operand" "")))]
1e07edd3 11143 "!TARGET_64BIT"
94bb5d0c
RH
11144{
11145 if (SIBLING_CALL_P (insn))
0f40f9f7 11146 return "jmp\t%P0";
94bb5d0c 11147 else
0f40f9f7
ZW
11148 return "call\t%P0";
11149}
94bb5d0c 11150 [(set_attr "type" "call")])
6300f037 11151
55a19d49
UB
11152(define_insn "*call_pop_1"
11153 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11154 (match_operand:SI 1 "" ""))
0f032845
UB
11155 (set (reg:SI SP_REG)
11156 (plus:SI (reg:SI SP_REG)
11157 (match_operand:SI 2 "immediate_operand" "i")))]
8410737a 11158 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
886c62d1 11159{
e1ff012c 11160 if (constant_call_address_operand (operands[0], Pmode))
8c40d061
UB
11161 return "call\t%P0";
11162 return "call\t%A0";
0f40f9f7 11163}
e075ae69 11164 [(set_attr "type" "call")])
886c62d1 11165
8c40d061
UB
11166(define_insn "*sibcall_pop_1"
11167 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11168 (match_operand:SI 1 "" ""))
0f032845
UB
11169 (set (reg:SI SP_REG)
11170 (plus:SI (reg:SI SP_REG)
11171 (match_operand:SI 2 "immediate_operand" "i,i")))]
55a19d49 11172 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
8c40d061
UB
11173 "@
11174 jmp\t%P0
11175 jmp\t%A0"
11176 [(set_attr "type" "call")])
11177
2bb7a0f5 11178(define_expand "call"
cbbf65e0 11179 [(call (match_operand:QI 0 "" "")
39d04363
JH
11180 (match_operand 1 "" ""))
11181 (use (match_operand 2 "" ""))]
2bb7a0f5 11182 ""
2bb7a0f5 11183{
4977bab6
ZW
11184 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11185 DONE;
11186})
11187
11188(define_expand "sibcall"
11189 [(call (match_operand:QI 0 "" "")
11190 (match_operand 1 "" ""))
11191 (use (match_operand 2 "" ""))]
11192 ""
11193{
11194 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
0e07aff3 11195 DONE;
0f40f9f7 11196})
2bb7a0f5 11197
94bb5d0c 11198(define_insn "*call_0"
32ee7d1d
JH
11199 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11200 (match_operand 1 "" ""))]
94bb5d0c 11201 ""
94bb5d0c
RH
11202{
11203 if (SIBLING_CALL_P (insn))
0f40f9f7 11204 return "jmp\t%P0";
94bb5d0c 11205 else
0f40f9f7
ZW
11206 return "call\t%P0";
11207}
94bb5d0c
RH
11208 [(set_attr "type" "call")])
11209
55a19d49
UB
11210(define_insn "*call_1"
11211 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11212 (match_operand 1 "" ""))]
8410737a 11213 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
32ee7d1d 11214{
e427abbf 11215 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
11216 return "call\t%P0";
11217 return "call\t%A0";
11218}
11219 [(set_attr "type" "call")])
11220
11221(define_insn "*sibcall_1"
ac2e563f 11222 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
4977bab6 11223 (match_operand 1 "" ""))]
55a19d49 11224 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
ac2e563f
RH
11225 "@
11226 jmp\t%P0
11227 jmp\t%A0"
32ee7d1d
JH
11228 [(set_attr "type" "call")])
11229
11230(define_insn "*call_1_rex64"
11231 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11232 (match_operand 1 "" ""))]
55a19d49 11233 "TARGET_64BIT && !SIBLING_CALL_P (insn)
dc4d7240 11234 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
886c62d1 11235{
e427abbf 11236 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
11237 return "call\t%P0";
11238 return "call\t%A0";
0f40f9f7 11239}
e075ae69 11240 [(set_attr "type" "call")])
886c62d1 11241
924eabec
JH
11242(define_insn "*call_1_rex64_ms_sysv"
11243 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11244 (match_operand 1 "" ""))
11245 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
78168632
UB
11246 (clobber (reg:TI XMM6_REG))
11247 (clobber (reg:TI XMM7_REG))
11248 (clobber (reg:TI XMM8_REG))
11249 (clobber (reg:TI XMM9_REG))
11250 (clobber (reg:TI XMM10_REG))
11251 (clobber (reg:TI XMM11_REG))
11252 (clobber (reg:TI XMM12_REG))
11253 (clobber (reg:TI XMM13_REG))
11254 (clobber (reg:TI XMM14_REG))
11255 (clobber (reg:TI XMM15_REG))
924eabec
JH
11256 (clobber (reg:DI SI_REG))
11257 (clobber (reg:DI DI_REG))]
55a19d49 11258 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
924eabec
JH
11259{
11260 if (constant_call_address_operand (operands[0], Pmode))
11261 return "call\t%P0";
11262 return "call\t%A0";
11263}
11264 [(set_attr "type" "call")])
11265
dc4d7240
JH
11266(define_insn "*call_1_rex64_large"
11267 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11268 (match_operand 1 "" ""))]
55a19d49 11269 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
dc4d7240
JH
11270 "call\t%A0"
11271 [(set_attr "type" "call")])
11272
4977bab6 11273(define_insn "*sibcall_1_rex64"
ac2e563f 11274 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
4977bab6 11275 (match_operand 1 "" ""))]
55a19d49 11276 "TARGET_64BIT && SIBLING_CALL_P (insn)"
ac2e563f
RH
11277 "@
11278 jmp\t%P0
11279 jmp\t%A0"
4977bab6
ZW
11280 [(set_attr "type" "call")])
11281
886c62d1 11282;; Call subroutine, returning value in operand 0
2bb7a0f5
RS
11283(define_expand "call_value_pop"
11284 [(parallel [(set (match_operand 0 "" "")
cbbf65e0
RH
11285 (call (match_operand:QI 1 "" "")
11286 (match_operand:SI 2 "" "")))
8bc527af
SB
11287 (set (reg:SI SP_REG)
11288 (plus:SI (reg:SI SP_REG)
cbbf65e0 11289 (match_operand:SI 4 "" "")))])]
1e07edd3 11290 "!TARGET_64BIT"
2bb7a0f5 11291{
0e07aff3 11292 ix86_expand_call (operands[0], operands[1], operands[2],
4977bab6 11293 operands[3], operands[4], 0);
0e07aff3 11294 DONE;
0f40f9f7 11295})
2bb7a0f5 11296
2bb7a0f5
RS
11297(define_expand "call_value"
11298 [(set (match_operand 0 "" "")
cbbf65e0 11299 (call (match_operand:QI 1 "" "")
39d04363
JH
11300 (match_operand:SI 2 "" "")))
11301 (use (match_operand:SI 3 "" ""))]
0f032845 11302 ;; Operand 3 is not used on the i386.
2bb7a0f5 11303 ""
2bb7a0f5 11304{
0f032845
UB
11305 ix86_expand_call (operands[0], operands[1], operands[2],
11306 operands[3], NULL, 0);
4977bab6
ZW
11307 DONE;
11308})
11309
11310(define_expand "sibcall_value"
11311 [(set (match_operand 0 "" "")
11312 (call (match_operand:QI 1 "" "")
11313 (match_operand:SI 2 "" "")))
11314 (use (match_operand:SI 3 "" ""))]
0f032845 11315 ;; Operand 3 is not used on the i386.
4977bab6
ZW
11316 ""
11317{
0f032845
UB
11318 ix86_expand_call (operands[0], operands[1], operands[2],
11319 operands[3], NULL, 1);
39d04363 11320 DONE;
0f40f9f7 11321})
2bb7a0f5 11322
b840bfb0
MM
11323;; Call subroutine returning any type.
11324
576182a3 11325(define_expand "untyped_call"
b840bfb0 11326 [(parallel [(call (match_operand 0 "" "")
576182a3 11327 (const_int 0))
b840bfb0 11328 (match_operand 1 "" "")
576182a3
TW
11329 (match_operand 2 "" "")])]
11330 ""
576182a3 11331{
b840bfb0 11332 int i;
576182a3 11333
d8b679b9
RK
11334 /* In order to give reg-stack an easier job in validating two
11335 coprocessor registers as containing a possible return value,
11336 simply pretend the untyped call returns a complex long double
435a61d3
L
11337 value.
11338
11339 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11340 and should have the default ABI. */
74775c7a 11341
0e07aff3
RH
11342 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11343 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
7c800926 11344 operands[0], const0_rtx,
435a61d3 11345 GEN_INT ((TARGET_64BIT
51212b32 11346 ? (ix86_abi == SYSV_ABI
435a61d3 11347 ? X86_64_SSE_REGPARM_MAX
72fa3605 11348 : X86_64_MS_SSE_REGPARM_MAX)
435a61d3 11349 : X86_32_SSE_REGPARM_MAX)
7c800926 11350 - 1),
4977bab6 11351 NULL, 0);
576182a3 11352
b840bfb0 11353 for (i = 0; i < XVECLEN (operands[2], 0); i++)
576182a3 11354 {
b840bfb0
MM
11355 rtx set = XVECEXP (operands[2], 0, i);
11356 emit_move_insn (SET_DEST (set), SET_SRC (set));
576182a3 11357 }
576182a3 11358
b840bfb0
MM
11359 /* The optimizer does not know that the call sets the function value
11360 registers we stored in the result block. We avoid problems by
11361 claiming that all hard registers are used and clobbered at this
11362 point. */
6fb5fa3c 11363 emit_insn (gen_blockage ());
576182a3
TW
11364
11365 DONE;
0f40f9f7 11366})
e075ae69
RH
11367\f
11368;; Prologue and epilogue instructions
576182a3 11369
b840bfb0
MM
11370;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11371;; all of memory. This blocks insns from being moved across this point.
11372
11373(define_insn "blockage"
6fb5fa3c
DB
11374 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11375 ""
11376 ""
11377 [(set_attr "length" "0")])
11378
b058b753
UB
11379;; Do not schedule instructions accessing memory across this point.
11380
11381(define_expand "memory_blockage"
11382 [(set (match_dup 0)
11383 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11384 ""
11385{
11386 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11387 MEM_VOLATILE_P (operands[0]) = 1;
11388})
11389
11390(define_insn "*memory_blockage"
11391 [(set (match_operand:BLK 0 "" "")
11392 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11393 ""
11394 ""
11395 [(set_attr "length" "0")])
11396
6fb5fa3c
DB
11397;; As USE insns aren't meaningful after reload, this is used instead
11398;; to prevent deleting instructions setting registers for PIC code
11399(define_insn "prologue_use"
11400 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
576182a3 11401 ""
90aec2cf 11402 ""
e075ae69 11403 [(set_attr "length" "0")])
576182a3 11404
886c62d1
JVA
11405;; Insn emitted into the body of a function to return from a function.
11406;; This is only done if the function's epilogue is known to be simple.
182a4620 11407;; See comments for ix86_can_use_return_insn_p in i386.c.
886c62d1 11408
5f3d14e3 11409(define_expand "return"
886c62d1 11410 [(return)]
5f3d14e3 11411 "ix86_can_use_return_insn_p ()"
9a7372d6 11412{
38173d38 11413 if (crtl->args.pops_args)
9a7372d6 11414 {
38173d38 11415 rtx popc = GEN_INT (crtl->args.pops_args);
9a7372d6
RH
11416 emit_jump_insn (gen_return_pop_internal (popc));
11417 DONE;
11418 }
0f40f9f7 11419})
5f3d14e3
SC
11420
11421(define_insn "return_internal"
11422 [(return)]
11423 "reload_completed"
90aec2cf 11424 "ret"
6ef67412 11425 [(set_attr "length" "1")
b6837b94 11426 (set_attr "atom_unit" "jeu")
6ef67412
JH
11427 (set_attr "length_immediate" "0")
11428 (set_attr "modrm" "0")])
5f3d14e3 11429
253c7a00
JH
11430;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11431;; instruction Athlon and K8 have.
11432
11433(define_insn "return_internal_long"
11434 [(return)
11435 (unspec [(const_int 0)] UNSPEC_REP)]
11436 "reload_completed"
9ad5e54f 11437 "rep\;ret"
a952487c 11438 [(set_attr "length" "2")
b6837b94 11439 (set_attr "atom_unit" "jeu")
253c7a00
JH
11440 (set_attr "length_immediate" "0")
11441 (set_attr "prefix_rep" "1")
11442 (set_attr "modrm" "0")])
11443
6cd96118
SC
11444(define_insn "return_pop_internal"
11445 [(return)
11446 (use (match_operand:SI 0 "const_int_operand" ""))]
11447 "reload_completed"
0f40f9f7 11448 "ret\t%0"
6ef67412 11449 [(set_attr "length" "3")
b6837b94 11450 (set_attr "atom_unit" "jeu")
6ef67412
JH
11451 (set_attr "length_immediate" "2")
11452 (set_attr "modrm" "0")])
6cd96118 11453
11837777
RH
11454(define_insn "return_indirect_internal"
11455 [(return)
11456 (use (match_operand:SI 0 "register_operand" "r"))]
11457 "reload_completed"
0f40f9f7 11458 "jmp\t%A0"
11837777
RH
11459 [(set_attr "type" "ibr")
11460 (set_attr "length_immediate" "0")])
11461
5f3d14e3
SC
11462(define_insn "nop"
11463 [(const_int 0)]
11464 ""
90aec2cf 11465 "nop"
e075ae69 11466 [(set_attr "length" "1")
6ef67412 11467 (set_attr "length_immediate" "0")
56bab446 11468 (set_attr "modrm" "0")])
5f3d14e3 11469
e7ed95a2
L
11470;; Generate nops. Operand 0 is the number of nops, up to 8.
11471(define_insn "nops"
17eba947
UB
11472 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11473 UNSPECV_NOPS)]
e7ed95a2
L
11474 "reload_completed"
11475{
17eba947
UB
11476 int num = INTVAL (operands[0]);
11477
11478 gcc_assert (num >= 1 && num <= 8);
11479
11480 while (num--)
11481 fputs ("\tnop\n", asm_out_file);
11482
11483 return "";
e7ed95a2
L
11484}
11485 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11486 (set_attr "length_immediate" "0")
11487 (set_attr "modrm" "0")])
11488
6a90d232 11489;; Pad to 16-byte boundary, max skip in op0. Used to avoid
9ccf9681
RH
11490;; branch prediction penalty for the third jump in a 16-byte
11491;; block on K8.
d2c49530 11492
6a90d232 11493(define_insn "pad"
d2c49530
JH
11494 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11495 ""
11496{
6a90d232
L
11497#ifdef ASM_OUTPUT_MAX_SKIP_PAD
11498 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
9ccf9681 11499#else
6262f66a
JH
11500 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11501 The align insn is used to avoid 3 jump instructions in the row to improve
6fc0bb99 11502 branch prediction and the benefits hardly outweigh the cost of extra 8
6262f66a 11503 nops on the average inserted by full alignment pseudo operation. */
d2c49530 11504#endif
9ccf9681 11505 return "";
d2c49530
JH
11506}
11507 [(set_attr "length" "16")])
11508
5f3d14e3 11509(define_expand "prologue"
00188daa 11510 [(const_int 0)]
5f3d14e3 11511 ""
e075ae69 11512 "ix86_expand_prologue (); DONE;")
5f3d14e3 11513
bd09bdeb 11514(define_insn "set_got"
69404d6f 11515 [(set (match_operand:SI 0 "register_operand" "=r")
c8c03509 11516 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
8bc527af 11517 (clobber (reg:CC FLAGS_REG))]
1e07edd3 11518 "!TARGET_64BIT"
6fd71fde 11519 "* return output_set_got (operands[0], NULL_RTX);"
7d072037
SH
11520 [(set_attr "type" "multi")
11521 (set_attr "length" "12")])
11522
11523(define_insn "set_got_labelled"
11524 [(set (match_operand:SI 0 "register_operand" "=r")
11525 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11526 UNSPEC_SET_GOT))
11527 (clobber (reg:CC FLAGS_REG))]
11528 "!TARGET_64BIT"
6fd71fde 11529 "* return output_set_got (operands[0], operands[1]);"
c8c03509
RH
11530 [(set_attr "type" "multi")
11531 (set_attr "length" "12")])
5f3d14e3 11532
7dcbf659
JH
11533(define_insn "set_got_rex64"
11534 [(set (match_operand:DI 0 "register_operand" "=r")
11535 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11536 "TARGET_64BIT"
9ad5e54f 11537 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
7dcbf659 11538 [(set_attr "type" "lea")
725fd454
JJ
11539 (set_attr "length_address" "4")
11540 (set_attr "mode" "DI")])
7dcbf659 11541
dc4d7240
JH
11542(define_insn "set_rip_rex64"
11543 [(set (match_operand:DI 0 "register_operand" "=r")
bef3c57b 11544 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
dc4d7240 11545 "TARGET_64BIT"
9ad5e54f 11546 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
dc4d7240 11547 [(set_attr "type" "lea")
725fd454
JJ
11548 (set_attr "length_address" "4")
11549 (set_attr "mode" "DI")])
dc4d7240
JH
11550
11551(define_insn "set_got_offset_rex64"
11552 [(set (match_operand:DI 0 "register_operand" "=r")
bef3c57b
UB
11553 (unspec:DI
11554 [(label_ref (match_operand 1 "" ""))]
11555 UNSPEC_SET_GOT_OFFSET))]
dc4d7240 11556 "TARGET_64BIT"
9ad5e54f 11557 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
dc4d7240 11558 [(set_attr "type" "imov")
725fd454
JJ
11559 (set_attr "length_immediate" "0")
11560 (set_attr "length_address" "8")
11561 (set_attr "mode" "DI")])
dc4d7240 11562
e075ae69 11563(define_expand "epilogue"
00188daa 11564 [(const_int 0)]
e075ae69 11565 ""
cbbf65e0
RH
11566 "ix86_expand_epilogue (1); DONE;")
11567
11568(define_expand "sibcall_epilogue"
00188daa 11569 [(const_int 0)]
cbbf65e0
RH
11570 ""
11571 "ix86_expand_epilogue (0); DONE;")
e075ae69 11572
1020a5ab 11573(define_expand "eh_return"
34dc173c 11574 [(use (match_operand 0 "register_operand" ""))]
1020a5ab 11575 ""
1020a5ab 11576{
34dc173c 11577 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
1020a5ab
RH
11578
11579 /* Tricky bit: we write the address of the handler to which we will
11580 be returning into someone else's stack frame, one word below the
11581 stack address we wish to restore. */
11582 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11583 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11584 tmp = gen_rtx_MEM (Pmode, tmp);
11585 emit_move_insn (tmp, ra);
11586
cd9c1ca8 11587 emit_jump_insn (gen_eh_return_internal ());
1020a5ab
RH
11588 emit_barrier ();
11589 DONE;
0f40f9f7 11590})
1020a5ab 11591
cd9c1ca8
RH
11592(define_insn_and_split "eh_return_internal"
11593 [(eh_return)]
c4fe74e0 11594 ""
1020a5ab 11595 "#"
cd9c1ca8 11596 "epilogue_completed"
00188daa 11597 [(const_int 0)]
1020a5ab
RH
11598 "ix86_expand_epilogue (2); DONE;")
11599
e075ae69 11600(define_insn "leave"
8bc527af
SB
11601 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11602 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
f2042df3 11603 (clobber (mem:BLK (scratch)))]
1e07edd3 11604 "!TARGET_64BIT"
e075ae69 11605 "leave"
4977bab6 11606 [(set_attr "type" "leave")])
8362f420
JH
11607
11608(define_insn "leave_rex64"
8bc527af
SB
11609 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11610 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
f2042df3 11611 (clobber (mem:BLK (scratch)))]
8362f420
JH
11612 "TARGET_64BIT"
11613 "leave"
4977bab6 11614 [(set_attr "type" "leave")])
e075ae69 11615\f
7458026b
ILT
11616;; Handle -fsplit-stack.
11617
11618(define_expand "split_stack_prologue"
11619 [(const_int 0)]
11620 ""
11621{
11622 ix86_expand_split_stack_prologue ();
11623 DONE;
11624})
11625
11626;; In order to support the call/return predictor, we use a return
11627;; instruction which the middle-end doesn't see.
11628(define_insn "split_stack_return"
11629 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11630 UNSPEC_STACK_CHECK)]
11631 ""
11632{
11633 if (operands[0] == const0_rtx)
11634 return "ret";
11635 else
11636 return "ret\t%0";
11637}
11638 [(set_attr "atom_unit" "jeu")
11639 (set_attr "modrm" "0")
11640 (set (attr "length")
11641 (if_then_else (match_operand:SI 0 "const0_operand" "")
11642 (const_int 1)
11643 (const_int 3)))
11644 (set (attr "length_immediate")
11645 (if_then_else (match_operand:SI 0 "const0_operand" "")
11646 (const_int 0)
11647 (const_int 2)))])
11648
11649;; If there are operand 0 bytes available on the stack, jump to
11650;; operand 1.
11651
11652(define_expand "split_stack_space_check"
11653 [(set (pc) (if_then_else
11654 (ltu (minus (reg SP_REG)
11655 (match_operand 0 "register_operand" ""))
11656 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11657 (label_ref (match_operand 1 "" ""))
11658 (pc)))]
11659 ""
11660{
11661 rtx reg, size, limit;
11662
11663 reg = gen_reg_rtx (Pmode);
11664 size = force_reg (Pmode, operands[0]);
11665 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11666 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11667 UNSPEC_STACK_CHECK);
11668 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11669 ix86_expand_branch (GEU, reg, limit, operands[1]);
11670
11671 DONE;
11672})
11673\f
e96ccb30 11674;; Bit manipulation instructions.
e075ae69 11675
e96ccb30 11676(define_expand "ffs<mode>2"
8acfdd43 11677 [(set (match_dup 2) (const_int -1))
08024fb5 11678 (parallel [(set (reg:CCZ FLAGS_REG)
e96ccb30
UB
11679 (compare:CCZ
11680 (match_operand:SWI48 1 "nonimmediate_operand" "")
11681 (const_int 0)))
11682 (set (match_operand:SWI48 0 "register_operand" "")
11683 (ctz:SWI48 (match_dup 1)))])
11684 (set (match_dup 0) (if_then_else:SWI48
8bc527af 11685 (eq (reg:CCZ FLAGS_REG) (const_int 0))
8acfdd43
RH
11686 (match_dup 2)
11687 (match_dup 0)))
e96ccb30 11688 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
8bc527af 11689 (clobber (reg:CC FLAGS_REG))])]
e96ccb30
UB
11690 ""
11691{
11692 if (<MODE>mode == SImode && !TARGET_CMOVE)
11693 {
11694 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11695 DONE;
11696 }
11697 operands[2] = gen_reg_rtx (<MODE>mode);
11698})
e0dc26ff 11699
e96ccb30 11700(define_insn_and_split "ffssi2_no_cmove"
3cdf0c62 11701 [(set (match_operand:SI 0 "register_operand" "=r")
8acfdd43 11702 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
fa543fdd 11703 (clobber (match_scratch:SI 2 "=&q"))
8bc527af 11704 (clobber (reg:CC FLAGS_REG))]
08024fb5 11705 "!TARGET_CMOVE"
8acfdd43 11706 "#"
08024fb5
UB
11707 "&& reload_completed"
11708 [(parallel [(set (reg:CCZ FLAGS_REG)
11709 (compare:CCZ (match_dup 1) (const_int 0)))
8acfdd43
RH
11710 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11711 (set (strict_low_part (match_dup 3))
8bc527af 11712 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
8acfdd43 11713 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
8bc527af 11714 (clobber (reg:CC FLAGS_REG))])
8acfdd43 11715 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
8bc527af 11716 (clobber (reg:CC FLAGS_REG))])
8acfdd43 11717 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8bc527af 11718 (clobber (reg:CC FLAGS_REG))])]
8acfdd43
RH
11719{
11720 operands[3] = gen_lowpart (QImode, operands[2]);
707e58b1 11721 ix86_expand_clear (operands[2]);
0f40f9f7 11722})
886c62d1 11723
e96ccb30 11724(define_insn "*ffs<mode>_1"
8bc527af 11725 [(set (reg:CCZ FLAGS_REG)
e96ccb30 11726 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
16189740 11727 (const_int 0)))
e96ccb30
UB
11728 (set (match_operand:SWI48 0 "register_operand" "=r")
11729 (ctz:SWI48 (match_dup 1)))]
8acfdd43 11730 ""
e96ccb30 11731 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
725fd454
JJ
11732 [(set_attr "type" "alu1")
11733 (set_attr "prefix_0f" "1")
e96ccb30 11734 (set_attr "mode" "<MODE>")])
d413e3cc 11735
e96ccb30
UB
11736(define_insn "ctz<mode>2"
11737 [(set (match_operand:SWI48 0 "register_operand" "=r")
11738 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
8bc527af 11739 (clobber (reg:CC FLAGS_REG))]
e075ae69 11740 ""
e96ccb30 11741 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
725fd454
JJ
11742 [(set_attr "type" "alu1")
11743 (set_attr "prefix_0f" "1")
e96ccb30 11744 (set_attr "mode" "<MODE>")])
d413e3cc 11745
e96ccb30 11746(define_expand "clz<mode>2"
8acfdd43 11747 [(parallel
e96ccb30
UB
11748 [(set (match_operand:SWI248 0 "register_operand" "")
11749 (minus:SWI248
11750 (match_dup 2)
11751 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
8bc527af 11752 (clobber (reg:CC FLAGS_REG))])
8acfdd43 11753 (parallel
e96ccb30 11754 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
8bc527af 11755 (clobber (reg:CC FLAGS_REG))])]
8acfdd43 11756 ""
21efb4d4
HJ
11757{
11758 if (TARGET_ABM)
11759 {
e96ccb30 11760 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
21efb4d4
HJ
11761 DONE;
11762 }
e96ccb30 11763 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
21efb4d4
HJ
11764})
11765
e96ccb30
UB
11766(define_insn "clz<mode>2_abm"
11767 [(set (match_operand:SWI248 0 "register_operand" "=r")
11768 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
21efb4d4
HJ
11769 (clobber (reg:CC FLAGS_REG))]
11770 "TARGET_ABM"
e96ccb30 11771 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
21efb4d4
HJ
11772 [(set_attr "prefix_rep" "1")
11773 (set_attr "type" "bitmanip")
e96ccb30
UB
11774 (set_attr "mode" "<MODE>")])
11775
11776(define_insn "bsr_rex64"
11777 [(set (match_operand:DI 0 "register_operand" "=r")
11778 (minus:DI (const_int 63)
11779 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11780 (clobber (reg:CC FLAGS_REG))]
11781 "TARGET_64BIT"
11782 "bsr{q}\t{%1, %0|%0, %1}"
11783 [(set_attr "type" "alu1")
11784 (set_attr "prefix_0f" "1")
11785 (set_attr "mode" "DI")])
8acfdd43 11786
7c45393e 11787(define_insn "bsr"
8acfdd43
RH
11788 [(set (match_operand:SI 0 "register_operand" "=r")
11789 (minus:SI (const_int 31)
11790 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
8bc527af 11791 (clobber (reg:CC FLAGS_REG))]
8acfdd43
RH
11792 ""
11793 "bsr{l}\t{%1, %0|%0, %1}"
725fd454
JJ
11794 [(set_attr "type" "alu1")
11795 (set_attr "prefix_0f" "1")
21efb4d4
HJ
11796 (set_attr "mode" "SI")])
11797
e96ccb30
UB
11798(define_insn "*bsrhi"
11799 [(set (match_operand:HI 0 "register_operand" "=r")
11800 (minus:HI (const_int 15)
11801 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11802 (clobber (reg:CC FLAGS_REG))]
11803 ""
11804 "bsr{w}\t{%1, %0|%0, %1}"
11805 [(set_attr "type" "alu1")
11806 (set_attr "prefix_0f" "1")
11807 (set_attr "mode" "HI")])
11808
a00ce5fe
UB
11809(define_insn "popcount<mode>2"
11810 [(set (match_operand:SWI248 0 "register_operand" "=r")
11811 (popcount:SWI248
11812 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
21efb4d4
HJ
11813 (clobber (reg:CC FLAGS_REG))]
11814 "TARGET_POPCNT"
a00ce5fe
UB
11815{
11816#if TARGET_MACHO
11817 return "popcnt\t{%1, %0|%0, %1}";
11818#else
11819 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11820#endif
11821}
21efb4d4
HJ
11822 [(set_attr "prefix_rep" "1")
11823 (set_attr "type" "bitmanip")
a00ce5fe 11824 (set_attr "mode" "<MODE>")])
21efb4d4 11825
a00ce5fe 11826(define_insn "*popcount<mode>2_cmp"
21efb4d4
HJ
11827 [(set (reg FLAGS_REG)
11828 (compare
a00ce5fe
UB
11829 (popcount:SWI248
11830 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
21efb4d4 11831 (const_int 0)))
a00ce5fe
UB
11832 (set (match_operand:SWI248 0 "register_operand" "=r")
11833 (popcount:SWI248 (match_dup 1)))]
21efb4d4 11834 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
a00ce5fe
UB
11835{
11836#if TARGET_MACHO
11837 return "popcnt\t{%1, %0|%0, %1}";
11838#else
11839 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11840#endif
11841}
21efb4d4
HJ
11842 [(set_attr "prefix_rep" "1")
11843 (set_attr "type" "bitmanip")
a00ce5fe 11844 (set_attr "mode" "<MODE>")])
21efb4d4
HJ
11845
11846(define_insn "*popcountsi2_cmp_zext"
11847 [(set (reg FLAGS_REG)
11848 (compare
11849 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11850 (const_int 0)))
11851 (set (match_operand:DI 0 "register_operand" "=r")
11852 (zero_extend:DI(popcount:SI (match_dup 1))))]
11853 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
a00ce5fe
UB
11854{
11855#if TARGET_MACHO
11856 return "popcnt\t{%1, %0|%0, %1}";
11857#else
0fcbf3ed 11858 return "popcnt{l}\t{%1, %0|%0, %1}";
a00ce5fe
UB
11859#endif
11860}
21efb4d4
HJ
11861 [(set_attr "prefix_rep" "1")
11862 (set_attr "type" "bitmanip")
11863 (set_attr "mode" "SI")])
d413e3cc 11864
2d2d5a91
UB
11865(define_expand "bswap<mode>2"
11866 [(set (match_operand:SWI48 0 "register_operand" "")
11867 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
2e6834d3
RH
11868 ""
11869{
2d2d5a91 11870 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
2e6834d3
RH
11871 {
11872 rtx x = operands[0];
11873
11874 emit_move_insn (x, operands[1]);
11875 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11876 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11877 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11878 DONE;
11879 }
11880})
11881
2d2d5a91
UB
11882(define_insn "*bswap<mode>2_movbe"
11883 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11884 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11885 "TARGET_MOVBE
e96ccb30
UB
11886 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11887 "@
11888 bswap\t%0
11889 movbe\t{%1, %0|%0, %1}
11890 movbe\t{%1, %0|%0, %1}"
2d2d5a91
UB
11891 [(set_attr "type" "bitmanip,imov,imov")
11892 (set_attr "modrm" "0,1,1")
11893 (set_attr "prefix_0f" "*,1,1")
cabf85c3 11894 (set_attr "prefix_extra" "*,1,1")
2d2d5a91 11895 (set_attr "mode" "<MODE>")])
e96ccb30 11896
2d2d5a91
UB
11897(define_insn "*bswap<mode>2_1"
11898 [(set (match_operand:SWI48 0 "register_operand" "=r")
11899 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
6300f037 11900 "TARGET_BSWAP"
2e6834d3 11901 "bswap\t%0"
2d2d5a91
UB
11902 [(set_attr "type" "bitmanip")
11903 (set_attr "modrm" "0")
11904 (set_attr "mode" "<MODE>")])
6300f037 11905
fa681e39
UB
11906(define_insn "*bswaphi_lowpart_1"
11907 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11908 (bswap:HI (match_dup 0)))
11909 (clobber (reg:CC FLAGS_REG))]
3debdc1e 11910 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
fa681e39
UB
11911 "@
11912 xchg{b}\t{%h0, %b0|%b0, %h0}
11913 rol{w}\t{$8, %0|%0, 8}"
11914 [(set_attr "length" "2,4")
11915 (set_attr "mode" "QI,HI")])
11916
2e6834d3 11917(define_insn "bswaphi_lowpart"
fa681e39
UB
11918 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11919 (bswap:HI (match_dup 0)))
11920 (clobber (reg:CC FLAGS_REG))]
2e6834d3 11921 ""
fa681e39
UB
11922 "rol{w}\t{$8, %0|%0, 8}"
11923 [(set_attr "length" "4")
11924 (set_attr "mode" "HI")])
2e6834d3 11925
0f7b6776
UB
11926(define_expand "paritydi2"
11927 [(set (match_operand:DI 0 "register_operand" "")
40cca4f9 11928 (parity:DI (match_operand:DI 1 "register_operand" "")))]
0f7b6776
UB
11929 "! TARGET_POPCNT"
11930{
11931 rtx scratch = gen_reg_rtx (QImode);
11932 rtx cond;
11933
11934 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11935 NULL_RTX, operands[1]));
11936
11937 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11938 gen_rtx_REG (CCmode, FLAGS_REG),
11939 const0_rtx);
11940 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11941
11942 if (TARGET_64BIT)
11943 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11944 else
11945 {
11946 rtx tmp = gen_reg_rtx (SImode);
11947
11948 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11949 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11950 }
11951 DONE;
11952})
11953
e96ccb30
UB
11954(define_expand "paritysi2"
11955 [(set (match_operand:SI 0 "register_operand" "")
11956 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11957 "! TARGET_POPCNT"
11958{
11959 rtx scratch = gen_reg_rtx (QImode);
11960 rtx cond;
11961
11962 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11963
11964 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11965 gen_rtx_REG (CCmode, FLAGS_REG),
11966 const0_rtx);
11967 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11968
11969 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11970 DONE;
11971})
11972
0f7b6776
UB
11973(define_insn_and_split "paritydi2_cmp"
11974 [(set (reg:CC FLAGS_REG)
b79a08f6
UB
11975 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11976 UNSPEC_PARITY))
40cca4f9
UB
11977 (clobber (match_scratch:DI 0 "=r"))
11978 (clobber (match_scratch:SI 1 "=&r"))
11979 (clobber (match_scratch:HI 2 "=Q"))]
0f7b6776
UB
11980 "! TARGET_POPCNT"
11981 "#"
11982 "&& reload_completed"
11983 [(parallel
11984 [(set (match_dup 1)
11985 (xor:SI (match_dup 1) (match_dup 4)))
11986 (clobber (reg:CC FLAGS_REG))])
11987 (parallel
11988 [(set (reg:CC FLAGS_REG)
b79a08f6 11989 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
0f7b6776
UB
11990 (clobber (match_dup 1))
11991 (clobber (match_dup 2))])]
11992{
11993 operands[4] = gen_lowpart (SImode, operands[3]);
11994
40cca4f9 11995 if (TARGET_64BIT)
0f7b6776
UB
11996 {
11997 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11998 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11999 }
40cca4f9
UB
12000 else
12001 operands[1] = gen_highpart (SImode, operands[3]);
0f7b6776
UB
12002})
12003
0f7b6776
UB
12004(define_insn_and_split "paritysi2_cmp"
12005 [(set (reg:CC FLAGS_REG)
b79a08f6
UB
12006 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12007 UNSPEC_PARITY))
40cca4f9
UB
12008 (clobber (match_scratch:SI 0 "=r"))
12009 (clobber (match_scratch:HI 1 "=&Q"))]
0f7b6776
UB
12010 "! TARGET_POPCNT"
12011 "#"
12012 "&& reload_completed"
12013 [(parallel
12014 [(set (match_dup 1)
12015 (xor:HI (match_dup 1) (match_dup 3)))
12016 (clobber (reg:CC FLAGS_REG))])
12017 (parallel
12018 [(set (reg:CC FLAGS_REG)
b79a08f6 12019 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
0f7b6776
UB
12020 (clobber (match_dup 1))])]
12021{
12022 operands[3] = gen_lowpart (HImode, operands[2]);
12023
40cca4f9
UB
12024 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12025 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
0f7b6776
UB
12026})
12027
12028(define_insn "*parityhi2_cmp"
12029 [(set (reg:CC FLAGS_REG)
b79a08f6
UB
12030 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12031 UNSPEC_PARITY))
0f7b6776
UB
12032 (clobber (match_scratch:HI 0 "=Q"))]
12033 "! TARGET_POPCNT"
12034 "xor{b}\t{%h0, %b0|%b0, %h0}"
12035 [(set_attr "length" "2")
12036 (set_attr "mode" "HI")])
e075ae69 12037\f
f996902d
RH
12038;; Thread-local storage patterns for ELF.
12039;;
12040;; Note that these code sequences must appear exactly as shown
12041;; in order to allow linker relaxation.
12042
75d38379 12043(define_insn "*tls_global_dynamic_32_gnu"
f996902d
RH
12044 [(set (match_operand:SI 0 "register_operand" "=a")
12045 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12046 (match_operand:SI 2 "tls_symbolic_operand" "")
12047 (match_operand:SI 3 "call_insn_operand" "")]
12048 UNSPEC_TLS_GD))
12049 (clobber (match_scratch:SI 4 "=d"))
12050 (clobber (match_scratch:SI 5 "=c"))
8bc527af 12051 (clobber (reg:CC FLAGS_REG))]
75d38379 12052 "!TARGET_64BIT && TARGET_GNU_TLS"
f1c26cad 12053 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
f996902d
RH
12054 [(set_attr "type" "multi")
12055 (set_attr "length" "12")])
12056
75d38379 12057(define_expand "tls_global_dynamic_32"
f996902d
RH
12058 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12059 (unspec:SI
12060 [(match_dup 2)
12061 (match_operand:SI 1 "tls_symbolic_operand" "")
12062 (match_dup 3)]
12063 UNSPEC_TLS_GD))
12064 (clobber (match_scratch:SI 4 ""))
12065 (clobber (match_scratch:SI 5 ""))
8bc527af 12066 (clobber (reg:CC FLAGS_REG))])]
f996902d
RH
12067 ""
12068{
dce81a1a
JJ
12069 if (flag_pic)
12070 operands[2] = pic_offset_table_rtx;
12071 else
12072 {
12073 operands[2] = gen_reg_rtx (Pmode);
12074 emit_insn (gen_set_got (operands[2]));
12075 }
5bf5a10b
AO
12076 if (TARGET_GNU2_TLS)
12077 {
12078 emit_insn (gen_tls_dynamic_gnu2_32
12079 (operands[0], operands[1], operands[2]));
12080 DONE;
12081 }
f996902d
RH
12082 operands[3] = ix86_tls_get_addr ();
12083})
12084
75d38379
JJ
12085(define_insn "*tls_global_dynamic_64"
12086 [(set (match_operand:DI 0 "register_operand" "=a")
e347ff9e
AO
12087 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12088 (match_operand:DI 3 "" "")))
75d38379
JJ
12089 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12090 UNSPEC_TLS_GD)]
12091 "TARGET_64BIT"
f1c26cad 12092 { 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"; }
75d38379
JJ
12093 [(set_attr "type" "multi")
12094 (set_attr "length" "16")])
12095
12096(define_expand "tls_global_dynamic_64"
12097 [(parallel [(set (match_operand:DI 0 "register_operand" "")
e347ff9e 12098 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
75d38379
JJ
12099 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12100 UNSPEC_TLS_GD)])]
12101 ""
12102{
5bf5a10b
AO
12103 if (TARGET_GNU2_TLS)
12104 {
12105 emit_insn (gen_tls_dynamic_gnu2_64
12106 (operands[0], operands[1]));
12107 DONE;
12108 }
75d38379
JJ
12109 operands[2] = ix86_tls_get_addr ();
12110})
12111
12112(define_insn "*tls_local_dynamic_base_32_gnu"
f996902d
RH
12113 [(set (match_operand:SI 0 "register_operand" "=a")
12114 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12115 (match_operand:SI 2 "call_insn_operand" "")]
12116 UNSPEC_TLS_LD_BASE))
12117 (clobber (match_scratch:SI 3 "=d"))
12118 (clobber (match_scratch:SI 4 "=c"))
8bc527af 12119 (clobber (reg:CC FLAGS_REG))]
75d38379 12120 "!TARGET_64BIT && TARGET_GNU_TLS"
f1c26cad 12121 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
f996902d
RH
12122 [(set_attr "type" "multi")
12123 (set_attr "length" "11")])
12124
75d38379 12125(define_expand "tls_local_dynamic_base_32"
f996902d
RH
12126 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12127 (unspec:SI [(match_dup 1) (match_dup 2)]
12128 UNSPEC_TLS_LD_BASE))
12129 (clobber (match_scratch:SI 3 ""))
12130 (clobber (match_scratch:SI 4 ""))
8bc527af 12131 (clobber (reg:CC FLAGS_REG))])]
f996902d
RH
12132 ""
12133{
dce81a1a 12134 if (flag_pic)
9785f1d9 12135 operands[1] = pic_offset_table_rtx;
dce81a1a
JJ
12136 else
12137 {
9785f1d9
JJ
12138 operands[1] = gen_reg_rtx (Pmode);
12139 emit_insn (gen_set_got (operands[1]));
dce81a1a 12140 }
5bf5a10b
AO
12141 if (TARGET_GNU2_TLS)
12142 {
12143 emit_insn (gen_tls_dynamic_gnu2_32
12144 (operands[0], ix86_tls_module_base (), operands[1]));
12145 DONE;
12146 }
f996902d
RH
12147 operands[2] = ix86_tls_get_addr ();
12148})
12149
75d38379
JJ
12150(define_insn "*tls_local_dynamic_base_64"
12151 [(set (match_operand:DI 0 "register_operand" "=a")
e347ff9e
AO
12152 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12153 (match_operand:DI 2 "" "")))
75d38379
JJ
12154 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12155 "TARGET_64BIT"
f1c26cad 12156 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
75d38379
JJ
12157 [(set_attr "type" "multi")
12158 (set_attr "length" "12")])
12159
12160(define_expand "tls_local_dynamic_base_64"
12161 [(parallel [(set (match_operand:DI 0 "register_operand" "")
e347ff9e 12162 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
75d38379
JJ
12163 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12164 ""
12165{
5bf5a10b
AO
12166 if (TARGET_GNU2_TLS)
12167 {
12168 emit_insn (gen_tls_dynamic_gnu2_64
12169 (operands[0], ix86_tls_module_base ()));
12170 DONE;
12171 }
75d38379
JJ
12172 operands[1] = ix86_tls_get_addr ();
12173})
12174
f996902d
RH
12175;; Local dynamic of a single variable is a lose. Show combine how
12176;; to convert that back to global dynamic.
12177
75d38379 12178(define_insn_and_split "*tls_local_dynamic_32_once"
f996902d
RH
12179 [(set (match_operand:SI 0 "register_operand" "=a")
12180 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12181 (match_operand:SI 2 "call_insn_operand" "")]
12182 UNSPEC_TLS_LD_BASE)
12183 (const:SI (unspec:SI
12184 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12185 UNSPEC_DTPOFF))))
12186 (clobber (match_scratch:SI 4 "=d"))
12187 (clobber (match_scratch:SI 5 "=c"))
8bc527af 12188 (clobber (reg:CC FLAGS_REG))]
f996902d
RH
12189 ""
12190 "#"
12191 ""
12192 [(parallel [(set (match_dup 0)
12193 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12194 UNSPEC_TLS_GD))
12195 (clobber (match_dup 4))
12196 (clobber (match_dup 5))
a427621f 12197 (clobber (reg:CC FLAGS_REG))])])
74dc3e94 12198
d1e74401
UB
12199;; Segment register for the thread base ptr load
12200(define_mode_attr tp_seg [(SI "gs") (DI "fs")])
74dc3e94 12201
d1e74401
UB
12202;; Load and add the thread base pointer from %gs:0.
12203(define_insn "*load_tp_<mode>"
12204 [(set (match_operand:P 0 "register_operand" "=r")
12205 (unspec:P [(const_int 0)] UNSPEC_TP))]
12206 ""
12207 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
74dc3e94
RH
12208 [(set_attr "type" "imov")
12209 (set_attr "modrm" "0")
12210 (set_attr "length" "7")
12211 (set_attr "memory" "load")
12212 (set_attr "imm_disp" "false")])
12213
d1e74401
UB
12214(define_insn "*add_tp_<mode>"
12215 [(set (match_operand:P 0 "register_operand" "=r")
12216 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12217 (match_operand:P 1 "register_operand" "0")))
8bc527af 12218 (clobber (reg:CC FLAGS_REG))]
d1e74401
UB
12219 ""
12220 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
74dc3e94
RH
12221 [(set_attr "type" "alu")
12222 (set_attr "modrm" "0")
12223 (set_attr "length" "7")
12224 (set_attr "memory" "load")
12225 (set_attr "imm_disp" "false")])
5bf5a10b
AO
12226
12227;; GNU2 TLS patterns can be split.
12228
12229(define_expand "tls_dynamic_gnu2_32"
12230 [(set (match_dup 3)
12231 (plus:SI (match_operand:SI 2 "register_operand" "")
12232 (const:SI
12233 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12234 UNSPEC_TLSDESC))))
12235 (parallel
12236 [(set (match_operand:SI 0 "register_operand" "")
12237 (unspec:SI [(match_dup 1) (match_dup 3)
12238 (match_dup 2) (reg:SI SP_REG)]
12239 UNSPEC_TLSDESC))
12240 (clobber (reg:CC FLAGS_REG))])]
12241 "!TARGET_64BIT && TARGET_GNU2_TLS"
12242{
5071eab7 12243 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
5bf5a10b
AO
12244 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12245})
12246
12247(define_insn "*tls_dynamic_lea_32"
12248 [(set (match_operand:SI 0 "register_operand" "=r")
12249 (plus:SI (match_operand:SI 1 "register_operand" "b")
12250 (const:SI
12251 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12252 UNSPEC_TLSDESC))))]
12253 "!TARGET_64BIT && TARGET_GNU2_TLS"
12254 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12255 [(set_attr "type" "lea")
12256 (set_attr "mode" "SI")
12257 (set_attr "length" "6")
12258 (set_attr "length_address" "4")])
12259
12260(define_insn "*tls_dynamic_call_32"
12261 [(set (match_operand:SI 0 "register_operand" "=a")
12262 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12263 (match_operand:SI 2 "register_operand" "0")
12264 ;; we have to make sure %ebx still points to the GOT
12265 (match_operand:SI 3 "register_operand" "b")
12266 (reg:SI SP_REG)]
12267 UNSPEC_TLSDESC))
12268 (clobber (reg:CC FLAGS_REG))]
12269 "!TARGET_64BIT && TARGET_GNU2_TLS"
12270 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12271 [(set_attr "type" "call")
12272 (set_attr "length" "2")
12273 (set_attr "length_address" "0")])
12274
12275(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12276 [(set (match_operand:SI 0 "register_operand" "=&a")
12277 (plus:SI
31ebc801
AO
12278 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12279 (match_operand:SI 4 "" "")
12280 (match_operand:SI 2 "register_operand" "b")
12281 (reg:SI SP_REG)]
12282 UNSPEC_TLSDESC)
5bf5a10b
AO
12283 (const:SI (unspec:SI
12284 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12285 UNSPEC_DTPOFF))))
12286 (clobber (reg:CC FLAGS_REG))]
12287 "!TARGET_64BIT && TARGET_GNU2_TLS"
12288 "#"
12289 ""
31ebc801 12290 [(set (match_dup 0) (match_dup 5))]
5bf5a10b 12291{
5071eab7 12292 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
5bf5a10b
AO
12293 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12294})
12295
12296(define_expand "tls_dynamic_gnu2_64"
12297 [(set (match_dup 2)
12298 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12299 UNSPEC_TLSDESC))
12300 (parallel
12301 [(set (match_operand:DI 0 "register_operand" "")
12302 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12303 UNSPEC_TLSDESC))
12304 (clobber (reg:CC FLAGS_REG))])]
12305 "TARGET_64BIT && TARGET_GNU2_TLS"
12306{
5071eab7 12307 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
5bf5a10b
AO
12308 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12309})
12310
12311(define_insn "*tls_dynamic_lea_64"
12312 [(set (match_operand:DI 0 "register_operand" "=r")
12313 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12314 UNSPEC_TLSDESC))]
12315 "TARGET_64BIT && TARGET_GNU2_TLS"
9ad5e54f 12316 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
5bf5a10b
AO
12317 [(set_attr "type" "lea")
12318 (set_attr "mode" "DI")
12319 (set_attr "length" "7")
12320 (set_attr "length_address" "4")])
12321
12322(define_insn "*tls_dynamic_call_64"
12323 [(set (match_operand:DI 0 "register_operand" "=a")
12324 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12325 (match_operand:DI 2 "register_operand" "0")
12326 (reg:DI SP_REG)]
12327 UNSPEC_TLSDESC))
12328 (clobber (reg:CC FLAGS_REG))]
12329 "TARGET_64BIT && TARGET_GNU2_TLS"
12330 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12331 [(set_attr "type" "call")
12332 (set_attr "length" "2")
12333 (set_attr "length_address" "0")])
12334
12335(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12336 [(set (match_operand:DI 0 "register_operand" "=&a")
12337 (plus:DI
31ebc801
AO
12338 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12339 (match_operand:DI 3 "" "")
12340 (reg:DI SP_REG)]
12341 UNSPEC_TLSDESC)
5bf5a10b
AO
12342 (const:DI (unspec:DI
12343 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12344 UNSPEC_DTPOFF))))
12345 (clobber (reg:CC FLAGS_REG))]
12346 "TARGET_64BIT && TARGET_GNU2_TLS"
12347 "#"
12348 ""
31ebc801 12349 [(set (match_dup 0) (match_dup 4))]
5bf5a10b 12350{
5071eab7 12351 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
5bf5a10b
AO
12352 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12353})
f996902d 12354\f
e075ae69
RH
12355;; These patterns match the binary 387 instructions for addM3, subM3,
12356;; mulM3 and divM3. There are three patterns for each of DFmode and
12357;; SFmode. The first is the normal insn, the second the same insn but
12358;; with one operand a conversion, and the third the same insn but with
12359;; the other operand a conversion. The conversion may be SFmode or
12360;; SImode if the target mode DFmode, but only SImode if the target mode
12361;; is SFmode.
12362
caa6ec8d
JH
12363;; Gcc is slightly more smart about handling normal two address instructions
12364;; so use special patterns for add and mull.
965f5423 12365
95879c72
L
12366(define_insn "*fop_<mode>_comm_mixed_avx"
12367 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12368 (match_operator:MODEF 3 "binary_fp_operator"
12369 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12370 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12371 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12372 && COMMUTATIVE_ARITH_P (operands[3])
12373 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12374 "* return output_387_binary_op (insn, operands);"
12375 [(set (attr "type")
12376 (if_then_else (eq_attr "alternative" "1")
12377 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12378 (const_string "ssemul")
12379 (const_string "sseadd"))
12380 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12381 (const_string "fmul")
12382 (const_string "fop"))))
12383 (set_attr "prefix" "orig,maybe_vex")
12384 (set_attr "mode" "<MODE>")])
12385
ca3a2165
UB
12386(define_insn "*fop_<mode>_comm_mixed"
12387 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12388 (match_operator:MODEF 3 "binary_fp_operator"
12389 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12390 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12391 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
ec8e098d 12392 && COMMUTATIVE_ARITH_P (operands[3])
7656aee4 12393 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
caa6ec8d 12394 "* return output_387_binary_op (insn, operands);"
6300f037 12395 [(set (attr "type")
1deaa899 12396 (if_then_else (eq_attr "alternative" "1")
ca3a2165 12397 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
3d34cd91
JH
12398 (const_string "ssemul")
12399 (const_string "sseadd"))
ca3a2165 12400 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
1deaa899
JH
12401 (const_string "fmul")
12402 (const_string "fop"))))
ca3a2165 12403 (set_attr "mode" "<MODE>")])
1deaa899 12404
95879c72
L
12405(define_insn "*fop_<mode>_comm_avx"
12406 [(set (match_operand:MODEF 0 "register_operand" "=x")
12407 (match_operator:MODEF 3 "binary_fp_operator"
12408 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12409 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12410 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12411 && COMMUTATIVE_ARITH_P (operands[3])
12412 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12413 "* return output_387_binary_op (insn, operands);"
12414 [(set (attr "type")
12415 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12416 (const_string "ssemul")
12417 (const_string "sseadd")))
12418 (set_attr "prefix" "vex")
12419 (set_attr "mode" "<MODE>")])
12420
ca3a2165
UB
12421(define_insn "*fop_<mode>_comm_sse"
12422 [(set (match_operand:MODEF 0 "register_operand" "=x")
12423 (match_operator:MODEF 3 "binary_fp_operator"
12424 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12425 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12426 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
cfa185b8 12427 && COMMUTATIVE_ARITH_P (operands[3])
7656aee4 12428 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
1deaa899 12429 "* return output_387_binary_op (insn, operands);"
6300f037 12430 [(set (attr "type")
ca3a2165 12431 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
3d34cd91
JH
12432 (const_string "ssemul")
12433 (const_string "sseadd")))
ca3a2165 12434 (set_attr "mode" "<MODE>")])
caa6ec8d 12435
ca3a2165
UB
12436(define_insn "*fop_<mode>_comm_i387"
12437 [(set (match_operand:MODEF 0 "register_operand" "=f")
12438 (match_operator:MODEF 3 "binary_fp_operator"
12439 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12440 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
8ce94e44 12441 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
ec8e098d 12442 && COMMUTATIVE_ARITH_P (operands[3])
7656aee4 12443 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
965f5423 12444 "* return output_387_binary_op (insn, operands);"
6300f037 12445 [(set (attr "type")
ca3a2165 12446 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
965f5423
JH
12447 (const_string "fmul")
12448 (const_string "fop")))
ca3a2165 12449 (set_attr "mode" "<MODE>")])
965f5423 12450
95879c72
L
12451(define_insn "*fop_<mode>_1_mixed_avx"
12452 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12453 (match_operator:MODEF 3 "binary_fp_operator"
12454 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12455 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12456 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12457 && !COMMUTATIVE_ARITH_P (operands[3])
12458 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12459 "* return output_387_binary_op (insn, operands);"
12460 [(set (attr "type")
12461 (cond [(and (eq_attr "alternative" "2")
12462 (match_operand:MODEF 3 "mult_operator" ""))
12463 (const_string "ssemul")
12464 (and (eq_attr "alternative" "2")
12465 (match_operand:MODEF 3 "div_operator" ""))
12466 (const_string "ssediv")
12467 (eq_attr "alternative" "2")
12468 (const_string "sseadd")
12469 (match_operand:MODEF 3 "mult_operator" "")
12470 (const_string "fmul")
12471 (match_operand:MODEF 3 "div_operator" "")
12472 (const_string "fdiv")
12473 ]
12474 (const_string "fop")))
12475 (set_attr "prefix" "orig,orig,maybe_vex")
12476 (set_attr "mode" "<MODE>")])
12477
ca3a2165
UB
12478(define_insn "*fop_<mode>_1_mixed"
12479 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12480 (match_operator:MODEF 3 "binary_fp_operator"
12481 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12482 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12483 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
ec8e098d 12484 && !COMMUTATIVE_ARITH_P (operands[3])
7656aee4 12485 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
e075ae69 12486 "* return output_387_binary_op (insn, operands);"
6300f037 12487 [(set (attr "type")
3d34cd91 12488 (cond [(and (eq_attr "alternative" "2")
ca3a2165 12489 (match_operand:MODEF 3 "mult_operator" ""))
3d34cd91
JH
12490 (const_string "ssemul")
12491 (and (eq_attr "alternative" "2")
ca3a2165 12492 (match_operand:MODEF 3 "div_operator" ""))
3d34cd91
JH
12493 (const_string "ssediv")
12494 (eq_attr "alternative" "2")
12495 (const_string "sseadd")
ca3a2165 12496 (match_operand:MODEF 3 "mult_operator" "")
e075ae69 12497 (const_string "fmul")
ca3a2165 12498 (match_operand:MODEF 3 "div_operator" "")
e075ae69
RH
12499 (const_string "fdiv")
12500 ]
6ef67412 12501 (const_string "fop")))
ca3a2165 12502 (set_attr "mode" "<MODE>")])
e075ae69 12503
6b889d89
UB
12504(define_insn "*rcpsf2_sse"
12505 [(set (match_operand:SF 0 "register_operand" "=x")
12506 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12507 UNSPEC_RCP))]
12508 "TARGET_SSE_MATH"
95879c72 12509 "%vrcpss\t{%1, %d0|%d0, %1}"
6b889d89 12510 [(set_attr "type" "sse")
b6837b94 12511 (set_attr "atom_sse_attr" "rcp")
95879c72 12512 (set_attr "prefix" "maybe_vex")
6b889d89
UB
12513 (set_attr "mode" "SF")])
12514
95879c72
L
12515(define_insn "*fop_<mode>_1_avx"
12516 [(set (match_operand:MODEF 0 "register_operand" "=x")
12517 (match_operator:MODEF 3 "binary_fp_operator"
12518 [(match_operand:MODEF 1 "register_operand" "x")
12519 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12520 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12521 && !COMMUTATIVE_ARITH_P (operands[3])"
12522 "* return output_387_binary_op (insn, operands);"
12523 [(set (attr "type")
12524 (cond [(match_operand:MODEF 3 "mult_operator" "")
12525 (const_string "ssemul")
12526 (match_operand:MODEF 3 "div_operator" "")
12527 (const_string "ssediv")
12528 ]
12529 (const_string "sseadd")))
12530 (set_attr "prefix" "vex")
12531 (set_attr "mode" "<MODE>")])
12532
ca3a2165
UB
12533(define_insn "*fop_<mode>_1_sse"
12534 [(set (match_operand:MODEF 0 "register_operand" "=x")
12535 (match_operator:MODEF 3 "binary_fp_operator"
12536 [(match_operand:MODEF 1 "register_operand" "0")
12537 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12538 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
ec8e098d 12539 && !COMMUTATIVE_ARITH_P (operands[3])"
1deaa899 12540 "* return output_387_binary_op (insn, operands);"
6300f037 12541 [(set (attr "type")
ca3a2165 12542 (cond [(match_operand:MODEF 3 "mult_operator" "")
3d34cd91 12543 (const_string "ssemul")
ca3a2165 12544 (match_operand:MODEF 3 "div_operator" "")
3d34cd91
JH
12545 (const_string "ssediv")
12546 ]
12547 (const_string "sseadd")))
ca3a2165 12548 (set_attr "mode" "<MODE>")])
1deaa899 12549
9e4ae64b 12550;; This pattern is not fully shadowed by the pattern above.
ca3a2165
UB
12551(define_insn "*fop_<mode>_1_i387"
12552 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12553 (match_operator:MODEF 3 "binary_fp_operator"
12554 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12555 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
8ce94e44
JM
12556 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12557 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
cfa185b8 12558 && !COMMUTATIVE_ARITH_P (operands[3])
7656aee4 12559 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
cfa185b8 12560 "* return output_387_binary_op (insn, operands);"
6300f037 12561 [(set (attr "type")
ca3a2165 12562 (cond [(match_operand:MODEF 3 "mult_operator" "")
cfa185b8 12563 (const_string "fmul")
ca3a2165 12564 (match_operand:MODEF 3 "div_operator" "")
cfa185b8
UB
12565 (const_string "fdiv")
12566 ]
12567 (const_string "fop")))
0e8c2b0d 12568 (set_attr "mode" "<MODE>")])
e075ae69 12569
1deaa899 12570;; ??? Add SSE splitters for these!
ca3a2165
UB
12571(define_insn "*fop_<MODEF:mode>_2_i387"
12572 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12573 (match_operator:MODEF 3 "binary_fp_operator"
12574 [(float:MODEF
12575 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12576 (match_operand:MODEF 2 "register_operand" "0,0")]))]
8ce94e44
JM
12577 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12578 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
3debdc1e 12579 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
e075ae69 12580 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
6300f037 12581 [(set (attr "type")
ca3a2165 12582 (cond [(match_operand:MODEF 3 "mult_operator" "")
e075ae69 12583 (const_string "fmul")
ca3a2165 12584 (match_operand:MODEF 3 "div_operator" "")
e075ae69
RH
12585 (const_string "fdiv")
12586 ]
12587 (const_string "fop")))
12588 (set_attr "fp_int_src" "true")
ca3a2165
UB
12589 (set_attr "mode" "<X87MODEI12:MODE>")])
12590
12591(define_insn "*fop_<MODEF:mode>_3_i387"
12592 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12593 (match_operator:MODEF 3 "binary_fp_operator"
12594 [(match_operand:MODEF 1 "register_operand" "0,0")
12595 (float:MODEF
12596 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
8ce94e44
JM
12597 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12598 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
3debdc1e 12599 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
e075ae69 12600 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
6300f037 12601 [(set (attr "type")
ca3a2165 12602 (cond [(match_operand:MODEF 3 "mult_operator" "")
e075ae69 12603 (const_string "fmul")
ca3a2165 12604 (match_operand:MODEF 3 "div_operator" "")
e075ae69
RH
12605 (const_string "fdiv")
12606 ]
12607 (const_string "fop")))
12608 (set_attr "fp_int_src" "true")
0e8c2b0d 12609 (set_attr "mode" "<MODE>")])
e075ae69 12610
cfa185b8 12611(define_insn "*fop_df_4_i387"
e075ae69
RH
12612 [(set (match_operand:DF 0 "register_operand" "=f,f")
12613 (match_operator:DF 3 "binary_fp_operator"
69002843
UB
12614 [(float_extend:DF
12615 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
e075ae69 12616 (match_operand:DF 2 "register_operand" "0,f")]))]
8ce94e44
JM
12617 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12618 && !(TARGET_SSE2 && TARGET_SSE_MATH)
7656aee4 12619 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
e075ae69 12620 "* return output_387_binary_op (insn, operands);"
6300f037
EC
12621 [(set (attr "type")
12622 (cond [(match_operand:DF 3 "mult_operator" "")
e075ae69 12623 (const_string "fmul")
6300f037 12624 (match_operand:DF 3 "div_operator" "")
e075ae69
RH
12625 (const_string "fdiv")
12626 ]
6ef67412
JH
12627 (const_string "fop")))
12628 (set_attr "mode" "SF")])
e075ae69 12629
cfa185b8 12630(define_insn "*fop_df_5_i387"
e075ae69
RH
12631 [(set (match_operand:DF 0 "register_operand" "=f,f")
12632 (match_operator:DF 3 "binary_fp_operator"
12633 [(match_operand:DF 1 "register_operand" "0,f")
12634 (float_extend:DF
12635 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
8ce94e44
JM
12636 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12637 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
e075ae69 12638 "* return output_387_binary_op (insn, operands);"
6300f037
EC
12639 [(set (attr "type")
12640 (cond [(match_operand:DF 3 "mult_operator" "")
e075ae69 12641 (const_string "fmul")
6300f037 12642 (match_operand:DF 3 "div_operator" "")
e075ae69
RH
12643 (const_string "fdiv")
12644 ]
6ef67412
JH
12645 (const_string "fop")))
12646 (set_attr "mode" "SF")])
e075ae69 12647
cfa185b8 12648(define_insn "*fop_df_6_i387"
4977bab6
ZW
12649 [(set (match_operand:DF 0 "register_operand" "=f,f")
12650 (match_operator:DF 3 "binary_fp_operator"
12651 [(float_extend:DF
12652 (match_operand:SF 1 "register_operand" "0,f"))
12653 (float_extend:DF
12654 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
8ce94e44
JM
12655 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12656 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
4977bab6 12657 "* return output_387_binary_op (insn, operands);"
6300f037
EC
12658 [(set (attr "type")
12659 (cond [(match_operand:DF 3 "mult_operator" "")
4977bab6 12660 (const_string "fmul")
6300f037 12661 (match_operand:DF 3 "div_operator" "")
4977bab6
ZW
12662 (const_string "fdiv")
12663 ]
12664 (const_string "fop")))
12665 (set_attr "mode" "SF")])
12666
cfa185b8
UB
12667(define_insn "*fop_xf_comm_i387"
12668 [(set (match_operand:XF 0 "register_operand" "=f")
12669 (match_operator:XF 3 "binary_fp_operator"
12670 [(match_operand:XF 1 "register_operand" "%0")
12671 (match_operand:XF 2 "register_operand" "f")]))]
12672 "TARGET_80387
12673 && COMMUTATIVE_ARITH_P (operands[3])"
12674 "* return output_387_binary_op (insn, operands);"
6300f037
EC
12675 [(set (attr "type")
12676 (if_then_else (match_operand:XF 3 "mult_operator" "")
cfa185b8
UB
12677 (const_string "fmul")
12678 (const_string "fop")))
12679 (set_attr "mode" "XF")])
12680
12681(define_insn "*fop_xf_1_i387"
e075ae69
RH
12682 [(set (match_operand:XF 0 "register_operand" "=f,f")
12683 (match_operator:XF 3 "binary_fp_operator"
12684 [(match_operand:XF 1 "register_operand" "0,f")
12685 (match_operand:XF 2 "register_operand" "f,0")]))]
f8a1ebc6 12686 "TARGET_80387
ec8e098d 12687 && !COMMUTATIVE_ARITH_P (operands[3])"
e075ae69 12688 "* return output_387_binary_op (insn, operands);"
6300f037
EC
12689 [(set (attr "type")
12690 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 12691 (const_string "fmul")
6300f037 12692 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
12693 (const_string "fdiv")
12694 ]
6ef67412
JH
12695 (const_string "fop")))
12696 (set_attr "mode" "XF")])
e075ae69 12697
ca3a2165 12698(define_insn "*fop_xf_2_i387"
e075ae69
RH
12699 [(set (match_operand:XF 0 "register_operand" "=f,f")
12700 (match_operator:XF 3 "binary_fp_operator"
ca3a2165
UB
12701 [(float:XF
12702 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12703 (match_operand:XF 2 "register_operand" "0,0")]))]
3debdc1e 12704 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
2b589241 12705 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
6300f037
EC
12706 [(set (attr "type")
12707 (cond [(match_operand:XF 3 "mult_operator" "")
2b589241 12708 (const_string "fmul")
6300f037 12709 (match_operand:XF 3 "div_operator" "")
2b589241
JH
12710 (const_string "fdiv")
12711 ]
12712 (const_string "fop")))
12713 (set_attr "fp_int_src" "true")
0e8c2b0d 12714 (set_attr "mode" "<MODE>")])
2b589241 12715
ca3a2165 12716(define_insn "*fop_xf_3_i387"
e075ae69
RH
12717 [(set (match_operand:XF 0 "register_operand" "=f,f")
12718 (match_operator:XF 3 "binary_fp_operator"
12719 [(match_operand:XF 1 "register_operand" "0,0")
ca3a2165
UB
12720 (float:XF
12721 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
3debdc1e 12722 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
e075ae69 12723 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
6300f037
EC
12724 [(set (attr "type")
12725 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 12726 (const_string "fmul")
6300f037 12727 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
12728 (const_string "fdiv")
12729 ]
12730 (const_string "fop")))
12731 (set_attr "fp_int_src" "true")
0e8c2b0d 12732 (set_attr "mode" "<MODE>")])
e075ae69 12733
cfa185b8 12734(define_insn "*fop_xf_4_i387"
e075ae69
RH
12735 [(set (match_operand:XF 0 "register_operand" "=f,f")
12736 (match_operator:XF 3 "binary_fp_operator"
8002331e 12737 [(float_extend:XF
00188daa 12738 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
e075ae69 12739 (match_operand:XF 2 "register_operand" "0,f")]))]
f8a1ebc6 12740 "TARGET_80387"
e075ae69 12741 "* return output_387_binary_op (insn, operands);"
6300f037
EC
12742 [(set (attr "type")
12743 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 12744 (const_string "fmul")
6300f037 12745 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
12746 (const_string "fdiv")
12747 ]
6ef67412 12748 (const_string "fop")))
ca3a2165 12749 (set_attr "mode" "<MODE>")])
e075ae69 12750
cfa185b8 12751(define_insn "*fop_xf_5_i387"
e075ae69
RH
12752 [(set (match_operand:XF 0 "register_operand" "=f,f")
12753 (match_operator:XF 3 "binary_fp_operator"
12754 [(match_operand:XF 1 "register_operand" "0,f")
12755 (float_extend:XF
00188daa 12756 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
f8a1ebc6 12757 "TARGET_80387"
e075ae69 12758 "* return output_387_binary_op (insn, operands);"
6300f037
EC
12759 [(set (attr "type")
12760 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 12761 (const_string "fmul")
6300f037 12762 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
12763 (const_string "fdiv")
12764 ]
6ef67412 12765 (const_string "fop")))
ca3a2165 12766 (set_attr "mode" "<MODE>")])
e075ae69 12767
cfa185b8 12768(define_insn "*fop_xf_6_i387"
e075ae69
RH
12769 [(set (match_operand:XF 0 "register_operand" "=f,f")
12770 (match_operator:XF 3 "binary_fp_operator"
4977bab6 12771 [(float_extend:XF
00188daa 12772 (match_operand:MODEF 1 "register_operand" "0,f"))
e075ae69 12773 (float_extend:XF
00188daa 12774 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
f8a1ebc6 12775 "TARGET_80387"
e075ae69 12776 "* return output_387_binary_op (insn, operands);"
6300f037
EC
12777 [(set (attr "type")
12778 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 12779 (const_string "fmul")
6300f037 12780 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
12781 (const_string "fdiv")
12782 ]
6ef67412 12783 (const_string "fop")))
ca3a2165 12784 (set_attr "mode" "<MODE>")])
e075ae69
RH
12785
12786(define_split
12787 [(set (match_operand 0 "register_operand" "")
12788 (match_operator 3 "binary_fp_operator"
0e8c2b0d 12789 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
e075ae69 12790 (match_operand 2 "register_operand" "")]))]
27ac40e2 12791 "reload_completed
8ce94e44
JM
12792 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12793 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
4211a8fb 12794 [(const_int 0)]
6300f037 12795{
4211a8fb
JH
12796 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12797 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12798 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12799 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12800 GET_MODE (operands[3]),
12801 operands[4],
12802 operands[2])));
12803 ix86_free_from_memory (GET_MODE (operands[1]));
12804 DONE;
0f40f9f7 12805})
e075ae69
RH
12806
12807(define_split
12808 [(set (match_operand 0 "register_operand" "")
12809 (match_operator 3 "binary_fp_operator"
12810 [(match_operand 1 "register_operand" "")
0e8c2b0d 12811 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
27ac40e2 12812 "reload_completed
8ce94e44
JM
12813 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12814 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
4211a8fb 12815 [(const_int 0)]
4211a8fb
JH
12816{
12817 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12818 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12819 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2b66da3c 12820 gen_rtx_fmt_ee (GET_CODE (operands[3]),
4211a8fb
JH
12821 GET_MODE (operands[3]),
12822 operands[1],
12823 operands[4])));
12824 ix86_free_from_memory (GET_MODE (operands[2]));
12825 DONE;
0f40f9f7 12826})
e075ae69
RH
12827\f
12828;; FPU special functions.
12829
01302104
UB
12830;; This pattern implements a no-op XFmode truncation for
12831;; all fancy i386 XFmode math functions.
a8083431 12832
01302104 12833(define_insn "truncxf<mode>2_i387_noop_unspec"
00188daa
UB
12834 [(set (match_operand:MODEF 0 "register_operand" "=f")
12835 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
01302104 12836 UNSPEC_TRUNC_NOOP))]
22b768d4 12837 "TARGET_USE_FANCY_MATH_387"
01302104
UB
12838 "* return output_387_reg_move (insn, operands);"
12839 [(set_attr "type" "fmov")
12840 (set_attr "mode" "<MODE>")])
e075ae69
RH
12841
12842(define_insn "sqrtxf2"
12843 [(set (match_operand:XF 0 "register_operand" "=f")
12844 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
5a4171a0 12845 "TARGET_USE_FANCY_MATH_387"
2b589241
JH
12846 "fsqrt"
12847 [(set_attr "type" "fpspc")
12848 (set_attr "mode" "XF")
21efb4d4
HJ
12849 (set_attr "athlon_decode" "direct")
12850 (set_attr "amdfam10_decode" "direct")])
2b589241 12851
786f159e 12852(define_insn "sqrt_extend<mode>xf2_i387"
e075ae69 12853 [(set (match_operand:XF 0 "register_operand" "=f")
01302104
UB
12854 (sqrt:XF
12855 (float_extend:XF
00188daa 12856 (match_operand:MODEF 1 "register_operand" "0"))))]
ba2baa55 12857 "TARGET_USE_FANCY_MATH_387"
2b589241
JH
12858 "fsqrt"
12859 [(set_attr "type" "fpspc")
12860 (set_attr "mode" "XF")
4f3f76e6 12861 (set_attr "athlon_decode" "direct")
21efb4d4 12862 (set_attr "amdfam10_decode" "direct")])
2b589241 12863
6b889d89
UB
12864(define_insn "*rsqrtsf2_sse"
12865 [(set (match_operand:SF 0 "register_operand" "=x")
12866 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12867 UNSPEC_RSQRT))]
12868 "TARGET_SSE_MATH"
95879c72 12869 "%vrsqrtss\t{%1, %d0|%d0, %1}"
6b889d89 12870 [(set_attr "type" "sse")
b6837b94 12871 (set_attr "atom_sse_attr" "rcp")
95879c72 12872 (set_attr "prefix" "maybe_vex")
6b889d89
UB
12873 (set_attr "mode" "SF")])
12874
12875(define_expand "rsqrtsf2"
00188daa
UB
12876 [(set (match_operand:SF 0 "register_operand" "")
12877 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
6b889d89 12878 UNSPEC_RSQRT))]
f1bf33ce 12879 "TARGET_SSE_MATH"
6b889d89
UB
12880{
12881 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12882 DONE;
12883})
12884
01302104 12885(define_insn "*sqrt<mode>2_sse"
00188daa
UB
12886 [(set (match_operand:MODEF 0 "register_operand" "=x")
12887 (sqrt:MODEF
12888 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
01302104 12889 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
95879c72 12890 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
01302104 12891 [(set_attr "type" "sse")
b6837b94 12892 (set_attr "atom_sse_attr" "sqrt")
95879c72 12893 (set_attr "prefix" "maybe_vex")
01302104 12894 (set_attr "mode" "<MODE>")
21efb4d4
HJ
12895 (set_attr "athlon_decode" "*")
12896 (set_attr "amdfam10_decode" "*")])
01302104
UB
12897
12898(define_expand "sqrt<mode>2"
00188daa
UB
12899 [(set (match_operand:MODEF 0 "register_operand" "")
12900 (sqrt:MODEF
12901 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
8ce94e44 12902 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
01302104
UB
12903 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12904{
6b889d89 12905 if (<MODE>mode == SFmode
3debdc1e 12906 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
6b889d89
UB
12907 && flag_finite_math_only && !flag_trapping_math
12908 && flag_unsafe_math_optimizations)
12909 {
12910 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12911 DONE;
12912 }
12913
01302104
UB
12914 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12915 {
12916 rtx op0 = gen_reg_rtx (XFmode);
12917 rtx op1 = force_reg (<MODE>mode, operands[1]);
12918
786f159e 12919 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
01302104
UB
12920 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12921 DONE;
12922 }
12923})
2b589241 12924
786f159e 12925(define_insn "fpremxf4_i387"
5ae27cfa
UB
12926 [(set (match_operand:XF 0 "register_operand" "=f")
12927 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12928 (match_operand:XF 3 "register_operand" "1")]
12929 UNSPEC_FPREM_F))
12930 (set (match_operand:XF 1 "register_operand" "=u")
12931 (unspec:XF [(match_dup 2) (match_dup 3)]
12932 UNSPEC_FPREM_U))
8bc527af 12933 (set (reg:CCFP FPSR_REG)
79cd820a
UB
12934 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12935 UNSPEC_C2_FLAG))]
17b98269 12936 "TARGET_USE_FANCY_MATH_387"
5ae27cfa
UB
12937 "fprem"
12938 [(set_attr "type" "fpspc")
12939 (set_attr "mode" "XF")])
12940
786f159e
UB
12941(define_expand "fmodxf3"
12942 [(use (match_operand:XF 0 "register_operand" ""))
17c340e0
UB
12943 (use (match_operand:XF 1 "general_operand" ""))
12944 (use (match_operand:XF 2 "general_operand" ""))]
786f159e 12945 "TARGET_USE_FANCY_MATH_387"
5ae27cfa
UB
12946{
12947 rtx label = gen_label_rtx ();
12948
17c340e0
UB
12949 rtx op1 = gen_reg_rtx (XFmode);
12950 rtx op2 = gen_reg_rtx (XFmode);
21da84bd 12951
17c340e0 12952 emit_move_insn (op2, operands[2]);
f2a55e41 12953 emit_move_insn (op1, operands[1]);
5ae27cfa 12954
21da84bd 12955 emit_label (label);
17c340e0 12956 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
5ae27cfa 12957 ix86_emit_fp_unordered_jump (label);
79cd820a 12958 LABEL_NUSES (label) = 1;
5ae27cfa 12959
17c340e0 12960 emit_move_insn (operands[0], op1);
5ae27cfa
UB
12961 DONE;
12962})
12963
786f159e 12964(define_expand "fmod<mode>3"
00188daa
UB
12965 [(use (match_operand:MODEF 0 "register_operand" ""))
12966 (use (match_operand:MODEF 1 "general_operand" ""))
12967 (use (match_operand:MODEF 2 "general_operand" ""))]
e26feb2c 12968 "TARGET_USE_FANCY_MATH_387"
5ae27cfa 12969{
9aa5922d
UB
12970 rtx (*gen_truncxf) (rtx, rtx);
12971
5ae27cfa
UB
12972 rtx label = gen_label_rtx ();
12973
12974 rtx op1 = gen_reg_rtx (XFmode);
12975 rtx op2 = gen_reg_rtx (XFmode);
12976
e26feb2c 12977 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
f2a55e41 12978 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
5ae27cfa
UB
12979
12980 emit_label (label);
786f159e 12981 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
5ae27cfa 12982 ix86_emit_fp_unordered_jump (label);
79cd820a 12983 LABEL_NUSES (label) = 1;
5ae27cfa 12984
e26feb2c
UB
12985 /* Truncate the result properly for strict SSE math. */
12986 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12987 && !TARGET_MIX_SSE_I387)
9aa5922d 12988 gen_truncxf = gen_truncxf<mode>2;
e26feb2c 12989 else
9aa5922d 12990 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
e26feb2c 12991
9aa5922d 12992 emit_insn (gen_truncxf (operands[0], op1));
5ae27cfa
UB
12993 DONE;
12994})
12995
786f159e 12996(define_insn "fprem1xf4_i387"
5ae27cfa
UB
12997 [(set (match_operand:XF 0 "register_operand" "=f")
12998 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12999 (match_operand:XF 3 "register_operand" "1")]
13000 UNSPEC_FPREM1_F))
13001 (set (match_operand:XF 1 "register_operand" "=u")
13002 (unspec:XF [(match_dup 2) (match_dup 3)]
13003 UNSPEC_FPREM1_U))
8bc527af 13004 (set (reg:CCFP FPSR_REG)
79cd820a
UB
13005 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13006 UNSPEC_C2_FLAG))]
17b98269 13007 "TARGET_USE_FANCY_MATH_387"
5ae27cfa
UB
13008 "fprem1"
13009 [(set_attr "type" "fpspc")
13010 (set_attr "mode" "XF")])
13011
786f159e
UB
13012(define_expand "remainderxf3"
13013 [(use (match_operand:XF 0 "register_operand" ""))
17c340e0
UB
13014 (use (match_operand:XF 1 "general_operand" ""))
13015 (use (match_operand:XF 2 "general_operand" ""))]
786f159e 13016 "TARGET_USE_FANCY_MATH_387"
5ae27cfa
UB
13017{
13018 rtx label = gen_label_rtx ();
13019
17c340e0
UB
13020 rtx op1 = gen_reg_rtx (XFmode);
13021 rtx op2 = gen_reg_rtx (XFmode);
21da84bd 13022
17c340e0 13023 emit_move_insn (op2, operands[2]);
f2a55e41 13024 emit_move_insn (op1, operands[1]);
5ae27cfa 13025
21da84bd 13026 emit_label (label);
17c340e0 13027 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
5ae27cfa 13028 ix86_emit_fp_unordered_jump (label);
79cd820a 13029 LABEL_NUSES (label) = 1;
5ae27cfa 13030
17c340e0 13031 emit_move_insn (operands[0], op1);
5ae27cfa
UB
13032 DONE;
13033})
13034
786f159e 13035(define_expand "remainder<mode>3"
00188daa
UB
13036 [(use (match_operand:MODEF 0 "register_operand" ""))
13037 (use (match_operand:MODEF 1 "general_operand" ""))
13038 (use (match_operand:MODEF 2 "general_operand" ""))]
e26feb2c 13039 "TARGET_USE_FANCY_MATH_387"
5ae27cfa 13040{
9aa5922d
UB
13041 rtx (*gen_truncxf) (rtx, rtx);
13042
5ae27cfa
UB
13043 rtx label = gen_label_rtx ();
13044
13045 rtx op1 = gen_reg_rtx (XFmode);
13046 rtx op2 = gen_reg_rtx (XFmode);
13047
e26feb2c 13048 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
f2a55e41 13049 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
5ae27cfa
UB
13050
13051 emit_label (label);
13052
786f159e 13053 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
5ae27cfa 13054 ix86_emit_fp_unordered_jump (label);
79cd820a 13055 LABEL_NUSES (label) = 1;
5ae27cfa 13056
e26feb2c
UB
13057 /* Truncate the result properly for strict SSE math. */
13058 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13059 && !TARGET_MIX_SSE_I387)
9aa5922d 13060 gen_truncxf = gen_truncxf<mode>2;
e26feb2c 13061 else
9aa5922d 13062 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
e26feb2c 13063
9aa5922d 13064 emit_insn (gen_truncxf (operands[0], op1));
5ae27cfa
UB
13065 DONE;
13066})
13067
c648dedb 13068(define_insn "*sinxf2_i387"
e075ae69 13069 [(set (match_operand:XF 0 "register_operand" "=f")
8ee41eaf 13070 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
ba2baa55 13071 "TARGET_USE_FANCY_MATH_387
de6c5979 13072 && flag_unsafe_math_optimizations"
2b589241
JH
13073 "fsin"
13074 [(set_attr "type" "fpspc")
13075 (set_attr "mode" "XF")])
13076
c648dedb
UB
13077(define_insn "*sin_extend<mode>xf2_i387"
13078 [(set (match_operand:XF 0 "register_operand" "=f")
13079 (unspec:XF [(float_extend:XF
00188daa 13080 (match_operand:MODEF 1 "register_operand" "0"))]
c648dedb 13081 UNSPEC_SIN))]
ba2baa55 13082 "TARGET_USE_FANCY_MATH_387
c648dedb
UB
13083 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13084 || TARGET_MIX_SSE_I387)
de6c5979 13085 && flag_unsafe_math_optimizations"
c648dedb 13086 "fsin"
6ef67412 13087 [(set_attr "type" "fpspc")
c648dedb 13088 (set_attr "mode" "XF")])
bca7cce2 13089
c648dedb
UB
13090(define_insn "*cosxf2_i387"
13091 [(set (match_operand:XF 0 "register_operand" "=f")
13092 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
ba2baa55 13093 "TARGET_USE_FANCY_MATH_387
de6c5979 13094 && flag_unsafe_math_optimizations"
e075ae69 13095 "fcos"
6ef67412 13096 [(set_attr "type" "fpspc")
c648dedb 13097 (set_attr "mode" "XF")])
5f3d14e3 13098
c648dedb 13099(define_insn "*cos_extend<mode>xf2_i387"
e075ae69 13100 [(set (match_operand:XF 0 "register_operand" "=f")
c648dedb 13101 (unspec:XF [(float_extend:XF
00188daa 13102 (match_operand:MODEF 1 "register_operand" "0"))]
c648dedb 13103 UNSPEC_COS))]
ba2baa55 13104 "TARGET_USE_FANCY_MATH_387
c648dedb
UB
13105 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13106 || TARGET_MIX_SSE_I387)
de6c5979 13107 && flag_unsafe_math_optimizations"
2b589241
JH
13108 "fcos"
13109 [(set_attr "type" "fpspc")
13110 (set_attr "mode" "XF")])
1fb54135 13111
c648dedb 13112;; When sincos pattern is defined, sin and cos builtin functions will be
6300f037 13113;; expanded to sincos pattern with one of its outputs left unused.
c648dedb 13114;; CSE pass will figure out if two sincos patterns can be combined,
1ae58c30 13115;; otherwise sincos pattern will be split back to sin or cos pattern,
6c7cf1f0
UB
13116;; depending on the unused output.
13117
c648dedb
UB
13118(define_insn "sincosxf3"
13119 [(set (match_operand:XF 0 "register_operand" "=f")
13120 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
6c7cf1f0 13121 UNSPEC_SINCOS_COS))
c648dedb
UB
13122 (set (match_operand:XF 1 "register_operand" "=u")
13123 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
ba2baa55 13124 "TARGET_USE_FANCY_MATH_387
6c7cf1f0
UB
13125 && flag_unsafe_math_optimizations"
13126 "fsincos"
13127 [(set_attr "type" "fpspc")
c648dedb 13128 (set_attr "mode" "XF")])
6c7cf1f0
UB
13129
13130(define_split
c648dedb
UB
13131 [(set (match_operand:XF 0 "register_operand" "")
13132 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
6c7cf1f0 13133 UNSPEC_SINCOS_COS))
c648dedb
UB
13134 (set (match_operand:XF 1 "register_operand" "")
13135 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
6c7cf1f0 13136 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
00188daa 13137 && !(reload_completed || reload_in_progress)"
cb1b497e 13138 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
6c7cf1f0
UB
13139
13140(define_split
c648dedb
UB
13141 [(set (match_operand:XF 0 "register_operand" "")
13142 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
6c7cf1f0 13143 UNSPEC_SINCOS_COS))
c648dedb
UB
13144 (set (match_operand:XF 1 "register_operand" "")
13145 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
6c7cf1f0 13146 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
00188daa 13147 && !(reload_completed || reload_in_progress)"
cb1b497e 13148 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
6c7cf1f0 13149
c648dedb 13150(define_insn "sincos_extend<mode>xf3_i387"
6c7cf1f0 13151 [(set (match_operand:XF 0 "register_operand" "=f")
c648dedb 13152 (unspec:XF [(float_extend:XF
00188daa 13153 (match_operand:MODEF 2 "register_operand" "0"))]
6c7cf1f0
UB
13154 UNSPEC_SINCOS_COS))
13155 (set (match_operand:XF 1 "register_operand" "=u")
c648dedb 13156 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
ba2baa55 13157 "TARGET_USE_FANCY_MATH_387
c648dedb
UB
13158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13159 || TARGET_MIX_SSE_I387)
6c7cf1f0
UB
13160 && flag_unsafe_math_optimizations"
13161 "fsincos"
13162 [(set_attr "type" "fpspc")
13163 (set_attr "mode" "XF")])
13164
13165(define_split
13166 [(set (match_operand:XF 0 "register_operand" "")
c648dedb 13167 (unspec:XF [(float_extend:XF
00188daa 13168 (match_operand:MODEF 2 "register_operand" ""))]
6c7cf1f0
UB
13169 UNSPEC_SINCOS_COS))
13170 (set (match_operand:XF 1 "register_operand" "")
c648dedb 13171 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
6c7cf1f0 13172 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
00188daa 13173 && !(reload_completed || reload_in_progress)"
cb1b497e
UB
13174 [(set (match_dup 1)
13175 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
6c7cf1f0
UB
13176
13177(define_split
13178 [(set (match_operand:XF 0 "register_operand" "")
c648dedb 13179 (unspec:XF [(float_extend:XF
00188daa 13180 (match_operand:MODEF 2 "register_operand" ""))]
6c7cf1f0
UB
13181 UNSPEC_SINCOS_COS))
13182 (set (match_operand:XF 1 "register_operand" "")
c648dedb 13183 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
6c7cf1f0 13184 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
00188daa 13185 && !(reload_completed || reload_in_progress)"
cb1b497e
UB
13186 [(set (match_dup 0)
13187 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
6c7cf1f0 13188
c648dedb 13189(define_expand "sincos<mode>3"
00188daa
UB
13190 [(use (match_operand:MODEF 0 "register_operand" ""))
13191 (use (match_operand:MODEF 1 "register_operand" ""))
13192 (use (match_operand:MODEF 2 "register_operand" ""))]
c648dedb
UB
13193 "TARGET_USE_FANCY_MATH_387
13194 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13195 || TARGET_MIX_SSE_I387)
13196 && flag_unsafe_math_optimizations"
13197{
13198 rtx op0 = gen_reg_rtx (XFmode);
13199 rtx op1 = gen_reg_rtx (XFmode);
13200
13201 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
d85c7550
UB
13202 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13203 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
c648dedb
UB
13204 DONE;
13205})
13206
d85c7550
UB
13207(define_insn "fptanxf4_i387"
13208 [(set (match_operand:XF 0 "register_operand" "=f")
13209 (match_operand:XF 3 "const_double_operand" "F"))
13210 (set (match_operand:XF 1 "register_operand" "=u")
13211 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13212 UNSPEC_TAN))]
ba2baa55 13213 "TARGET_USE_FANCY_MATH_387
d85c7550
UB
13214 && flag_unsafe_math_optimizations
13215 && standard_80387_constant_p (operands[3]) == 2"
a072d43b
UB
13216 "fptan"
13217 [(set_attr "type" "fpspc")
d85c7550 13218 (set_attr "mode" "XF")])
a072d43b 13219
d85c7550 13220(define_insn "fptan_extend<mode>xf4_i387"
00188daa
UB
13221 [(set (match_operand:MODEF 0 "register_operand" "=f")
13222 (match_operand:MODEF 3 "const_double_operand" "F"))
d85c7550
UB
13223 (set (match_operand:XF 1 "register_operand" "=u")
13224 (unspec:XF [(float_extend:XF
00188daa 13225 (match_operand:MODEF 2 "register_operand" "0"))]
d85c7550 13226 UNSPEC_TAN))]
ba2baa55 13227 "TARGET_USE_FANCY_MATH_387
d85c7550
UB
13228 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13229 || TARGET_MIX_SSE_I387)
13230 && flag_unsafe_math_optimizations
13231 && standard_80387_constant_p (operands[3]) == 2"
a072d43b
UB
13232 "fptan"
13233 [(set_attr "type" "fpspc")
d85c7550 13234 (set_attr "mode" "XF")])
a072d43b 13235
d85c7550
UB
13236(define_expand "tanxf2"
13237 [(use (match_operand:XF 0 "register_operand" ""))
13238 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 13239 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
13240 && flag_unsafe_math_optimizations"
13241{
d85c7550 13242 rtx one = gen_reg_rtx (XFmode);
9db27449 13243 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
d85c7550 13244
9db27449 13245 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
d85c7550 13246 DONE;
a072d43b
UB
13247})
13248
d85c7550 13249(define_expand "tan<mode>2"
00188daa
UB
13250 [(use (match_operand:MODEF 0 "register_operand" ""))
13251 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 13252 "TARGET_USE_FANCY_MATH_387
d85c7550
UB
13253 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13254 || TARGET_MIX_SSE_I387)
a072d43b 13255 && flag_unsafe_math_optimizations"
d85c7550
UB
13256{
13257 rtx op0 = gen_reg_rtx (XFmode);
a072d43b 13258
d85c7550 13259 rtx one = gen_reg_rtx (<MODE>mode);
9db27449 13260 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
a072d43b 13261
d85c7550 13262 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
9db27449 13263 operands[1], op2));
d85c7550
UB
13264 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13265 DONE;
a072d43b
UB
13266})
13267
8ef4f42c
UB
13268(define_insn "*fpatanxf3_i387"
13269 [(set (match_operand:XF 0 "register_operand" "=f")
13270 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13271 (match_operand:XF 2 "register_operand" "u")]
13272 UNSPEC_FPATAN))
13273 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 13274 "TARGET_USE_FANCY_MATH_387
1fb54135
RS
13275 && flag_unsafe_math_optimizations"
13276 "fpatan"
13277 [(set_attr "type" "fpspc")
8ef4f42c 13278 (set_attr "mode" "XF")])
a6bf61c7 13279
8ef4f42c 13280(define_insn "fpatan_extend<mode>xf3_i387"
cb0bc263 13281 [(set (match_operand:XF 0 "register_operand" "=f")
8ef4f42c 13282 (unspec:XF [(float_extend:XF
00188daa 13283 (match_operand:MODEF 1 "register_operand" "0"))
8ef4f42c 13284 (float_extend:XF
00188daa 13285 (match_operand:MODEF 2 "register_operand" "u"))]
cb0bc263 13286 UNSPEC_FPATAN))
8ef4f42c 13287 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 13288 "TARGET_USE_FANCY_MATH_387
8ef4f42c
UB
13289 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13290 || TARGET_MIX_SSE_I387)
f8a1ebc6 13291 && flag_unsafe_math_optimizations"
1fb54135
RS
13292 "fpatan"
13293 [(set_attr "type" "fpspc")
13294 (set_attr "mode" "XF")])
13295
afeeac3f 13296(define_expand "atan2xf3"
8ef4f42c
UB
13297 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13298 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13299 (match_operand:XF 1 "register_operand" "")]
13300 UNSPEC_FPATAN))
13301 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 13302 "TARGET_USE_FANCY_MATH_387
a427621f 13303 && flag_unsafe_math_optimizations")
8ef4f42c
UB
13304
13305(define_expand "atan2<mode>3"
00188daa
UB
13306 [(use (match_operand:MODEF 0 "register_operand" ""))
13307 (use (match_operand:MODEF 1 "register_operand" ""))
13308 (use (match_operand:MODEF 2 "register_operand" ""))]
8ef4f42c
UB
13309 "TARGET_USE_FANCY_MATH_387
13310 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13311 || TARGET_MIX_SSE_I387)
13312 && flag_unsafe_math_optimizations"
afeeac3f 13313{
8ef4f42c
UB
13314 rtx op0 = gen_reg_rtx (XFmode);
13315
13316 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
afeeac3f 13318 DONE;
923c4cf2 13319})
afeeac3f 13320
a6bf61c7
UB
13321(define_expand "atanxf2"
13322 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13323 (unspec:XF [(match_dup 2)
13324 (match_operand:XF 1 "register_operand" "")]
8ef4f42c 13325 UNSPEC_FPATAN))
a6bf61c7 13326 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 13327 "TARGET_USE_FANCY_MATH_387
a6bf61c7
UB
13328 && flag_unsafe_math_optimizations"
13329{
13330 operands[2] = gen_reg_rtx (XFmode);
13331 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13332})
13333
8ef4f42c 13334(define_expand "atan<mode>2"
00188daa
UB
13335 [(use (match_operand:MODEF 0 "register_operand" ""))
13336 (use (match_operand:MODEF 1 "register_operand" ""))]
8ef4f42c
UB
13337 "TARGET_USE_FANCY_MATH_387
13338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13339 || TARGET_MIX_SSE_I387)
13340 && flag_unsafe_math_optimizations"
13341{
13342 rtx op0 = gen_reg_rtx (XFmode);
13343
9db27449
UB
13344 rtx op2 = gen_reg_rtx (<MODE>mode);
13345 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
8ef4f42c 13346
9db27449 13347 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
8ef4f42c
UB
13348 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13349 DONE;
13350})
13351
c56122d8
UB
13352(define_expand "asinxf2"
13353 [(set (match_dup 2)
13354 (mult:XF (match_operand:XF 1 "register_operand" "")
13355 (match_dup 1)))
13356 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13357 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13358 (parallel [(set (match_operand:XF 0 "register_operand" "")
13359 (unspec:XF [(match_dup 5) (match_dup 1)]
13360 UNSPEC_FPATAN))
13361 (clobber (match_scratch:XF 6 ""))])]
ba2baa55 13362 "TARGET_USE_FANCY_MATH_387
18bd082d 13363 && flag_unsafe_math_optimizations"
c56122d8
UB
13364{
13365 int i;
13366
18bd082d
JH
13367 if (optimize_insn_for_size_p ())
13368 FAIL;
13369
e2fc57a3 13370 for (i = 2; i < 6; i++)
c56122d8
UB
13371 operands[i] = gen_reg_rtx (XFmode);
13372
13373 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13374})
13375
e2fc57a3 13376(define_expand "asin<mode>2"
00188daa
UB
13377 [(use (match_operand:MODEF 0 "register_operand" ""))
13378 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
13379 "TARGET_USE_FANCY_MATH_387
13380 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13381 || TARGET_MIX_SSE_I387)
18bd082d 13382 && flag_unsafe_math_optimizations"
c56122d8 13383{
e2fc57a3
UB
13384 rtx op0 = gen_reg_rtx (XFmode);
13385 rtx op1 = gen_reg_rtx (XFmode);
c56122d8 13386
18bd082d
JH
13387 if (optimize_insn_for_size_p ())
13388 FAIL;
13389
e2fc57a3
UB
13390 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13391 emit_insn (gen_asinxf2 (op0, op1));
13392 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13393 DONE;
c56122d8
UB
13394})
13395
13396(define_expand "acosxf2"
13397 [(set (match_dup 2)
13398 (mult:XF (match_operand:XF 1 "register_operand" "")
13399 (match_dup 1)))
13400 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13401 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13402 (parallel [(set (match_operand:XF 0 "register_operand" "")
13403 (unspec:XF [(match_dup 1) (match_dup 5)]
13404 UNSPEC_FPATAN))
13405 (clobber (match_scratch:XF 6 ""))])]
ba2baa55 13406 "TARGET_USE_FANCY_MATH_387
18bd082d 13407 && flag_unsafe_math_optimizations"
c56122d8
UB
13408{
13409 int i;
13410
18bd082d
JH
13411 if (optimize_insn_for_size_p ())
13412 FAIL;
13413
e2fc57a3 13414 for (i = 2; i < 6; i++)
c56122d8
UB
13415 operands[i] = gen_reg_rtx (XFmode);
13416
13417 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13418})
13419
e2fc57a3 13420(define_expand "acos<mode>2"
00188daa
UB
13421 [(use (match_operand:MODEF 0 "register_operand" ""))
13422 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
13423 "TARGET_USE_FANCY_MATH_387
13424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13425 || TARGET_MIX_SSE_I387)
18bd082d 13426 && flag_unsafe_math_optimizations"
e2fc57a3
UB
13427{
13428 rtx op0 = gen_reg_rtx (XFmode);
13429 rtx op1 = gen_reg_rtx (XFmode);
13430
18bd082d
JH
13431 if (optimize_insn_for_size_p ())
13432 FAIL;
13433
e2fc57a3
UB
13434 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13435 emit_insn (gen_acosxf2 (op0, op1));
13436 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13437 DONE;
13438})
13439
0ac45694 13440(define_insn "fyl2xxf3_i387"
cb0bc263 13441 [(set (match_operand:XF 0 "register_operand" "=f")
0ac45694
UB
13442 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13443 (match_operand:XF 2 "register_operand" "u")]
cb0bc263 13444 UNSPEC_FYL2X))
0ac45694 13445 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 13446 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 13447 && flag_unsafe_math_optimizations"
358997e2
RS
13448 "fyl2x"
13449 [(set_attr "type" "fpspc")
13450 (set_attr "mode" "XF")])
13451
0ac45694
UB
13452(define_insn "fyl2x_extend<mode>xf3_i387"
13453 [(set (match_operand:XF 0 "register_operand" "=f")
13454 (unspec:XF [(float_extend:XF
00188daa 13455 (match_operand:MODEF 1 "register_operand" "0"))
0ac45694
UB
13456 (match_operand:XF 2 "register_operand" "u")]
13457 UNSPEC_FYL2X))
13458 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 13459 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
13460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13461 || TARGET_MIX_SSE_I387)
358997e2 13462 && flag_unsafe_math_optimizations"
0ac45694
UB
13463 "fyl2x"
13464 [(set_attr "type" "fpspc")
13465 (set_attr "mode" "XF")])
358997e2 13466
0ac45694
UB
13467(define_expand "logxf2"
13468 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13469 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13470 (match_dup 2)] UNSPEC_FYL2X))
13471 (clobber (match_scratch:XF 3 ""))])]
13472 "TARGET_USE_FANCY_MATH_387
13473 && flag_unsafe_math_optimizations"
13474{
f8a1ebc6 13475 operands[2] = gen_reg_rtx (XFmode);
0ac45694 13476 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
358997e2
RS
13477})
13478
0ac45694 13479(define_expand "log<mode>2"
00188daa
UB
13480 [(use (match_operand:MODEF 0 "register_operand" ""))
13481 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 13482 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
13483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13484 || TARGET_MIX_SSE_I387)
358997e2
RS
13485 && flag_unsafe_math_optimizations"
13486{
0ac45694 13487 rtx op0 = gen_reg_rtx (XFmode);
358997e2 13488
9db27449
UB
13489 rtx op2 = gen_reg_rtx (XFmode);
13490 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
6adcf89d 13491
9db27449 13492 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
e2fc57a3 13493 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
0ac45694 13494 DONE;
358997e2
RS
13495})
13496
0ac45694 13497(define_expand "log10xf2"
e43736ad
RS
13498 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13499 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13500 (match_dup 2)] UNSPEC_FYL2X))
cb0bc263 13501 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 13502 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 13503 && flag_unsafe_math_optimizations"
358997e2 13504{
3b8e0c91 13505 operands[2] = gen_reg_rtx (XFmode);
0ac45694 13506 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
3b8e0c91
UB
13507})
13508
0ac45694 13509(define_expand "log10<mode>2"
00188daa
UB
13510 [(use (match_operand:MODEF 0 "register_operand" ""))
13511 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 13512 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
13513 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13514 || TARGET_MIX_SSE_I387)
3b8e0c91
UB
13515 && flag_unsafe_math_optimizations"
13516{
0ac45694 13517 rtx op0 = gen_reg_rtx (XFmode);
3b8e0c91 13518
9db27449
UB
13519 rtx op2 = gen_reg_rtx (XFmode);
13520 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
6adcf89d 13521
9db27449 13522 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
e2fc57a3 13523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
0ac45694 13524 DONE;
3b8e0c91
UB
13525})
13526
0ac45694 13527(define_expand "log2xf2"
3b8e0c91
UB
13528 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13529 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13530 (match_dup 2)] UNSPEC_FYL2X))
13531 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 13532 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
13533 && flag_unsafe_math_optimizations"
13534{
3b8e0c91 13535 operands[2] = gen_reg_rtx (XFmode);
0ac45694 13536 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
3b8e0c91
UB
13537})
13538
0ac45694 13539(define_expand "log2<mode>2"
00188daa
UB
13540 [(use (match_operand:MODEF 0 "register_operand" ""))
13541 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 13542 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
13543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13544 || TARGET_MIX_SSE_I387)
3b8e0c91
UB
13545 && flag_unsafe_math_optimizations"
13546{
0ac45694 13547 rtx op0 = gen_reg_rtx (XFmode);
3b8e0c91 13548
9db27449
UB
13549 rtx op2 = gen_reg_rtx (XFmode);
13550 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
6adcf89d 13551
9db27449 13552 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
e2fc57a3 13553 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
0ac45694 13554 DONE;
3b8e0c91
UB
13555})
13556
0ac45694
UB
13557(define_insn "fyl2xp1xf3_i387"
13558 [(set (match_operand:XF 0 "register_operand" "=f")
13559 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13560 (match_operand:XF 2 "register_operand" "u")]
13561 UNSPEC_FYL2XP1))
13562 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 13563 "TARGET_USE_FANCY_MATH_387
3b8e0c91 13564 && flag_unsafe_math_optimizations"
0ac45694
UB
13565 "fyl2xp1"
13566 [(set_attr "type" "fpspc")
13567 (set_attr "mode" "XF")])
3b8e0c91 13568
0ac45694 13569(define_insn "fyl2xp1_extend<mode>xf3_i387"
c2fcfa4f 13570 [(set (match_operand:XF 0 "register_operand" "=f")
0ac45694 13571 (unspec:XF [(float_extend:XF
00188daa 13572 (match_operand:MODEF 1 "register_operand" "0"))
0ac45694 13573 (match_operand:XF 2 "register_operand" "u")]
c2fcfa4f 13574 UNSPEC_FYL2XP1))
0ac45694 13575 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 13576 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
13577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13578 || TARGET_MIX_SSE_I387)
c2fcfa4f
UB
13579 && flag_unsafe_math_optimizations"
13580 "fyl2xp1"
13581 [(set_attr "type" "fpspc")
13582 (set_attr "mode" "XF")])
13583
0ac45694
UB
13584(define_expand "log1pxf2"
13585 [(use (match_operand:XF 0 "register_operand" ""))
13586 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 13587 "TARGET_USE_FANCY_MATH_387
18bd082d 13588 && flag_unsafe_math_optimizations"
c2fcfa4f 13589{
18bd082d
JH
13590 if (optimize_insn_for_size_p ())
13591 FAIL;
13592
0ac45694 13593 ix86_emit_i387_log1p (operands[0], operands[1]);
c2fcfa4f
UB
13594 DONE;
13595})
13596
0ac45694 13597(define_expand "log1p<mode>2"
00188daa
UB
13598 [(use (match_operand:MODEF 0 "register_operand" ""))
13599 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 13600 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
13601 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13602 || TARGET_MIX_SSE_I387)
18bd082d 13603 && flag_unsafe_math_optimizations"
c2fcfa4f 13604{
18bd082d
JH
13605 rtx op0;
13606
13607 if (optimize_insn_for_size_p ())
13608 FAIL;
13609
13610 op0 = gen_reg_rtx (XFmode);
c2fcfa4f 13611
0ac45694 13612 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
c2fcfa4f 13613
0ac45694 13614 ix86_emit_i387_log1p (op0, operands[1]);
e2fc57a3 13615 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
c2fcfa4f
UB
13616 DONE;
13617})
13618
eaee4464 13619(define_insn "fxtractxf3_i387"
6adcf89d
UB
13620 [(set (match_operand:XF 0 "register_operand" "=f")
13621 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
88b28a31 13622 UNSPEC_XTRACT_FRACT))
6adcf89d
UB
13623 (set (match_operand:XF 1 "register_operand" "=u")
13624 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
ba2baa55 13625 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
13626 && flag_unsafe_math_optimizations"
13627 "fxtract"
13628 [(set_attr "type" "fpspc")
6adcf89d 13629 (set_attr "mode" "XF")])
88b28a31 13630
0ac45694
UB
13631(define_insn "fxtract_extend<mode>xf3_i387"
13632 [(set (match_operand:XF 0 "register_operand" "=f")
13633 (unspec:XF [(float_extend:XF
00188daa 13634 (match_operand:MODEF 2 "register_operand" "0"))]
0ac45694
UB
13635 UNSPEC_XTRACT_FRACT))
13636 (set (match_operand:XF 1 "register_operand" "=u")
13637 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
ba2baa55 13638 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
13639 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13640 || TARGET_MIX_SSE_I387)
88b28a31 13641 && flag_unsafe_math_optimizations"
0ac45694
UB
13642 "fxtract"
13643 [(set_attr "type" "fpspc")
13644 (set_attr "mode" "XF")])
88b28a31 13645
88b28a31
UB
13646(define_expand "logbxf2"
13647 [(parallel [(set (match_dup 2)
13648 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13649 UNSPEC_XTRACT_FRACT))
13650 (set (match_operand:XF 0 "register_operand" "")
13651 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
ba2baa55 13652 "TARGET_USE_FANCY_MATH_387
88b28a31 13653 && flag_unsafe_math_optimizations"
a427621f 13654 "operands[2] = gen_reg_rtx (XFmode);")
88b28a31 13655
0ac45694 13656(define_expand "logb<mode>2"
00188daa
UB
13657 [(use (match_operand:MODEF 0 "register_operand" ""))
13658 (use (match_operand:MODEF 1 "register_operand" ""))]
0ac45694
UB
13659 "TARGET_USE_FANCY_MATH_387
13660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13661 || TARGET_MIX_SSE_I387)
13662 && flag_unsafe_math_optimizations"
13663{
13664 rtx op0 = gen_reg_rtx (XFmode);
13665 rtx op1 = gen_reg_rtx (XFmode);
13666
13667 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
e2fc57a3 13668 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
0ac45694
UB
13669 DONE;
13670})
13671
eaee4464
UB
13672(define_expand "ilogbxf2"
13673 [(use (match_operand:SI 0 "register_operand" ""))
13674 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 13675 "TARGET_USE_FANCY_MATH_387
18bd082d 13676 && flag_unsafe_math_optimizations"
88b28a31 13677{
18bd082d
JH
13678 rtx op0, op1;
13679
13680 if (optimize_insn_for_size_p ())
13681 FAIL;
13682
13683 op0 = gen_reg_rtx (XFmode);
13684 op1 = gen_reg_rtx (XFmode);
eaee4464
UB
13685
13686 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13687 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13688 DONE;
13689})
13690
13691(define_expand "ilogb<mode>2"
13692 [(use (match_operand:SI 0 "register_operand" ""))
00188daa 13693 (use (match_operand:MODEF 1 "register_operand" ""))]
eaee4464
UB
13694 "TARGET_USE_FANCY_MATH_387
13695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13696 || TARGET_MIX_SSE_I387)
18bd082d 13697 && flag_unsafe_math_optimizations"
eaee4464 13698{
18bd082d
JH
13699 rtx op0, op1;
13700
13701 if (optimize_insn_for_size_p ())
13702 FAIL;
13703
13704 op0 = gen_reg_rtx (XFmode);
13705 op1 = gen_reg_rtx (XFmode);
eaee4464
UB
13706
13707 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13708 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13709 DONE;
88b28a31
UB
13710})
13711
e2fc57a3 13712(define_insn "*f2xm1xf2_i387"
9d5b9dae
RS
13713 [(set (match_operand:XF 0 "register_operand" "=f")
13714 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
e2fc57a3 13715 UNSPEC_F2XM1))]
ba2baa55 13716 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 13717 && flag_unsafe_math_optimizations"
9d5b9dae
RS
13718 "f2xm1"
13719 [(set_attr "type" "fpspc")
13720 (set_attr "mode" "XF")])
13721
e2fc57a3 13722(define_insn "*fscalexf4_i387"
f964bd29
UB
13723 [(set (match_operand:XF 0 "register_operand" "=f")
13724 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13725 (match_operand:XF 3 "register_operand" "1")]
13726 UNSPEC_FSCALE_FRACT))
13727 (set (match_operand:XF 1 "register_operand" "=u")
13728 (unspec:XF [(match_dup 2) (match_dup 3)]
13729 UNSPEC_FSCALE_EXP))]
ba2baa55 13730 "TARGET_USE_FANCY_MATH_387
f964bd29
UB
13731 && flag_unsafe_math_optimizations"
13732 "fscale"
13733 [(set_attr "type" "fpspc")
152e3565 13734 (set_attr "mode" "XF")])
f964bd29 13735
e2fc57a3 13736(define_expand "expNcorexf3"
9d5b9dae 13737 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
e2fc57a3 13738 (match_operand:XF 2 "register_operand" "")))
9d5b9dae
RS
13739 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13740 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13741 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13742 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13743 (parallel [(set (match_operand:XF 0 "register_operand" "")
f964bd29
UB
13744 (unspec:XF [(match_dup 8) (match_dup 4)]
13745 UNSPEC_FSCALE_FRACT))
13746 (set (match_dup 9)
13747 (unspec:XF [(match_dup 8) (match_dup 4)]
13748 UNSPEC_FSCALE_EXP))])]
ba2baa55 13749 "TARGET_USE_FANCY_MATH_387
18bd082d 13750 && flag_unsafe_math_optimizations"
9d5b9dae 13751{
9d5b9dae
RS
13752 int i;
13753
18bd082d
JH
13754 if (optimize_insn_for_size_p ())
13755 FAIL;
13756
e2fc57a3 13757 for (i = 3; i < 10; i++)
9d5b9dae 13758 operands[i] = gen_reg_rtx (XFmode);
e2fc57a3 13759
9d5b9dae
RS
13760 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13761})
82d397c7 13762
e2fc57a3
UB
13763(define_expand "expxf2"
13764 [(use (match_operand:XF 0 "register_operand" ""))
13765 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 13766 "TARGET_USE_FANCY_MATH_387
18bd082d 13767 && flag_unsafe_math_optimizations"
a251102e 13768{
18bd082d
JH
13769 rtx op2;
13770
13771 if (optimize_insn_for_size_p ())
13772 FAIL;
13773
13774 op2 = gen_reg_rtx (XFmode);
9db27449 13775 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
a251102e 13776
9db27449 13777 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
e2fc57a3 13778 DONE;
a251102e
UB
13779})
13780
e2fc57a3 13781(define_expand "exp<mode>2"
00188daa
UB
13782 [(use (match_operand:MODEF 0 "register_operand" ""))
13783 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
13784 "TARGET_USE_FANCY_MATH_387
13785 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13786 || TARGET_MIX_SSE_I387)
18bd082d 13787 && flag_unsafe_math_optimizations"
a251102e 13788{
18bd082d
JH
13789 rtx op0, op1;
13790
13791 if (optimize_insn_for_size_p ())
13792 FAIL;
13793
13794 op0 = gen_reg_rtx (XFmode);
13795 op1 = gen_reg_rtx (XFmode);
a251102e 13796
e2fc57a3
UB
13797 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13798 emit_insn (gen_expxf2 (op0, op1));
13799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13800 DONE;
a251102e
UB
13801})
13802
13803(define_expand "exp10xf2"
e2fc57a3
UB
13804 [(use (match_operand:XF 0 "register_operand" ""))
13805 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 13806 "TARGET_USE_FANCY_MATH_387
18bd082d 13807 && flag_unsafe_math_optimizations"
a251102e 13808{
18bd082d
JH
13809 rtx op2;
13810
13811 if (optimize_insn_for_size_p ())
13812 FAIL;
13813
13814 op2 = gen_reg_rtx (XFmode);
9db27449 13815 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
a251102e 13816
9db27449 13817 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
e2fc57a3 13818 DONE;
a251102e
UB
13819})
13820
e2fc57a3 13821(define_expand "exp10<mode>2"
00188daa
UB
13822 [(use (match_operand:MODEF 0 "register_operand" ""))
13823 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
13824 "TARGET_USE_FANCY_MATH_387
13825 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13826 || TARGET_MIX_SSE_I387)
18bd082d 13827 && flag_unsafe_math_optimizations"
a251102e 13828{
18bd082d
JH
13829 rtx op0, op1;
13830
13831 if (optimize_insn_for_size_p ())
13832 FAIL;
13833
13834 op0 = gen_reg_rtx (XFmode);
13835 op1 = gen_reg_rtx (XFmode);
a251102e 13836
e2fc57a3
UB
13837 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13838 emit_insn (gen_exp10xf2 (op0, op1));
13839 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13840 DONE;
a251102e
UB
13841})
13842
13843(define_expand "exp2xf2"
e2fc57a3
UB
13844 [(use (match_operand:XF 0 "register_operand" ""))
13845 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 13846 "TARGET_USE_FANCY_MATH_387
18bd082d 13847 && flag_unsafe_math_optimizations"
7a8e07c7 13848{
18bd082d
JH
13849 rtx op2;
13850
13851 if (optimize_insn_for_size_p ())
13852 FAIL;
13853
13854 op2 = gen_reg_rtx (XFmode);
9db27449 13855 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
7a8e07c7 13856
9db27449 13857 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
e2fc57a3 13858 DONE;
7a8e07c7
UB
13859})
13860
e2fc57a3 13861(define_expand "exp2<mode>2"
00188daa
UB
13862 [(use (match_operand:MODEF 0 "register_operand" ""))
13863 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
13864 "TARGET_USE_FANCY_MATH_387
13865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13866 || TARGET_MIX_SSE_I387)
18bd082d 13867 && flag_unsafe_math_optimizations"
7a8e07c7 13868{
18bd082d
JH
13869 rtx op0, op1;
13870
13871 if (optimize_insn_for_size_p ())
13872 FAIL;
13873
13874 op0 = gen_reg_rtx (XFmode);
13875 op1 = gen_reg_rtx (XFmode);
7a8e07c7 13876
e2fc57a3
UB
13877 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13878 emit_insn (gen_exp2xf2 (op0, op1));
13879 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13880 DONE;
7a8e07c7
UB
13881})
13882
13883(define_expand "expm1xf2"
13884 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13885 (match_dup 2)))
13886 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13887 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
6bdcc60c 13888 (set (match_dup 9) (float_extend:XF (match_dup 13)))
7a8e07c7
UB
13889 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13890 (parallel [(set (match_dup 7)
13891 (unspec:XF [(match_dup 6) (match_dup 4)]
13892 UNSPEC_FSCALE_FRACT))
6bdcc60c 13893 (set (match_dup 8)
7a8e07c7
UB
13894 (unspec:XF [(match_dup 6) (match_dup 4)]
13895 UNSPEC_FSCALE_EXP))])
13896 (parallel [(set (match_dup 10)
13897 (unspec:XF [(match_dup 9) (match_dup 8)]
13898 UNSPEC_FSCALE_FRACT))
13899 (set (match_dup 11)
13900 (unspec:XF [(match_dup 9) (match_dup 8)]
13901 UNSPEC_FSCALE_EXP))])
6bdcc60c
UB
13902 (set (match_dup 12) (minus:XF (match_dup 10)
13903 (float_extend:XF (match_dup 13))))
7a8e07c7
UB
13904 (set (match_operand:XF 0 "register_operand" "")
13905 (plus:XF (match_dup 12) (match_dup 7)))]
ba2baa55 13906 "TARGET_USE_FANCY_MATH_387
18bd082d 13907 && flag_unsafe_math_optimizations"
7a8e07c7 13908{
7a8e07c7
UB
13909 int i;
13910
18bd082d
JH
13911 if (optimize_insn_for_size_p ())
13912 FAIL;
13913
e2fc57a3 13914 for (i = 2; i < 13; i++)
7a8e07c7 13915 operands[i] = gen_reg_rtx (XFmode);
6bdcc60c
UB
13916
13917 operands[13]
13918 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13919
e2fc57a3 13920 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
7a8e07c7 13921})
c94a75af 13922
e2fc57a3 13923(define_expand "expm1<mode>2"
00188daa
UB
13924 [(use (match_operand:MODEF 0 "register_operand" ""))
13925 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
13926 "TARGET_USE_FANCY_MATH_387
13927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13928 || TARGET_MIX_SSE_I387)
18bd082d 13929 && flag_unsafe_math_optimizations"
c94a75af 13930{
18bd082d
JH
13931 rtx op0, op1;
13932
13933 if (optimize_insn_for_size_p ())
13934 FAIL;
13935
13936 op0 = gen_reg_rtx (XFmode);
13937 op1 = gen_reg_rtx (XFmode);
c94a75af 13938
e2fc57a3
UB
13939 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13940 emit_insn (gen_expm1xf2 (op0, op1));
13941 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13942 DONE;
c94a75af
UB
13943})
13944
13945(define_expand "ldexpxf3"
13946 [(set (match_dup 3)
13947 (float:XF (match_operand:SI 2 "register_operand" "")))
13948 (parallel [(set (match_operand:XF 0 " register_operand" "")
13949 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13950 (match_dup 3)]
13951 UNSPEC_FSCALE_FRACT))
13952 (set (match_dup 4)
13953 (unspec:XF [(match_dup 1) (match_dup 3)]
13954 UNSPEC_FSCALE_EXP))])]
13955 "TARGET_USE_FANCY_MATH_387
18bd082d 13956 && flag_unsafe_math_optimizations"
c94a75af 13957{
18bd082d
JH
13958 if (optimize_insn_for_size_p ())
13959 FAIL;
13960
e2fc57a3
UB
13961 operands[3] = gen_reg_rtx (XFmode);
13962 operands[4] = gen_reg_rtx (XFmode);
13963})
c94a75af 13964
e2fc57a3 13965(define_expand "ldexp<mode>3"
00188daa
UB
13966 [(use (match_operand:MODEF 0 "register_operand" ""))
13967 (use (match_operand:MODEF 1 "general_operand" ""))
e2fc57a3
UB
13968 (use (match_operand:SI 2 "register_operand" ""))]
13969 "TARGET_USE_FANCY_MATH_387
13970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13971 || TARGET_MIX_SSE_I387)
18bd082d 13972 && flag_unsafe_math_optimizations"
e2fc57a3 13973{
18bd082d
JH
13974 rtx op0, op1;
13975
13976 if (optimize_insn_for_size_p ())
13977 FAIL;
13978
13979 op0 = gen_reg_rtx (XFmode);
13980 op1 = gen_reg_rtx (XFmode);
e2fc57a3
UB
13981
13982 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13983 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13985 DONE;
c94a75af 13986})
0c0d910d
KG
13987
13988(define_expand "scalbxf3"
13989 [(parallel [(set (match_operand:XF 0 " register_operand" "")
13990 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13991 (match_operand:XF 2 "register_operand" "")]
13992 UNSPEC_FSCALE_FRACT))
13993 (set (match_dup 3)
13994 (unspec:XF [(match_dup 1) (match_dup 2)]
13995 UNSPEC_FSCALE_EXP))])]
13996 "TARGET_USE_FANCY_MATH_387
18bd082d 13997 && flag_unsafe_math_optimizations"
0c0d910d 13998{
18bd082d
JH
13999 if (optimize_insn_for_size_p ())
14000 FAIL;
14001
0c0d910d
KG
14002 operands[3] = gen_reg_rtx (XFmode);
14003})
14004
14005(define_expand "scalb<mode>3"
00188daa
UB
14006 [(use (match_operand:MODEF 0 "register_operand" ""))
14007 (use (match_operand:MODEF 1 "general_operand" ""))
dc6707b8 14008 (use (match_operand:MODEF 2 "general_operand" ""))]
0c0d910d
KG
14009 "TARGET_USE_FANCY_MATH_387
14010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011 || TARGET_MIX_SSE_I387)
18bd082d 14012 && flag_unsafe_math_optimizations"
0c0d910d 14013{
18bd082d
JH
14014 rtx op0, op1, op2;
14015
14016 if (optimize_insn_for_size_p ())
14017 FAIL;
14018
14019 op0 = gen_reg_rtx (XFmode);
14020 op1 = gen_reg_rtx (XFmode);
14021 op2 = gen_reg_rtx (XFmode);
0c0d910d
KG
14022
14023 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14024 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14025 emit_insn (gen_scalbxf3 (op0, op1, op2));
14026 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14027 DONE;
14028})
dc6707b8
UB
14029
14030(define_expand "significandxf2"
14031 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14032 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14033 UNSPEC_XTRACT_FRACT))
14034 (set (match_dup 2)
14035 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14036 "TARGET_USE_FANCY_MATH_387
14037 && flag_unsafe_math_optimizations"
a427621f 14038 "operands[2] = gen_reg_rtx (XFmode);")
dc6707b8
UB
14039
14040(define_expand "significand<mode>2"
14041 [(use (match_operand:MODEF 0 "register_operand" ""))
14042 (use (match_operand:MODEF 1 "register_operand" ""))]
14043 "TARGET_USE_FANCY_MATH_387
14044 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045 || TARGET_MIX_SSE_I387)
14046 && flag_unsafe_math_optimizations"
14047{
14048 rtx op0 = gen_reg_rtx (XFmode);
14049 rtx op1 = gen_reg_rtx (XFmode);
14050
14051 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14052 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14053 DONE;
14054})
edeacc14
UB
14055\f
14056
f28eb39c 14057(define_insn "sse4_1_round<mode>2"
00188daa
UB
14058 [(set (match_operand:MODEF 0 "register_operand" "=x")
14059 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14060 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14061 UNSPEC_ROUND))]
04e1d06b 14062 "TARGET_ROUND"
95879c72 14063 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
f28eb39c
UB
14064 [(set_attr "type" "ssecvt")
14065 (set_attr "prefix_extra" "1")
95879c72 14066 (set_attr "prefix" "maybe_vex")
f28eb39c
UB
14067 (set_attr "mode" "<MODE>")])
14068
acaaf0c6 14069(define_insn "rintxf2"
edeacc14
UB
14070 [(set (match_operand:XF 0 "register_operand" "=f")
14071 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
acaaf0c6 14072 UNSPEC_FRNDINT))]
ba2baa55 14073 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
14074 && flag_unsafe_math_optimizations"
14075 "frndint"
14076 [(set_attr "type" "fpspc")
14077 (set_attr "mode" "XF")])
14078
acaaf0c6 14079(define_expand "rint<mode>2"
00188daa
UB
14080 [(use (match_operand:MODEF 0 "register_operand" ""))
14081 (use (match_operand:MODEF 1 "register_operand" ""))]
c7d32ff6 14082 "(TARGET_USE_FANCY_MATH_387
acaaf0c6
UB
14083 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14084 || TARGET_MIX_SSE_I387)
c7d32ff6 14085 && flag_unsafe_math_optimizations)
acaaf0c6 14086 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 14087 && !flag_trapping_math)"
c7d32ff6 14088{
acaaf0c6 14089 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 14090 && !flag_trapping_math)
f28eb39c 14091 {
18bd082d
JH
14092 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14093 FAIL;
04e1d06b 14094 if (TARGET_ROUND)
f28eb39c
UB
14095 emit_insn (gen_sse4_1_round<mode>2
14096 (operands[0], operands[1], GEN_INT (0x04)));
14097 else
14098 ix86_expand_rint (operand0, operand1);
14099 }
c7d32ff6
RG
14100 else
14101 {
1d08f955
RG
14102 rtx op0 = gen_reg_rtx (XFmode);
14103 rtx op1 = gen_reg_rtx (XFmode);
edeacc14 14104
acaaf0c6
UB
14105 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14106 emit_insn (gen_rintxf2 (op0, op1));
edeacc14 14107
acaaf0c6 14108 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
c7d32ff6 14109 }
edeacc14
UB
14110 DONE;
14111})
14112
acaaf0c6 14113(define_expand "round<mode>2"
00188daa
UB
14114 [(match_operand:MODEF 0 "register_operand" "")
14115 (match_operand:MODEF 1 "nonimmediate_operand" "")]
acaaf0c6 14116 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 14117 && !flag_trapping_math && !flag_rounding_math"
097f2964 14118{
18bd082d
JH
14119 if (optimize_insn_for_size_p ())
14120 FAIL;
f28eb39c 14121 if (TARGET_64BIT || (<MODE>mode != DFmode))
097f2964
RG
14122 ix86_expand_round (operand0, operand1);
14123 else
14124 ix86_expand_rounddf_32 (operand0, operand1);
14125 DONE;
14126})
14127
4d06b0a2 14128(define_insn_and_split "*fistdi2_1"
00188daa
UB
14129 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14130 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 14131 UNSPEC_FIST))]
87bb8864 14132 "TARGET_USE_FANCY_MATH_387
5071eab7 14133 && can_create_pseudo_p ()"
87bb8864
UB
14134 "#"
14135 "&& 1"
14136 [(const_int 0)]
14137{
14138 if (memory_operand (operands[0], VOIDmode))
4d06b0a2 14139 emit_insn (gen_fistdi2 (operands[0], operands[1]));
87bb8864
UB
14140 else
14141 {
4d06b0a2
UB
14142 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14143 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14144 operands[2]));
87bb8864
UB
14145 }
14146 DONE;
14147}
14148 [(set_attr "type" "fpspc")
4d06b0a2 14149 (set_attr "mode" "DI")])
87bb8864 14150
6e858d45
UB
14151(define_insn "fistdi2"
14152 [(set (match_operand:DI 0 "memory_operand" "=m")
14153 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
acaaf0c6 14154 UNSPEC_FIST))
6e858d45 14155 (clobber (match_scratch:XF 2 "=&1f"))]
bb7f0423 14156 "TARGET_USE_FANCY_MATH_387"
6e858d45
UB
14157 "* return output_fix_trunc (insn, operands, 0);"
14158 [(set_attr "type" "fpspc")
14159 (set_attr "mode" "DI")])
14160
14161(define_insn "fistdi2_with_temp"
14162 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14163 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
acaaf0c6 14164 UNSPEC_FIST))
73e8165a 14165 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
6e858d45 14166 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
bb7f0423 14167 "TARGET_USE_FANCY_MATH_387"
6e858d45
UB
14168 "#"
14169 [(set_attr "type" "fpspc")
14170 (set_attr "mode" "DI")])
14171
6300f037 14172(define_split
6e858d45
UB
14173 [(set (match_operand:DI 0 "register_operand" "")
14174 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 14175 UNSPEC_FIST))
6e858d45
UB
14176 (clobber (match_operand:DI 2 "memory_operand" ""))
14177 (clobber (match_scratch 3 ""))]
14178 "reload_completed"
14179 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14180 (clobber (match_dup 3))])
cb1b497e 14181 (set (match_dup 0) (match_dup 2))])
6e858d45 14182
6300f037 14183(define_split
6e858d45
UB
14184 [(set (match_operand:DI 0 "memory_operand" "")
14185 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 14186 UNSPEC_FIST))
6e858d45
UB
14187 (clobber (match_operand:DI 2 "memory_operand" ""))
14188 (clobber (match_scratch 3 ""))]
14189 "reload_completed"
14190 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
cb1b497e 14191 (clobber (match_dup 3))])])
6e858d45 14192
4d06b0a2 14193(define_insn_and_split "*fist<mode>2_1"
00188daa
UB
14194 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14195 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 14196 UNSPEC_FIST))]
4d06b0a2 14197 "TARGET_USE_FANCY_MATH_387
5071eab7 14198 && can_create_pseudo_p ()"
4d06b0a2
UB
14199 "#"
14200 "&& 1"
14201 [(const_int 0)]
14202{
14203 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14204 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14205 operands[2]));
14206 DONE;
14207}
14208 [(set_attr "type" "fpspc")
14209 (set_attr "mode" "<MODE>")])
14210
6e858d45
UB
14211(define_insn "fist<mode>2"
14212 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14213 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
acaaf0c6 14214 UNSPEC_FIST))]
bb7f0423 14215 "TARGET_USE_FANCY_MATH_387"
6e858d45
UB
14216 "* return output_fix_trunc (insn, operands, 0);"
14217 [(set_attr "type" "fpspc")
14218 (set_attr "mode" "<MODE>")])
14219
14220(define_insn "fist<mode>2_with_temp"
4d06b0a2
UB
14221 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14222 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
acaaf0c6 14223 UNSPEC_FIST))
4d06b0a2 14224 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
bb7f0423 14225 "TARGET_USE_FANCY_MATH_387"
6e858d45
UB
14226 "#"
14227 [(set_attr "type" "fpspc")
14228 (set_attr "mode" "<MODE>")])
14229
6300f037 14230(define_split
6e858d45
UB
14231 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14232 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 14233 UNSPEC_FIST))
6e858d45
UB
14234 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14235 "reload_completed"
acaaf0c6 14236 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
cb1b497e 14237 (set (match_dup 0) (match_dup 2))])
6e858d45 14238
6300f037 14239(define_split
6e858d45
UB
14240 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14241 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 14242 UNSPEC_FIST))
cec471db 14243 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
6e858d45 14244 "reload_completed"
cb1b497e 14245 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
6e858d45 14246
bb7f0423 14247(define_expand "lrintxf<mode>2"
87bb8864 14248 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
bb7f0423 14249 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 14250 UNSPEC_FIST))]
a427621f 14251 "TARGET_USE_FANCY_MATH_387")
bb7f0423 14252
00188daa 14253(define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
acaaf0c6 14254 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
00188daa 14255 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
acaaf0c6 14256 UNSPEC_FIX_NOTRUNC))]
00188daa 14257 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
a427621f 14258 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
bb7f0423 14259
00188daa 14260(define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
acaaf0c6 14261 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
00188daa
UB
14262 (match_operand:MODEF 1 "register_operand" "")]
14263 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
acaaf0c6 14264 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18bd082d 14265 && !flag_trapping_math && !flag_rounding_math"
4d81bf84 14266{
18bd082d
JH
14267 if (optimize_insn_for_size_p ())
14268 FAIL;
4d81bf84
RG
14269 ix86_expand_lround (operand0, operand1);
14270 DONE;
14271})
14272
c9d3aede
UB
14273;; Rounding mode control word calculation could clobber FLAGS_REG.
14274(define_insn_and_split "frndintxf2_floor"
00188daa
UB
14275 [(set (match_operand:XF 0 "register_operand" "")
14276 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
c9d3aede
UB
14277 UNSPEC_FRNDINT_FLOOR))
14278 (clobber (reg:CC FLAGS_REG))]
14279 "TARGET_USE_FANCY_MATH_387
14280 && flag_unsafe_math_optimizations
5071eab7 14281 && can_create_pseudo_p ()"
c9d3aede
UB
14282 "#"
14283 "&& 1"
14284 [(const_int 0)]
14285{
ff680eb1 14286 ix86_optimize_mode_switching[I387_FLOOR] = 1;
c9d3aede 14287
ff680eb1
UB
14288 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14289 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
c9d3aede
UB
14290
14291 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14292 operands[2], operands[3]));
14293 DONE;
14294}
14295 [(set_attr "type" "frndint")
14296 (set_attr "i387_cw" "floor")
14297 (set_attr "mode" "XF")])
14298
14299(define_insn "frndintxf2_floor_i387"
edeacc14
UB
14300 [(set (match_operand:XF 0 "register_operand" "=f")
14301 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14302 UNSPEC_FRNDINT_FLOOR))
14303 (use (match_operand:HI 2 "memory_operand" "m"))
14304 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 14305 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
14306 && flag_unsafe_math_optimizations"
14307 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14308 [(set_attr "type" "frndint")
14309 (set_attr "i387_cw" "floor")
14310 (set_attr "mode" "XF")])
14311
c9d3aede
UB
14312(define_expand "floorxf2"
14313 [(use (match_operand:XF 0 "register_operand" ""))
14314 (use (match_operand:XF 1 "register_operand" ""))]
14315 "TARGET_USE_FANCY_MATH_387
18bd082d 14316 && flag_unsafe_math_optimizations"
c9d3aede 14317{
18bd082d
JH
14318 if (optimize_insn_for_size_p ())
14319 FAIL;
c9d3aede
UB
14320 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14321 DONE;
14322})
14323
f28eb39c 14324(define_expand "floor<mode>2"
00188daa
UB
14325 [(use (match_operand:MODEF 0 "register_operand" ""))
14326 (use (match_operand:MODEF 1 "register_operand" ""))]
f28eb39c
UB
14327 "(TARGET_USE_FANCY_MATH_387
14328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14329 || TARGET_MIX_SSE_I387)
18bd082d 14330 && flag_unsafe_math_optimizations)
f28eb39c 14331 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 14332 && !flag_trapping_math)"
edeacc14 14333{
f28eb39c
UB
14334 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14335 && !flag_trapping_math
18bd082d 14336 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
d096ecdd 14337 {
18bd082d
JH
14338 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14339 FAIL;
04e1d06b 14340 if (TARGET_ROUND)
f28eb39c
UB
14341 emit_insn (gen_sse4_1_round<mode>2
14342 (operands[0], operands[1], GEN_INT (0x01)));
14343 else if (TARGET_64BIT || (<MODE>mode != DFmode))
d096ecdd
RG
14344 ix86_expand_floorceil (operand0, operand1, true);
14345 else
14346 ix86_expand_floorceildf_32 (operand0, operand1, true);
14347 }
14348 else
14349 {
18bd082d
JH
14350 rtx op0, op1;
14351
14352 if (optimize_insn_for_size_p ())
14353 FAIL;
edeacc14 14354
18bd082d
JH
14355 op0 = gen_reg_rtx (XFmode);
14356 op1 = gen_reg_rtx (XFmode);
f28eb39c 14357 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
d096ecdd 14358 emit_insn (gen_frndintxf2_floor (op0, op1));
edeacc14 14359
f28eb39c 14360 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
d096ecdd 14361 }
edeacc14
UB
14362 DONE;
14363})
14364
4a927664 14365(define_insn_and_split "*fist<mode>2_floor_1"
00188daa
UB
14366 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14367 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
4a927664
UB
14368 UNSPEC_FIST_FLOOR))
14369 (clobber (reg:CC FLAGS_REG))]
14370 "TARGET_USE_FANCY_MATH_387
14371 && flag_unsafe_math_optimizations
5071eab7 14372 && can_create_pseudo_p ()"
4a927664
UB
14373 "#"
14374 "&& 1"
14375 [(const_int 0)]
14376{
ff680eb1
UB
14377 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14378
14379 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14380 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
4a927664
UB
14381 if (memory_operand (operands[0], VOIDmode))
14382 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14383 operands[2], operands[3]));
14384 else
14385 {
ff680eb1 14386 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4a927664
UB
14387 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14388 operands[2], operands[3],
14389 operands[4]));
14390 }
14391 DONE;
14392}
14393 [(set_attr "type" "fistp")
14394 (set_attr "i387_cw" "floor")
14395 (set_attr "mode" "<MODE>")])
14396
14397(define_insn "fistdi2_floor"
14398 [(set (match_operand:DI 0 "memory_operand" "=m")
14399 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14400 UNSPEC_FIST_FLOOR))
14401 (use (match_operand:HI 2 "memory_operand" "m"))
14402 (use (match_operand:HI 3 "memory_operand" "m"))
14403 (clobber (match_scratch:XF 4 "=&1f"))]
14404 "TARGET_USE_FANCY_MATH_387
14405 && flag_unsafe_math_optimizations"
14406 "* return output_fix_trunc (insn, operands, 0);"
14407 [(set_attr "type" "fistp")
14408 (set_attr "i387_cw" "floor")
14409 (set_attr "mode" "DI")])
14410
14411(define_insn "fistdi2_floor_with_temp"
14412 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14413 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14414 UNSPEC_FIST_FLOOR))
14415 (use (match_operand:HI 2 "memory_operand" "m,m"))
14416 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 14417 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4a927664
UB
14418 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14419 "TARGET_USE_FANCY_MATH_387
14420 && flag_unsafe_math_optimizations"
14421 "#"
14422 [(set_attr "type" "fistp")
14423 (set_attr "i387_cw" "floor")
14424 (set_attr "mode" "DI")])
14425
6300f037 14426(define_split
4a927664
UB
14427 [(set (match_operand:DI 0 "register_operand" "")
14428 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14429 UNSPEC_FIST_FLOOR))
14430 (use (match_operand:HI 2 "memory_operand" ""))
14431 (use (match_operand:HI 3 "memory_operand" ""))
14432 (clobber (match_operand:DI 4 "memory_operand" ""))
14433 (clobber (match_scratch 5 ""))]
14434 "reload_completed"
14435 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14436 (use (match_dup 2))
14437 (use (match_dup 3))
14438 (clobber (match_dup 5))])
cb1b497e 14439 (set (match_dup 0) (match_dup 4))])
4a927664 14440
6300f037 14441(define_split
4a927664
UB
14442 [(set (match_operand:DI 0 "memory_operand" "")
14443 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14444 UNSPEC_FIST_FLOOR))
14445 (use (match_operand:HI 2 "memory_operand" ""))
14446 (use (match_operand:HI 3 "memory_operand" ""))
14447 (clobber (match_operand:DI 4 "memory_operand" ""))
14448 (clobber (match_scratch 5 ""))]
14449 "reload_completed"
14450 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14451 (use (match_dup 2))
14452 (use (match_dup 3))
cb1b497e 14453 (clobber (match_dup 5))])])
4a927664
UB
14454
14455(define_insn "fist<mode>2_floor"
14456 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14457 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14458 UNSPEC_FIST_FLOOR))
14459 (use (match_operand:HI 2 "memory_operand" "m"))
14460 (use (match_operand:HI 3 "memory_operand" "m"))]
14461 "TARGET_USE_FANCY_MATH_387
14462 && flag_unsafe_math_optimizations"
14463 "* return output_fix_trunc (insn, operands, 0);"
14464 [(set_attr "type" "fistp")
14465 (set_attr "i387_cw" "floor")
14466 (set_attr "mode" "<MODE>")])
14467
14468(define_insn "fist<mode>2_floor_with_temp"
14469 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14470 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14471 UNSPEC_FIST_FLOOR))
14472 (use (match_operand:HI 2 "memory_operand" "m,m"))
14473 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 14474 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4a927664
UB
14475 "TARGET_USE_FANCY_MATH_387
14476 && flag_unsafe_math_optimizations"
14477 "#"
14478 [(set_attr "type" "fistp")
14479 (set_attr "i387_cw" "floor")
14480 (set_attr "mode" "<MODE>")])
14481
6300f037 14482(define_split
4a927664
UB
14483 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14484 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14485 UNSPEC_FIST_FLOOR))
14486 (use (match_operand:HI 2 "memory_operand" ""))
14487 (use (match_operand:HI 3 "memory_operand" ""))
14488 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14489 "reload_completed"
14490 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14491 UNSPEC_FIST_FLOOR))
14492 (use (match_dup 2))
14493 (use (match_dup 3))])
cb1b497e 14494 (set (match_dup 0) (match_dup 4))])
4a927664 14495
6300f037 14496(define_split
4a927664
UB
14497 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14498 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14499 UNSPEC_FIST_FLOOR))
14500 (use (match_operand:HI 2 "memory_operand" ""))
14501 (use (match_operand:HI 3 "memory_operand" ""))
14502 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14503 "reload_completed"
14504 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14505 UNSPEC_FIST_FLOOR))
14506 (use (match_dup 2))
cb1b497e 14507 (use (match_dup 3))])])
4a927664 14508
c3a4177f 14509(define_expand "lfloorxf<mode>2"
4a927664
UB
14510 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14511 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14512 UNSPEC_FIST_FLOOR))
14513 (clobber (reg:CC FLAGS_REG))])]
14514 "TARGET_USE_FANCY_MATH_387
14515 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
a427621f 14516 && flag_unsafe_math_optimizations")
4a927664 14517
85760734
UB
14518(define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14519 [(match_operand:SWI48 0 "nonimmediate_operand" "")
00188daa 14520 (match_operand:MODEF 1 "register_operand" "")]
85760734 14521 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18bd082d 14522 && !flag_trapping_math"
c3a4177f 14523{
85760734 14524 if (TARGET_64BIT && optimize_insn_for_size_p ())
18bd082d 14525 FAIL;
c3a4177f
RG
14526 ix86_expand_lfloorceil (operand0, operand1, true);
14527 DONE;
14528})
14529
c9d3aede
UB
14530;; Rounding mode control word calculation could clobber FLAGS_REG.
14531(define_insn_and_split "frndintxf2_ceil"
00188daa
UB
14532 [(set (match_operand:XF 0 "register_operand" "")
14533 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
c9d3aede
UB
14534 UNSPEC_FRNDINT_CEIL))
14535 (clobber (reg:CC FLAGS_REG))]
ba2baa55 14536 "TARGET_USE_FANCY_MATH_387
c9d3aede 14537 && flag_unsafe_math_optimizations
5071eab7 14538 && can_create_pseudo_p ()"
c9d3aede
UB
14539 "#"
14540 "&& 1"
14541 [(const_int 0)]
edeacc14 14542{
ff680eb1 14543 ix86_optimize_mode_switching[I387_CEIL] = 1;
edeacc14 14544
ff680eb1
UB
14545 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14546 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
c9d3aede
UB
14547
14548 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14549 operands[2], operands[3]));
edeacc14 14550 DONE;
c9d3aede
UB
14551}
14552 [(set_attr "type" "frndint")
14553 (set_attr "i387_cw" "ceil")
14554 (set_attr "mode" "XF")])
edeacc14 14555
c9d3aede 14556(define_insn "frndintxf2_ceil_i387"
edeacc14
UB
14557 [(set (match_operand:XF 0 "register_operand" "=f")
14558 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14559 UNSPEC_FRNDINT_CEIL))
14560 (use (match_operand:HI 2 "memory_operand" "m"))
14561 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 14562 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
14563 && flag_unsafe_math_optimizations"
14564 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14565 [(set_attr "type" "frndint")
14566 (set_attr "i387_cw" "ceil")
14567 (set_attr "mode" "XF")])
14568
c9d3aede
UB
14569(define_expand "ceilxf2"
14570 [(use (match_operand:XF 0 "register_operand" ""))
14571 (use (match_operand:XF 1 "register_operand" ""))]
14572 "TARGET_USE_FANCY_MATH_387
18bd082d 14573 && flag_unsafe_math_optimizations"
c9d3aede 14574{
18bd082d
JH
14575 if (optimize_insn_for_size_p ())
14576 FAIL;
c9d3aede
UB
14577 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14578 DONE;
14579})
14580
f28eb39c 14581(define_expand "ceil<mode>2"
00188daa
UB
14582 [(use (match_operand:MODEF 0 "register_operand" ""))
14583 (use (match_operand:MODEF 1 "register_operand" ""))]
f28eb39c
UB
14584 "(TARGET_USE_FANCY_MATH_387
14585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586 || TARGET_MIX_SSE_I387)
18bd082d 14587 && flag_unsafe_math_optimizations)
f28eb39c 14588 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 14589 && !flag_trapping_math)"
edeacc14 14590{
f28eb39c
UB
14591 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14592 && !flag_trapping_math
18bd082d 14593 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
d096ecdd 14594 {
04e1d06b 14595 if (TARGET_ROUND)
f28eb39c
UB
14596 emit_insn (gen_sse4_1_round<mode>2
14597 (operands[0], operands[1], GEN_INT (0x02)));
18bd082d
JH
14598 else if (optimize_insn_for_size_p ())
14599 FAIL;
f28eb39c 14600 else if (TARGET_64BIT || (<MODE>mode != DFmode))
d096ecdd
RG
14601 ix86_expand_floorceil (operand0, operand1, false);
14602 else
14603 ix86_expand_floorceildf_32 (operand0, operand1, false);
14604 }
14605 else
14606 {
18bd082d
JH
14607 rtx op0, op1;
14608
14609 if (optimize_insn_for_size_p ())
14610 FAIL;
edeacc14 14611
18bd082d
JH
14612 op0 = gen_reg_rtx (XFmode);
14613 op1 = gen_reg_rtx (XFmode);
f28eb39c 14614 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
d096ecdd 14615 emit_insn (gen_frndintxf2_ceil (op0, op1));
edeacc14 14616
f28eb39c 14617 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
d096ecdd 14618 }
edeacc14
UB
14619 DONE;
14620})
14621
4a927664 14622(define_insn_and_split "*fist<mode>2_ceil_1"
00188daa
UB
14623 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14624 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
4a927664
UB
14625 UNSPEC_FIST_CEIL))
14626 (clobber (reg:CC FLAGS_REG))]
14627 "TARGET_USE_FANCY_MATH_387
14628 && flag_unsafe_math_optimizations
5071eab7 14629 && can_create_pseudo_p ()"
4a927664
UB
14630 "#"
14631 "&& 1"
14632 [(const_int 0)]
14633{
ff680eb1
UB
14634 ix86_optimize_mode_switching[I387_CEIL] = 1;
14635
14636 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14637 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
4a927664
UB
14638 if (memory_operand (operands[0], VOIDmode))
14639 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14640 operands[2], operands[3]));
14641 else
14642 {
ff680eb1 14643 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4a927664
UB
14644 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14645 operands[2], operands[3],
14646 operands[4]));
14647 }
14648 DONE;
14649}
14650 [(set_attr "type" "fistp")
14651 (set_attr "i387_cw" "ceil")
14652 (set_attr "mode" "<MODE>")])
14653
14654(define_insn "fistdi2_ceil"
14655 [(set (match_operand:DI 0 "memory_operand" "=m")
14656 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14657 UNSPEC_FIST_CEIL))
14658 (use (match_operand:HI 2 "memory_operand" "m"))
14659 (use (match_operand:HI 3 "memory_operand" "m"))
14660 (clobber (match_scratch:XF 4 "=&1f"))]
14661 "TARGET_USE_FANCY_MATH_387
14662 && flag_unsafe_math_optimizations"
14663 "* return output_fix_trunc (insn, operands, 0);"
14664 [(set_attr "type" "fistp")
14665 (set_attr "i387_cw" "ceil")
14666 (set_attr "mode" "DI")])
14667
14668(define_insn "fistdi2_ceil_with_temp"
14669 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14670 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14671 UNSPEC_FIST_CEIL))
14672 (use (match_operand:HI 2 "memory_operand" "m,m"))
14673 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 14674 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4a927664
UB
14675 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14676 "TARGET_USE_FANCY_MATH_387
14677 && flag_unsafe_math_optimizations"
14678 "#"
14679 [(set_attr "type" "fistp")
14680 (set_attr "i387_cw" "ceil")
14681 (set_attr "mode" "DI")])
14682
6300f037 14683(define_split
4a927664
UB
14684 [(set (match_operand:DI 0 "register_operand" "")
14685 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14686 UNSPEC_FIST_CEIL))
14687 (use (match_operand:HI 2 "memory_operand" ""))
14688 (use (match_operand:HI 3 "memory_operand" ""))
14689 (clobber (match_operand:DI 4 "memory_operand" ""))
14690 (clobber (match_scratch 5 ""))]
14691 "reload_completed"
14692 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14693 (use (match_dup 2))
14694 (use (match_dup 3))
14695 (clobber (match_dup 5))])
cb1b497e 14696 (set (match_dup 0) (match_dup 4))])
4a927664 14697
6300f037 14698(define_split
4a927664
UB
14699 [(set (match_operand:DI 0 "memory_operand" "")
14700 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14701 UNSPEC_FIST_CEIL))
14702 (use (match_operand:HI 2 "memory_operand" ""))
14703 (use (match_operand:HI 3 "memory_operand" ""))
14704 (clobber (match_operand:DI 4 "memory_operand" ""))
14705 (clobber (match_scratch 5 ""))]
14706 "reload_completed"
14707 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14708 (use (match_dup 2))
14709 (use (match_dup 3))
cb1b497e 14710 (clobber (match_dup 5))])])
4a927664
UB
14711
14712(define_insn "fist<mode>2_ceil"
14713 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14714 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14715 UNSPEC_FIST_CEIL))
14716 (use (match_operand:HI 2 "memory_operand" "m"))
14717 (use (match_operand:HI 3 "memory_operand" "m"))]
14718 "TARGET_USE_FANCY_MATH_387
14719 && flag_unsafe_math_optimizations"
14720 "* return output_fix_trunc (insn, operands, 0);"
14721 [(set_attr "type" "fistp")
14722 (set_attr "i387_cw" "ceil")
14723 (set_attr "mode" "<MODE>")])
14724
14725(define_insn "fist<mode>2_ceil_with_temp"
14726 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14727 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14728 UNSPEC_FIST_CEIL))
14729 (use (match_operand:HI 2 "memory_operand" "m,m"))
14730 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 14731 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4a927664
UB
14732 "TARGET_USE_FANCY_MATH_387
14733 && flag_unsafe_math_optimizations"
14734 "#"
14735 [(set_attr "type" "fistp")
14736 (set_attr "i387_cw" "ceil")
14737 (set_attr "mode" "<MODE>")])
14738
6300f037 14739(define_split
4a927664
UB
14740 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14741 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14742 UNSPEC_FIST_CEIL))
14743 (use (match_operand:HI 2 "memory_operand" ""))
14744 (use (match_operand:HI 3 "memory_operand" ""))
14745 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14746 "reload_completed"
14747 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14748 UNSPEC_FIST_CEIL))
14749 (use (match_dup 2))
14750 (use (match_dup 3))])
cb1b497e 14751 (set (match_dup 0) (match_dup 4))])
4a927664 14752
6300f037 14753(define_split
4a927664
UB
14754 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14755 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14756 UNSPEC_FIST_CEIL))
14757 (use (match_operand:HI 2 "memory_operand" ""))
14758 (use (match_operand:HI 3 "memory_operand" ""))
14759 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14760 "reload_completed"
14761 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14762 UNSPEC_FIST_CEIL))
14763 (use (match_dup 2))
cb1b497e 14764 (use (match_dup 3))])])
4a927664 14765
c3a4177f 14766(define_expand "lceilxf<mode>2"
4a927664
UB
14767 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14768 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14769 UNSPEC_FIST_CEIL))
14770 (clobber (reg:CC FLAGS_REG))])]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
a427621f 14773 && flag_unsafe_math_optimizations")
4a927664 14774
85760734
UB
14775(define_expand "lceil<MODEF:mode><SWI48:mode>2"
14776 [(match_operand:SWI48 0 "nonimmediate_operand" "")
00188daa 14777 (match_operand:MODEF 1 "register_operand" "")]
85760734 14778 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
c3a4177f
RG
14779 && !flag_trapping_math"
14780{
14781 ix86_expand_lfloorceil (operand0, operand1, false);
14782 DONE;
14783})
14784
c9d3aede
UB
14785;; Rounding mode control word calculation could clobber FLAGS_REG.
14786(define_insn_and_split "frndintxf2_trunc"
00188daa
UB
14787 [(set (match_operand:XF 0 "register_operand" "")
14788 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
c9d3aede
UB
14789 UNSPEC_FRNDINT_TRUNC))
14790 (clobber (reg:CC FLAGS_REG))]
ba2baa55 14791 "TARGET_USE_FANCY_MATH_387
c9d3aede 14792 && flag_unsafe_math_optimizations
5071eab7 14793 && can_create_pseudo_p ()"
c9d3aede
UB
14794 "#"
14795 "&& 1"
14796 [(const_int 0)]
edeacc14 14797{
ff680eb1 14798 ix86_optimize_mode_switching[I387_TRUNC] = 1;
edeacc14 14799
ff680eb1
UB
14800 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14801 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
c9d3aede
UB
14802
14803 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14804 operands[2], operands[3]));
edeacc14 14805 DONE;
c9d3aede
UB
14806}
14807 [(set_attr "type" "frndint")
14808 (set_attr "i387_cw" "trunc")
14809 (set_attr "mode" "XF")])
edeacc14 14810
c9d3aede 14811(define_insn "frndintxf2_trunc_i387"
edeacc14
UB
14812 [(set (match_operand:XF 0 "register_operand" "=f")
14813 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14814 UNSPEC_FRNDINT_TRUNC))
14815 (use (match_operand:HI 2 "memory_operand" "m"))
14816 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 14817 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
14818 && flag_unsafe_math_optimizations"
14819 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14820 [(set_attr "type" "frndint")
14821 (set_attr "i387_cw" "trunc")
14822 (set_attr "mode" "XF")])
14823
c9d3aede
UB
14824(define_expand "btruncxf2"
14825 [(use (match_operand:XF 0 "register_operand" ""))
14826 (use (match_operand:XF 1 "register_operand" ""))]
14827 "TARGET_USE_FANCY_MATH_387
18bd082d 14828 && flag_unsafe_math_optimizations"
c9d3aede 14829{
18bd082d
JH
14830 if (optimize_insn_for_size_p ())
14831 FAIL;
c9d3aede
UB
14832 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14833 DONE;
14834})
14835
f28eb39c 14836(define_expand "btrunc<mode>2"
00188daa
UB
14837 [(use (match_operand:MODEF 0 "register_operand" ""))
14838 (use (match_operand:MODEF 1 "register_operand" ""))]
f28eb39c
UB
14839 "(TARGET_USE_FANCY_MATH_387
14840 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14841 || TARGET_MIX_SSE_I387)
18bd082d 14842 && flag_unsafe_math_optimizations)
f28eb39c 14843 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 14844 && !flag_trapping_math)"
edeacc14 14845{
f28eb39c
UB
14846 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14847 && !flag_trapping_math
18bd082d 14848 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
044928d6 14849 {
04e1d06b 14850 if (TARGET_ROUND)
f28eb39c
UB
14851 emit_insn (gen_sse4_1_round<mode>2
14852 (operands[0], operands[1], GEN_INT (0x03)));
18bd082d
JH
14853 else if (optimize_insn_for_size_p ())
14854 FAIL;
f28eb39c 14855 else if (TARGET_64BIT || (<MODE>mode != DFmode))
044928d6
RG
14856 ix86_expand_trunc (operand0, operand1);
14857 else
14858 ix86_expand_truncdf_32 (operand0, operand1);
14859 }
14860 else
14861 {
18bd082d
JH
14862 rtx op0, op1;
14863
14864 if (optimize_insn_for_size_p ())
14865 FAIL;
edeacc14 14866
18bd082d
JH
14867 op0 = gen_reg_rtx (XFmode);
14868 op1 = gen_reg_rtx (XFmode);
f28eb39c 14869 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
044928d6 14870 emit_insn (gen_frndintxf2_trunc (op0, op1));
edeacc14 14871
f28eb39c 14872 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
044928d6 14873 }
edeacc14
UB
14874 DONE;
14875})
14876
c9d3aede
UB
14877;; Rounding mode control word calculation could clobber FLAGS_REG.
14878(define_insn_and_split "frndintxf2_mask_pm"
00188daa
UB
14879 [(set (match_operand:XF 0 "register_operand" "")
14880 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
c9d3aede
UB
14881 UNSPEC_FRNDINT_MASK_PM))
14882 (clobber (reg:CC FLAGS_REG))]
ba2baa55 14883 "TARGET_USE_FANCY_MATH_387
c9d3aede 14884 && flag_unsafe_math_optimizations
5071eab7 14885 && can_create_pseudo_p ()"
c9d3aede
UB
14886 "#"
14887 "&& 1"
14888 [(const_int 0)]
edeacc14 14889{
ff680eb1 14890 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
edeacc14 14891
ff680eb1
UB
14892 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14893 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
c9d3aede
UB
14894
14895 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14896 operands[2], operands[3]));
edeacc14 14897 DONE;
c9d3aede
UB
14898}
14899 [(set_attr "type" "frndint")
14900 (set_attr "i387_cw" "mask_pm")
14901 (set_attr "mode" "XF")])
edeacc14 14902
c9d3aede 14903(define_insn "frndintxf2_mask_pm_i387"
edeacc14
UB
14904 [(set (match_operand:XF 0 "register_operand" "=f")
14905 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14906 UNSPEC_FRNDINT_MASK_PM))
14907 (use (match_operand:HI 2 "memory_operand" "m"))
14908 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 14909 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
14910 && flag_unsafe_math_optimizations"
14911 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14912 [(set_attr "type" "frndint")
14913 (set_attr "i387_cw" "mask_pm")
14914 (set_attr "mode" "XF")])
14915
c9d3aede
UB
14916(define_expand "nearbyintxf2"
14917 [(use (match_operand:XF 0 "register_operand" ""))
14918 (use (match_operand:XF 1 "register_operand" ""))]
14919 "TARGET_USE_FANCY_MATH_387
14920 && flag_unsafe_math_optimizations"
14921{
14922 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
c9d3aede
UB
14923 DONE;
14924})
14925
00188daa
UB
14926(define_expand "nearbyint<mode>2"
14927 [(use (match_operand:MODEF 0 "register_operand" ""))
14928 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 14929 "TARGET_USE_FANCY_MATH_387
00188daa
UB
14930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14931 || TARGET_MIX_SSE_I387)
edeacc14
UB
14932 && flag_unsafe_math_optimizations"
14933{
14934 rtx op0 = gen_reg_rtx (XFmode);
14935 rtx op1 = gen_reg_rtx (XFmode);
edeacc14 14936
00188daa 14937 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
c9d3aede 14938 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
edeacc14 14939
00188daa 14940 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
edeacc14
UB
14941 DONE;
14942})
14943
9ed4207f
UB
14944(define_insn "fxam<mode>2_i387"
14945 [(set (match_operand:HI 0 "register_operand" "=a")
14946 (unspec:HI
14947 [(match_operand:X87MODEF 1 "register_operand" "f")]
14948 UNSPEC_FXAM))]
14949 "TARGET_USE_FANCY_MATH_387"
14950 "fxam\n\tfnstsw\t%0"
14951 [(set_attr "type" "multi")
725fd454 14952 (set_attr "length" "4")
9ed4207f
UB
14953 (set_attr "unit" "i387")
14954 (set_attr "mode" "<MODE>")])
14955
6b67572e
UB
14956(define_insn_and_split "fxam<mode>2_i387_with_temp"
14957 [(set (match_operand:HI 0 "register_operand" "")
14958 (unspec:HI
14959 [(match_operand:MODEF 1 "memory_operand" "")]
14960 UNSPEC_FXAM_MEM))]
14961 "TARGET_USE_FANCY_MATH_387
5071eab7 14962 && can_create_pseudo_p ()"
6b67572e
UB
14963 "#"
14964 "&& 1"
14965 [(set (match_dup 2)(match_dup 1))
14966 (set (match_dup 0)
14967 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14968{
14969 operands[2] = gen_reg_rtx (<MODE>mode);
14970
14971 MEM_VOLATILE_P (operands[1]) = 1;
14972}
14973 [(set_attr "type" "multi")
14974 (set_attr "unit" "i387")
14975 (set_attr "mode" "<MODE>")])
14976
14977(define_expand "isinfxf2"
14978 [(use (match_operand:SI 0 "register_operand" ""))
14979 (use (match_operand:XF 1 "register_operand" ""))]
14980 "TARGET_USE_FANCY_MATH_387
14981 && TARGET_C99_FUNCTIONS"
14982{
14983 rtx mask = GEN_INT (0x45);
14984 rtx val = GEN_INT (0x05);
14985
14986 rtx cond;
14987
14988 rtx scratch = gen_reg_rtx (HImode);
14989 rtx res = gen_reg_rtx (QImode);
14990
14991 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14992
14993 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14994 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14995 cond = gen_rtx_fmt_ee (EQ, QImode,
14996 gen_rtx_REG (CCmode, FLAGS_REG),
14997 const0_rtx);
14998 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14999 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15000 DONE;
15001})
15002
9ed4207f
UB
15003(define_expand "isinf<mode>2"
15004 [(use (match_operand:SI 0 "register_operand" ""))
6b67572e 15005 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
9ed4207f 15006 "TARGET_USE_FANCY_MATH_387
81e864cb 15007 && TARGET_C99_FUNCTIONS
d0c9d431 15008 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9ed4207f
UB
15009{
15010 rtx mask = GEN_INT (0x45);
15011 rtx val = GEN_INT (0x05);
15012
15013 rtx cond;
15014
15015 rtx scratch = gen_reg_rtx (HImode);
15016 rtx res = gen_reg_rtx (QImode);
15017
6b67572e
UB
15018 /* Remove excess precision by forcing value through memory. */
15019 if (memory_operand (operands[1], VOIDmode))
15020 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15021 else
15022 {
bbbbb16a
ILT
15023 enum ix86_stack_slot slot = (virtuals_instantiated
15024 ? SLOT_TEMP
15025 : SLOT_VIRTUAL);
6b67572e
UB
15026 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15027
15028 emit_move_insn (temp, operands[1]);
15029 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15030 }
15031
9ed4207f
UB
15032 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15033 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15034 cond = gen_rtx_fmt_ee (EQ, QImode,
15035 gen_rtx_REG (CCmode, FLAGS_REG),
15036 const0_rtx);
15037 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15038 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15039 DONE;
15040})
15041
d355d5ea 15042(define_expand "signbitxf2"
d0c9d431 15043 [(use (match_operand:SI 0 "register_operand" ""))
d355d5ea
UB
15044 (use (match_operand:XF 1 "register_operand" ""))]
15045 "TARGET_USE_FANCY_MATH_387"
15046{
15047 rtx scratch = gen_reg_rtx (HImode);
15048
15049 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15050 emit_insn (gen_andsi3 (operands[0],
15051 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15052 DONE;
15053})
15054
15055(define_insn "movmsk_df"
15056 [(set (match_operand:SI 0 "register_operand" "=r")
15057 (unspec:SI
15058 [(match_operand:DF 1 "register_operand" "x")]
15059 UNSPEC_MOVMSK))]
15060 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15061 "%vmovmskpd\t{%1, %0|%0, %1}"
15062 [(set_attr "type" "ssemov")
15063 (set_attr "prefix" "maybe_vex")
15064 (set_attr "mode" "DF")])
15065
15066;; Use movmskpd in SSE mode to avoid store forwarding stall
15067;; for 32bit targets and movq+shrq sequence for 64bit targets.
15068(define_expand "signbitdf2"
15069 [(use (match_operand:SI 0 "register_operand" ""))
15070 (use (match_operand:DF 1 "register_operand" ""))]
d0c9d431 15071 "TARGET_USE_FANCY_MATH_387
d355d5ea 15072 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
d0c9d431 15073{
d355d5ea
UB
15074 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15075 {
15076 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15077 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15078 }
15079 else
15080 {
15081 rtx scratch = gen_reg_rtx (HImode);
d0c9d431 15082
d355d5ea
UB
15083 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15084 emit_insn (gen_andsi3 (operands[0],
15085 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15086 }
15087 DONE;
15088})
15089
15090(define_expand "signbitsf2"
15091 [(use (match_operand:SI 0 "register_operand" ""))
15092 (use (match_operand:SF 1 "register_operand" ""))]
15093 "TARGET_USE_FANCY_MATH_387
15094 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15095{
d0c9d431
UB
15096 rtx scratch = gen_reg_rtx (HImode);
15097
d355d5ea
UB
15098 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15099 emit_insn (gen_andsi3 (operands[0],
15100 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
d0c9d431
UB
15101 DONE;
15102})
e075ae69
RH
15103\f
15104;; Block operation instructions
886c62d1 15105
922e3e33
UB
15106(define_insn "cld"
15107 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15108 ""
15109 "cld"
15110 [(set_attr "length" "1")
15111 (set_attr "length_immediate" "0")
15112 (set_attr "modrm" "0")])
15113
70128ad9 15114(define_expand "movmemsi"
f90800f8
JH
15115 [(use (match_operand:BLK 0 "memory_operand" ""))
15116 (use (match_operand:BLK 1 "memory_operand" ""))
79f05c19 15117 (use (match_operand:SI 2 "nonmemory_operand" ""))
079a182e
JH
15118 (use (match_operand:SI 3 "const_int_operand" ""))
15119 (use (match_operand:SI 4 "const_int_operand" ""))
15120 (use (match_operand:SI 5 "const_int_operand" ""))]
8c996513 15121 ""
886c62d1 15122{
8c996513 15123 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
079a182e 15124 operands[4], operands[5]))
0945b39d
JH
15125 DONE;
15126 else
15127 FAIL;
0f40f9f7 15128})
79f05c19 15129
70128ad9 15130(define_expand "movmemdi"
0945b39d
JH
15131 [(use (match_operand:BLK 0 "memory_operand" ""))
15132 (use (match_operand:BLK 1 "memory_operand" ""))
15133 (use (match_operand:DI 2 "nonmemory_operand" ""))
079a182e
JH
15134 (use (match_operand:DI 3 "const_int_operand" ""))
15135 (use (match_operand:SI 4 "const_int_operand" ""))
15136 (use (match_operand:SI 5 "const_int_operand" ""))]
0945b39d 15137 "TARGET_64BIT"
0945b39d 15138{
8c996513 15139 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
079a182e 15140 operands[4], operands[5]))
0945b39d
JH
15141 DONE;
15142 else
15143 FAIL;
0f40f9f7 15144})
79f05c19 15145
0945b39d
JH
15146;; Most CPUs don't like single string operations
15147;; Handle this case here to simplify previous expander.
79f05c19 15148
4e44c1ef
JJ
15149(define_expand "strmov"
15150 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15151 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15152 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
8bc527af 15153 (clobber (reg:CC FLAGS_REG))])
4e44c1ef 15154 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
8bc527af 15155 (clobber (reg:CC FLAGS_REG))])]
79f05c19 15156 ""
79f05c19 15157{
4e44c1ef 15158 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
79f05c19 15159
4e44c1ef
JJ
15160 /* If .md ever supports :P for Pmode, these can be directly
15161 in the pattern above. */
15162 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15163 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
0945b39d 15164
3c285765 15165 /* Can't use this if the user has appropriated esi or edi. */
18bd082d 15166 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
ec382b8c 15167 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
886c62d1 15168 {
4e44c1ef
JJ
15169 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15170 operands[2], operands[3],
15171 operands[5], operands[6]));
f90800f8
JH
15172 DONE;
15173 }
886c62d1 15174
4e44c1ef 15175 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
0f40f9f7 15176})
f90800f8 15177
4e44c1ef
JJ
15178(define_expand "strmov_singleop"
15179 [(parallel [(set (match_operand 1 "memory_operand" "")
15180 (match_operand 3 "memory_operand" ""))
15181 (set (match_operand 0 "register_operand" "")
15182 (match_operand 4 "" ""))
15183 (set (match_operand 2 "register_operand" "")
90c56b45 15184 (match_operand 5 "" ""))])]
18bd082d 15185 ""
922e3e33 15186 "ix86_current_function_needs_cld = 1;")
0945b39d 15187
4e44c1ef 15188(define_insn "*strmovdi_rex_1"
0945b39d
JH
15189 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15190 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15191 (set (match_operand:DI 0 "register_operand" "=D")
15192 (plus:DI (match_dup 2)
15193 (const_int 8)))
15194 (set (match_operand:DI 1 "register_operand" "=S")
15195 (plus:DI (match_dup 3)
90c56b45 15196 (const_int 8)))]
bdfd2026 15197 "TARGET_64BIT"
0945b39d
JH
15198 "movsq"
15199 [(set_attr "type" "str")
15200 (set_attr "mode" "DI")
15201 (set_attr "memory" "both")])
15202
4e44c1ef 15203(define_insn "*strmovsi_1"
79f05c19
JH
15204 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15205 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15206 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 15207 (plus:SI (match_dup 2)
79f05c19
JH
15208 (const_int 4)))
15209 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 15210 (plus:SI (match_dup 3)
90c56b45 15211 (const_int 4)))]
bdfd2026 15212 "!TARGET_64BIT"
62d2739a 15213 "movs{l|d}"
0945b39d
JH
15214 [(set_attr "type" "str")
15215 (set_attr "mode" "SI")
15216 (set_attr "memory" "both")])
15217
4e44c1ef 15218(define_insn "*strmovsi_rex_1"
0945b39d
JH
15219 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15220 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15221 (set (match_operand:DI 0 "register_operand" "=D")
15222 (plus:DI (match_dup 2)
15223 (const_int 4)))
15224 (set (match_operand:DI 1 "register_operand" "=S")
15225 (plus:DI (match_dup 3)
90c56b45 15226 (const_int 4)))]
bdfd2026 15227 "TARGET_64BIT"
62d2739a 15228 "movs{l|d}"
79f05c19 15229 [(set_attr "type" "str")
6ef67412 15230 (set_attr "mode" "SI")
79f05c19
JH
15231 (set_attr "memory" "both")])
15232
4e44c1ef 15233(define_insn "*strmovhi_1"
f90800f8
JH
15234 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15235 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15236 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 15237 (plus:SI (match_dup 2)
f90800f8
JH
15238 (const_int 2)))
15239 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 15240 (plus:SI (match_dup 3)
90c56b45 15241 (const_int 2)))]
bdfd2026 15242 "!TARGET_64BIT"
0945b39d
JH
15243 "movsw"
15244 [(set_attr "type" "str")
15245 (set_attr "memory" "both")
15246 (set_attr "mode" "HI")])
15247
4e44c1ef 15248(define_insn "*strmovhi_rex_1"
0945b39d
JH
15249 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15250 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15251 (set (match_operand:DI 0 "register_operand" "=D")
15252 (plus:DI (match_dup 2)
15253 (const_int 2)))
15254 (set (match_operand:DI 1 "register_operand" "=S")
15255 (plus:DI (match_dup 3)
90c56b45 15256 (const_int 2)))]
bdfd2026 15257 "TARGET_64BIT"
f90800f8
JH
15258 "movsw"
15259 [(set_attr "type" "str")
15260 (set_attr "memory" "both")
6ef67412 15261 (set_attr "mode" "HI")])
f90800f8 15262
4e44c1ef 15263(define_insn "*strmovqi_1"
f90800f8
JH
15264 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15265 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15266 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 15267 (plus:SI (match_dup 2)
f90800f8
JH
15268 (const_int 1)))
15269 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 15270 (plus:SI (match_dup 3)
90c56b45 15271 (const_int 1)))]
bdfd2026 15272 "!TARGET_64BIT"
f90800f8
JH
15273 "movsb"
15274 [(set_attr "type" "str")
6ef67412
JH
15275 (set_attr "memory" "both")
15276 (set_attr "mode" "QI")])
f90800f8 15277
4e44c1ef 15278(define_insn "*strmovqi_rex_1"
0945b39d
JH
15279 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15280 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15281 (set (match_operand:DI 0 "register_operand" "=D")
15282 (plus:DI (match_dup 2)
15283 (const_int 1)))
15284 (set (match_operand:DI 1 "register_operand" "=S")
15285 (plus:DI (match_dup 3)
90c56b45 15286 (const_int 1)))]
bdfd2026 15287 "TARGET_64BIT"
0945b39d
JH
15288 "movsb"
15289 [(set_attr "type" "str")
15290 (set_attr "memory" "both")
a952487c 15291 (set_attr "prefix_rex" "0")
0945b39d
JH
15292 (set_attr "mode" "QI")])
15293
4e44c1ef
JJ
15294(define_expand "rep_mov"
15295 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15296 (set (match_operand 0 "register_operand" "")
15297 (match_operand 5 "" ""))
15298 (set (match_operand 2 "register_operand" "")
15299 (match_operand 6 "" ""))
15300 (set (match_operand 1 "memory_operand" "")
15301 (match_operand 3 "memory_operand" ""))
90c56b45 15302 (use (match_dup 4))])]
4e44c1ef 15303 ""
922e3e33 15304 "ix86_current_function_needs_cld = 1;")
4e44c1ef
JJ
15305
15306(define_insn "*rep_movdi_rex64"
0945b39d 15307 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
6300f037 15308 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
15309 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15310 (const_int 3))
15311 (match_operand:DI 3 "register_operand" "0")))
6300f037 15312 (set (match_operand:DI 1 "register_operand" "=S")
0945b39d
JH
15313 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15314 (match_operand:DI 4 "register_operand" "1")))
15315 (set (mem:BLK (match_dup 3))
15316 (mem:BLK (match_dup 4)))
90c56b45 15317 (use (match_dup 5))]
0945b39d 15318 "TARGET_64BIT"
2433310d 15319 "rep{%;} movsq"
0945b39d
JH
15320 [(set_attr "type" "str")
15321 (set_attr "prefix_rep" "1")
15322 (set_attr "memory" "both")
15323 (set_attr "mode" "DI")])
15324
4e44c1ef 15325(define_insn "*rep_movsi"
f90800f8 15326 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
6300f037 15327 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
15328 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15329 (const_int 2))
15330 (match_operand:SI 3 "register_operand" "0")))
6300f037 15331 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb
JH
15332 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15333 (match_operand:SI 4 "register_operand" "1")))
f90800f8
JH
15334 (set (mem:BLK (match_dup 3))
15335 (mem:BLK (match_dup 4)))
90c56b45 15336 (use (match_dup 5))]
0945b39d 15337 "!TARGET_64BIT"
2433310d 15338 "rep{%;} movs{l|d}"
0945b39d
JH
15339 [(set_attr "type" "str")
15340 (set_attr "prefix_rep" "1")
15341 (set_attr "memory" "both")
15342 (set_attr "mode" "SI")])
15343
4e44c1ef 15344(define_insn "*rep_movsi_rex64"
0945b39d 15345 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
6300f037 15346 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
15347 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15348 (const_int 2))
15349 (match_operand:DI 3 "register_operand" "0")))
6300f037 15350 (set (match_operand:DI 1 "register_operand" "=S")
0945b39d
JH
15351 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15352 (match_operand:DI 4 "register_operand" "1")))
15353 (set (mem:BLK (match_dup 3))
15354 (mem:BLK (match_dup 4)))
90c56b45 15355 (use (match_dup 5))]
0945b39d 15356 "TARGET_64BIT"
2433310d 15357 "rep{%;} movs{l|d}"
f90800f8 15358 [(set_attr "type" "str")
6ef67412
JH
15359 (set_attr "prefix_rep" "1")
15360 (set_attr "memory" "both")
15361 (set_attr "mode" "SI")])
f90800f8 15362
4e44c1ef 15363(define_insn "*rep_movqi"
f90800f8 15364 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
6300f037 15365 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
15366 (plus:SI (match_operand:SI 3 "register_operand" "0")
15367 (match_operand:SI 5 "register_operand" "2")))
6300f037 15368 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 15369 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
f90800f8
JH
15370 (set (mem:BLK (match_dup 3))
15371 (mem:BLK (match_dup 4)))
90c56b45 15372 (use (match_dup 5))]
0945b39d 15373 "!TARGET_64BIT"
2433310d 15374 "rep{%;} movsb"
0945b39d
JH
15375 [(set_attr "type" "str")
15376 (set_attr "prefix_rep" "1")
15377 (set_attr "memory" "both")
15378 (set_attr "mode" "SI")])
15379
4e44c1ef 15380(define_insn "*rep_movqi_rex64"
0945b39d 15381 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
6300f037 15382 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
15383 (plus:DI (match_operand:DI 3 "register_operand" "0")
15384 (match_operand:DI 5 "register_operand" "2")))
6300f037 15385 (set (match_operand:DI 1 "register_operand" "=S")
0945b39d
JH
15386 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15387 (set (mem:BLK (match_dup 3))
15388 (mem:BLK (match_dup 4)))
90c56b45 15389 (use (match_dup 5))]
0945b39d 15390 "TARGET_64BIT"
2433310d 15391 "rep{%;} movsb"
f90800f8 15392 [(set_attr "type" "str")
6ef67412
JH
15393 (set_attr "prefix_rep" "1")
15394 (set_attr "memory" "both")
15395 (set_attr "mode" "SI")])
886c62d1 15396
57e84f18 15397(define_expand "setmemsi"
e2e52e1b 15398 [(use (match_operand:BLK 0 "memory_operand" ""))
79f05c19 15399 (use (match_operand:SI 1 "nonmemory_operand" ""))
57e84f18 15400 (use (match_operand 2 "const_int_operand" ""))
079a182e
JH
15401 (use (match_operand 3 "const_int_operand" ""))
15402 (use (match_operand:SI 4 "const_int_operand" ""))
15403 (use (match_operand:SI 5 "const_int_operand" ""))]
0ae40045 15404 ""
0ae40045 15405{
8c996513
JH
15406 if (ix86_expand_setmem (operands[0], operands[1],
15407 operands[2], operands[3],
079a182e 15408 operands[4], operands[5]))
0945b39d
JH
15409 DONE;
15410 else
15411 FAIL;
0f40f9f7 15412})
e2e52e1b 15413
57e84f18 15414(define_expand "setmemdi"
0945b39d
JH
15415 [(use (match_operand:BLK 0 "memory_operand" ""))
15416 (use (match_operand:DI 1 "nonmemory_operand" ""))
57e84f18 15417 (use (match_operand 2 "const_int_operand" ""))
8c996513
JH
15418 (use (match_operand 3 "const_int_operand" ""))
15419 (use (match_operand 4 "const_int_operand" ""))
15420 (use (match_operand 5 "const_int_operand" ""))]
0945b39d 15421 "TARGET_64BIT"
0945b39d 15422{
8c996513
JH
15423 if (ix86_expand_setmem (operands[0], operands[1],
15424 operands[2], operands[3],
079a182e 15425 operands[4], operands[5]))
0945b39d
JH
15426 DONE;
15427 else
15428 FAIL;
0f40f9f7 15429})
e2e52e1b 15430
0945b39d
JH
15431;; Most CPUs don't like single string operations
15432;; Handle this case here to simplify previous expander.
79f05c19 15433
4e44c1ef
JJ
15434(define_expand "strset"
15435 [(set (match_operand 1 "memory_operand" "")
15436 (match_operand 2 "register_operand" ""))
15437 (parallel [(set (match_operand 0 "register_operand" "")
15438 (match_dup 3))
8bc527af 15439 (clobber (reg:CC FLAGS_REG))])]
79f05c19 15440 ""
79f05c19 15441{
4e44c1ef
JJ
15442 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15443 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
79f05c19 15444
4e44c1ef
JJ
15445 /* If .md ever supports :P for Pmode, this can be directly
15446 in the pattern above. */
15447 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15448 GEN_INT (GET_MODE_SIZE (GET_MODE
15449 (operands[2]))));
18bd082d 15450 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
0945b39d 15451 {
4e44c1ef
JJ
15452 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15453 operands[3]));
0945b39d
JH
15454 DONE;
15455 }
0f40f9f7 15456})
0945b39d 15457
4e44c1ef
JJ
15458(define_expand "strset_singleop"
15459 [(parallel [(set (match_operand 1 "memory_operand" "")
15460 (match_operand 2 "register_operand" ""))
15461 (set (match_operand 0 "register_operand" "")
90c56b45 15462 (match_operand 3 "" ""))])]
bdfd2026 15463 ""
922e3e33 15464 "ix86_current_function_needs_cld = 1;")
0945b39d 15465
4e44c1ef 15466(define_insn "*strsetdi_rex_1"
22116d84
L
15467 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15468 (match_operand:DI 2 "register_operand" "a"))
0945b39d
JH
15469 (set (match_operand:DI 0 "register_operand" "=D")
15470 (plus:DI (match_dup 1)
90c56b45 15471 (const_int 8)))]
bdfd2026 15472 "TARGET_64BIT"
0945b39d
JH
15473 "stosq"
15474 [(set_attr "type" "str")
15475 (set_attr "memory" "store")
15476 (set_attr "mode" "DI")])
15477
4e44c1ef 15478(define_insn "*strsetsi_1"
79f05c19
JH
15479 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15480 (match_operand:SI 2 "register_operand" "a"))
15481 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 15482 (plus:SI (match_dup 1)
90c56b45 15483 (const_int 4)))]
bdfd2026 15484 "!TARGET_64BIT"
62d2739a 15485 "stos{l|d}"
0945b39d
JH
15486 [(set_attr "type" "str")
15487 (set_attr "memory" "store")
15488 (set_attr "mode" "SI")])
15489
4e44c1ef 15490(define_insn "*strsetsi_rex_1"
0945b39d
JH
15491 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15492 (match_operand:SI 2 "register_operand" "a"))
15493 (set (match_operand:DI 0 "register_operand" "=D")
15494 (plus:DI (match_dup 1)
90c56b45 15495 (const_int 4)))]
bdfd2026 15496 "TARGET_64BIT"
62d2739a 15497 "stos{l|d}"
79f05c19 15498 [(set_attr "type" "str")
6ef67412
JH
15499 (set_attr "memory" "store")
15500 (set_attr "mode" "SI")])
79f05c19 15501
4e44c1ef 15502(define_insn "*strsethi_1"
e2e52e1b
JH
15503 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15504 (match_operand:HI 2 "register_operand" "a"))
15505 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 15506 (plus:SI (match_dup 1)
90c56b45 15507 (const_int 2)))]
bdfd2026 15508 "!TARGET_64BIT"
0945b39d
JH
15509 "stosw"
15510 [(set_attr "type" "str")
15511 (set_attr "memory" "store")
15512 (set_attr "mode" "HI")])
15513
4e44c1ef 15514(define_insn "*strsethi_rex_1"
0945b39d
JH
15515 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15516 (match_operand:HI 2 "register_operand" "a"))
15517 (set (match_operand:DI 0 "register_operand" "=D")
15518 (plus:DI (match_dup 1)
90c56b45 15519 (const_int 2)))]
bdfd2026 15520 "TARGET_64BIT"
e2e52e1b
JH
15521 "stosw"
15522 [(set_attr "type" "str")
15523 (set_attr "memory" "store")
6ef67412 15524 (set_attr "mode" "HI")])
e2e52e1b 15525
4e44c1ef 15526(define_insn "*strsetqi_1"
e2e52e1b
JH
15527 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15528 (match_operand:QI 2 "register_operand" "a"))
15529 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 15530 (plus:SI (match_dup 1)
90c56b45 15531 (const_int 1)))]
bdfd2026 15532 "!TARGET_64BIT"
0945b39d
JH
15533 "stosb"
15534 [(set_attr "type" "str")
15535 (set_attr "memory" "store")
15536 (set_attr "mode" "QI")])
15537
4e44c1ef 15538(define_insn "*strsetqi_rex_1"
0945b39d
JH
15539 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15540 (match_operand:QI 2 "register_operand" "a"))
15541 (set (match_operand:DI 0 "register_operand" "=D")
15542 (plus:DI (match_dup 1)
90c56b45 15543 (const_int 1)))]
bdfd2026 15544 "TARGET_64BIT"
e2e52e1b
JH
15545 "stosb"
15546 [(set_attr "type" "str")
6ef67412 15547 (set_attr "memory" "store")
a952487c 15548 (set_attr "prefix_rex" "0")
6ef67412 15549 (set_attr "mode" "QI")])
e2e52e1b 15550
4e44c1ef
JJ
15551(define_expand "rep_stos"
15552 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15553 (set (match_operand 0 "register_operand" "")
15554 (match_operand 4 "" ""))
15555 (set (match_operand 2 "memory_operand" "") (const_int 0))
15556 (use (match_operand 3 "register_operand" ""))
90c56b45 15557 (use (match_dup 1))])]
4e44c1ef 15558 ""
922e3e33 15559 "ix86_current_function_needs_cld = 1;")
4e44c1ef
JJ
15560
15561(define_insn "*rep_stosdi_rex64"
0945b39d 15562 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
6300f037 15563 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
15564 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15565 (const_int 3))
15566 (match_operand:DI 3 "register_operand" "0")))
15567 (set (mem:BLK (match_dup 3))
15568 (const_int 0))
15569 (use (match_operand:DI 2 "register_operand" "a"))
90c56b45 15570 (use (match_dup 4))]
0945b39d 15571 "TARGET_64BIT"
2433310d 15572 "rep{%;} stosq"
0945b39d
JH
15573 [(set_attr "type" "str")
15574 (set_attr "prefix_rep" "1")
15575 (set_attr "memory" "store")
15576 (set_attr "mode" "DI")])
15577
4e44c1ef 15578(define_insn "*rep_stossi"
e2e52e1b 15579 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
6300f037 15580 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
15581 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15582 (const_int 2))
15583 (match_operand:SI 3 "register_operand" "0")))
e2e52e1b 15584 (set (mem:BLK (match_dup 3))
0ae40045 15585 (const_int 0))
b1cdafbb 15586 (use (match_operand:SI 2 "register_operand" "a"))
90c56b45 15587 (use (match_dup 4))]
0945b39d 15588 "!TARGET_64BIT"
2433310d 15589 "rep{%;} stos{l|d}"
0945b39d
JH
15590 [(set_attr "type" "str")
15591 (set_attr "prefix_rep" "1")
15592 (set_attr "memory" "store")
15593 (set_attr "mode" "SI")])
15594
4e44c1ef 15595(define_insn "*rep_stossi_rex64"
0945b39d 15596 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
6300f037 15597 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
15598 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15599 (const_int 2))
15600 (match_operand:DI 3 "register_operand" "0")))
15601 (set (mem:BLK (match_dup 3))
15602 (const_int 0))
15603 (use (match_operand:SI 2 "register_operand" "a"))
90c56b45 15604 (use (match_dup 4))]
0945b39d 15605 "TARGET_64BIT"
2433310d 15606 "rep{%;} stos{l|d}"
e2e52e1b 15607 [(set_attr "type" "str")
6ef67412
JH
15608 (set_attr "prefix_rep" "1")
15609 (set_attr "memory" "store")
15610 (set_attr "mode" "SI")])
0ae40045 15611
4e44c1ef 15612(define_insn "*rep_stosqi"
e2e52e1b 15613 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
6300f037 15614 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
15615 (plus:SI (match_operand:SI 3 "register_operand" "0")
15616 (match_operand:SI 4 "register_operand" "1")))
e2e52e1b
JH
15617 (set (mem:BLK (match_dup 3))
15618 (const_int 0))
b1cdafbb 15619 (use (match_operand:QI 2 "register_operand" "a"))
90c56b45 15620 (use (match_dup 4))]
0945b39d 15621 "!TARGET_64BIT"
2433310d 15622 "rep{%;} stosb"
0945b39d
JH
15623 [(set_attr "type" "str")
15624 (set_attr "prefix_rep" "1")
15625 (set_attr "memory" "store")
15626 (set_attr "mode" "QI")])
15627
4e44c1ef 15628(define_insn "*rep_stosqi_rex64"
0945b39d 15629 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
6300f037 15630 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
15631 (plus:DI (match_operand:DI 3 "register_operand" "0")
15632 (match_operand:DI 4 "register_operand" "1")))
15633 (set (mem:BLK (match_dup 3))
15634 (const_int 0))
15635 (use (match_operand:QI 2 "register_operand" "a"))
90c56b45 15636 (use (match_dup 4))]
0945b39d 15637 "TARGET_64BIT"
2433310d 15638 "rep{%;} stosb"
e2e52e1b 15639 [(set_attr "type" "str")
6ef67412
JH
15640 (set_attr "prefix_rep" "1")
15641 (set_attr "memory" "store")
a952487c 15642 (set_attr "prefix_rex" "0")
6ef67412 15643 (set_attr "mode" "QI")])
0ae40045 15644
40c1d5f8 15645(define_expand "cmpstrnsi"
e075ae69
RH
15646 [(set (match_operand:SI 0 "register_operand" "")
15647 (compare:SI (match_operand:BLK 1 "general_operand" "")
15648 (match_operand:BLK 2 "general_operand" "")))
0945b39d
JH
15649 (use (match_operand 3 "general_operand" ""))
15650 (use (match_operand 4 "immediate_operand" ""))]
18bd082d 15651 ""
886c62d1 15652{
e075ae69
RH
15653 rtx addr1, addr2, out, outlow, count, countreg, align;
15654
18bd082d
JH
15655 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15656 FAIL;
15657
d0a5295a 15658 /* Can't use this if the user has appropriated esi or edi. */
ec382b8c 15659 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
d0a5295a
RH
15660 FAIL;
15661
e075ae69 15662 out = operands[0];
7656aee4 15663 if (!REG_P (out))
e075ae69 15664 out = gen_reg_rtx (SImode);
783cdf65
JVA
15665
15666 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15667 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
4e44c1ef
JJ
15668 if (addr1 != XEXP (operands[1], 0))
15669 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15670 if (addr2 != XEXP (operands[2], 0))
15671 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15672
e075ae69 15673 count = operands[3];
d24b3457 15674 countreg = ix86_zero_extend_to_Pmode (count);
e075ae69
RH
15675
15676 /* %%% Iff we are testing strict equality, we can use known alignment
15677 to good advantage. This may be possible with combine, particularly
15678 once cc0 is dead. */
15679 align = operands[4];
783cdf65 15680
7656aee4 15681 if (CONST_INT_P (count))
e075ae69
RH
15682 {
15683 if (INTVAL (count) == 0)
15684 {
15685 emit_move_insn (operands[0], const0_rtx);
15686 DONE;
15687 }
40c1d5f8
AS
15688 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15689 operands[1], operands[2]));
e075ae69
RH
15690 }
15691 else
e2e52e1b 15692 {
9aa5922d 15693 rtx (*gen_cmp) (rtx, rtx);
a81f2330 15694
9aa5922d
UB
15695 gen_cmp = (TARGET_64BIT
15696 ? gen_cmpdi_1 : gen_cmpsi_1);
15697
15698 emit_insn (gen_cmp (countreg, countreg));
40c1d5f8
AS
15699 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15700 operands[1], operands[2]));
e2e52e1b 15701 }
e075ae69
RH
15702
15703 outlow = gen_lowpart (QImode, out);
15704 emit_insn (gen_cmpintqi (outlow));
15705 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
783cdf65 15706
e075ae69
RH
15707 if (operands[0] != out)
15708 emit_move_insn (operands[0], out);
783cdf65 15709
e075ae69 15710 DONE;
0f40f9f7 15711})
886c62d1 15712
e075ae69
RH
15713;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15714
15715(define_expand "cmpintqi"
15716 [(set (match_dup 1)
8bc527af 15717 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
e075ae69 15718 (set (match_dup 2)
8bc527af 15719 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
e075ae69
RH
15720 (parallel [(set (match_operand:QI 0 "register_operand" "")
15721 (minus:QI (match_dup 1)
15722 (match_dup 2)))
8bc527af 15723 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
15724 ""
15725 "operands[1] = gen_reg_rtx (QImode);
15726 operands[2] = gen_reg_rtx (QImode);")
15727
f76e3b05
JVA
15728;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15729;; zero. Emit extra code to make sure that a zero-length compare is EQ.
56c0e8fa 15730
40c1d5f8 15731(define_expand "cmpstrnqi_nz_1"
8bc527af 15732 [(parallel [(set (reg:CC FLAGS_REG)
4e44c1ef
JJ
15733 (compare:CC (match_operand 4 "memory_operand" "")
15734 (match_operand 5 "memory_operand" "")))
15735 (use (match_operand 2 "register_operand" ""))
15736 (use (match_operand:SI 3 "immediate_operand" ""))
4e44c1ef
JJ
15737 (clobber (match_operand 0 "register_operand" ""))
15738 (clobber (match_operand 1 "register_operand" ""))
15739 (clobber (match_dup 2))])]
15740 ""
922e3e33 15741 "ix86_current_function_needs_cld = 1;")
4e44c1ef 15742
40c1d5f8 15743(define_insn "*cmpstrnqi_nz_1"
8bc527af 15744 [(set (reg:CC FLAGS_REG)
b1cdafbb
JH
15745 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15746 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15747 (use (match_operand:SI 6 "register_operand" "2"))
886c62d1 15748 (use (match_operand:SI 3 "immediate_operand" "i"))
b1cdafbb
JH
15749 (clobber (match_operand:SI 0 "register_operand" "=S"))
15750 (clobber (match_operand:SI 1 "register_operand" "=D"))
15751 (clobber (match_operand:SI 2 "register_operand" "=c"))]
0945b39d 15752 "!TARGET_64BIT"
2433310d 15753 "repz{%;} cmpsb"
0945b39d
JH
15754 [(set_attr "type" "str")
15755 (set_attr "mode" "QI")
15756 (set_attr "prefix_rep" "1")])
15757
40c1d5f8 15758(define_insn "*cmpstrnqi_nz_rex_1"
8bc527af 15759 [(set (reg:CC FLAGS_REG)
0945b39d
JH
15760 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15761 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15762 (use (match_operand:DI 6 "register_operand" "2"))
15763 (use (match_operand:SI 3 "immediate_operand" "i"))
0945b39d
JH
15764 (clobber (match_operand:DI 0 "register_operand" "=S"))
15765 (clobber (match_operand:DI 1 "register_operand" "=D"))
15766 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15767 "TARGET_64BIT"
2433310d 15768 "repz{%;} cmpsb"
e2e52e1b 15769 [(set_attr "type" "str")
6ef67412 15770 (set_attr "mode" "QI")
a952487c 15771 (set_attr "prefix_rex" "0")
6ef67412 15772 (set_attr "prefix_rep" "1")])
886c62d1 15773
e075ae69 15774;; The same, but the count is not known to not be zero.
886c62d1 15775
40c1d5f8 15776(define_expand "cmpstrnqi_1"
8bc527af 15777 [(parallel [(set (reg:CC FLAGS_REG)
4e44c1ef
JJ
15778 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15779 (const_int 0))
15780 (compare:CC (match_operand 4 "memory_operand" "")
15781 (match_operand 5 "memory_operand" ""))
15782 (const_int 0)))
15783 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af 15784 (use (reg:CC FLAGS_REG))
4e44c1ef
JJ
15785 (clobber (match_operand 0 "register_operand" ""))
15786 (clobber (match_operand 1 "register_operand" ""))
15787 (clobber (match_dup 2))])]
15788 ""
922e3e33 15789 "ix86_current_function_needs_cld = 1;")
4e44c1ef 15790
40c1d5f8 15791(define_insn "*cmpstrnqi_1"
8bc527af 15792 [(set (reg:CC FLAGS_REG)
b1cdafbb 15793 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
e075ae69 15794 (const_int 0))
2bed3391 15795 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
b1cdafbb 15796 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
e075ae69
RH
15797 (const_int 0)))
15798 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af 15799 (use (reg:CC FLAGS_REG))
b1cdafbb
JH
15800 (clobber (match_operand:SI 0 "register_operand" "=S"))
15801 (clobber (match_operand:SI 1 "register_operand" "=D"))
15802 (clobber (match_operand:SI 2 "register_operand" "=c"))]
0945b39d 15803 "!TARGET_64BIT"
2433310d 15804 "repz{%;} cmpsb"
0945b39d
JH
15805 [(set_attr "type" "str")
15806 (set_attr "mode" "QI")
15807 (set_attr "prefix_rep" "1")])
15808
40c1d5f8 15809(define_insn "*cmpstrnqi_rex_1"
8bc527af 15810 [(set (reg:CC FLAGS_REG)
0945b39d
JH
15811 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15812 (const_int 0))
15813 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15814 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15815 (const_int 0)))
15816 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af 15817 (use (reg:CC FLAGS_REG))
0945b39d
JH
15818 (clobber (match_operand:DI 0 "register_operand" "=S"))
15819 (clobber (match_operand:DI 1 "register_operand" "=D"))
15820 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15821 "TARGET_64BIT"
2433310d 15822 "repz{%;} cmpsb"
e2e52e1b 15823 [(set_attr "type" "str")
6ef67412 15824 (set_attr "mode" "QI")
a952487c 15825 (set_attr "prefix_rex" "0")
6ef67412 15826 (set_attr "prefix_rep" "1")])
886c62d1 15827
e075ae69
RH
15828(define_expand "strlensi"
15829 [(set (match_operand:SI 0 "register_operand" "")
15830 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15831 (match_operand:QI 2 "immediate_operand" "")
8ee41eaf 15832 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
886c62d1 15833 ""
886c62d1 15834{
0945b39d
JH
15835 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15836 DONE;
15837 else
15838 FAIL;
0f40f9f7 15839})
e075ae69 15840
0945b39d
JH
15841(define_expand "strlendi"
15842 [(set (match_operand:DI 0 "register_operand" "")
15843 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15844 (match_operand:QI 2 "immediate_operand" "")
8ee41eaf 15845 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
0945b39d 15846 ""
0945b39d
JH
15847{
15848 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15849 DONE;
15850 else
15851 FAIL;
0f40f9f7 15852})
19c3fc24 15853
4e44c1ef
JJ
15854(define_expand "strlenqi_1"
15855 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
4e44c1ef 15856 (clobber (match_operand 1 "register_operand" ""))
8bc527af 15857 (clobber (reg:CC FLAGS_REG))])]
4e44c1ef 15858 ""
922e3e33 15859 "ix86_current_function_needs_cld = 1;")
4e44c1ef
JJ
15860
15861(define_insn "*strlenqi_1"
e075ae69 15862 [(set (match_operand:SI 0 "register_operand" "=&c")
b1cdafbb 15863 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
0945b39d 15864 (match_operand:QI 2 "register_operand" "a")
e075ae69 15865 (match_operand:SI 3 "immediate_operand" "i")
8ee41eaf 15866 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
b1cdafbb 15867 (clobber (match_operand:SI 1 "register_operand" "=D"))
8bc527af 15868 (clobber (reg:CC FLAGS_REG))]
0945b39d 15869 "!TARGET_64BIT"
2433310d 15870 "repnz{%;} scasb"
0945b39d
JH
15871 [(set_attr "type" "str")
15872 (set_attr "mode" "QI")
15873 (set_attr "prefix_rep" "1")])
15874
4e44c1ef 15875(define_insn "*strlenqi_rex_1"
0945b39d
JH
15876 [(set (match_operand:DI 0 "register_operand" "=&c")
15877 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15878 (match_operand:QI 2 "register_operand" "a")
15879 (match_operand:DI 3 "immediate_operand" "i")
8ee41eaf 15880 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
0945b39d 15881 (clobber (match_operand:DI 1 "register_operand" "=D"))
8bc527af 15882 (clobber (reg:CC FLAGS_REG))]
0945b39d 15883 "TARGET_64BIT"
2433310d 15884 "repnz{%;} scasb"
e2e52e1b 15885 [(set_attr "type" "str")
6ef67412 15886 (set_attr "mode" "QI")
a952487c 15887 (set_attr "prefix_rex" "0")
6ef67412 15888 (set_attr "prefix_rep" "1")])
a3e991f2 15889
40c1d5f8 15890;; Peephole optimizations to clean up after cmpstrn*. This should be
a3e991f2 15891;; handled in combine, but it is not currently up to the task.
40c1d5f8 15892;; When used for their truth value, the cmpstrn* expanders generate
a3e991f2
ZW
15893;; code like this:
15894;;
15895;; repz cmpsb
15896;; seta %al
15897;; setb %dl
15898;; cmpb %al, %dl
15899;; jcc label
15900;;
15901;; The intermediate three instructions are unnecessary.
15902
40c1d5f8 15903;; This one handles cmpstrn*_nz_1...
a3e991f2
ZW
15904(define_peephole2
15905 [(parallel[
8bc527af 15906 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
15907 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15908 (mem:BLK (match_operand 5 "register_operand" ""))))
15909 (use (match_operand 6 "register_operand" ""))
15910 (use (match_operand:SI 3 "immediate_operand" ""))
a3e991f2
ZW
15911 (clobber (match_operand 0 "register_operand" ""))
15912 (clobber (match_operand 1 "register_operand" ""))
15913 (clobber (match_operand 2 "register_operand" ""))])
15914 (set (match_operand:QI 7 "register_operand" "")
8bc527af 15915 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
a3e991f2 15916 (set (match_operand:QI 8 "register_operand" "")
8bc527af 15917 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
42fabf21 15918 (set (reg FLAGS_REG)
a3e991f2
ZW
15919 (compare (match_dup 7) (match_dup 8)))
15920 ]
244ec848 15921 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
a3e991f2 15922 [(parallel[
8bc527af 15923 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
15924 (compare:CC (mem:BLK (match_dup 4))
15925 (mem:BLK (match_dup 5))))
15926 (use (match_dup 6))
15927 (use (match_dup 3))
a3e991f2
ZW
15928 (clobber (match_dup 0))
15929 (clobber (match_dup 1))
cfc20f00 15930 (clobber (match_dup 2))])])
a3e991f2 15931
40c1d5f8 15932;; ...and this one handles cmpstrn*_1.
a3e991f2
ZW
15933(define_peephole2
15934 [(parallel[
8bc527af 15935 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
15936 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15937 (const_int 0))
15938 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15939 (mem:BLK (match_operand 5 "register_operand" "")))
15940 (const_int 0)))
15941 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af 15942 (use (reg:CC FLAGS_REG))
a3e991f2
ZW
15943 (clobber (match_operand 0 "register_operand" ""))
15944 (clobber (match_operand 1 "register_operand" ""))
15945 (clobber (match_operand 2 "register_operand" ""))])
15946 (set (match_operand:QI 7 "register_operand" "")
8bc527af 15947 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
a3e991f2 15948 (set (match_operand:QI 8 "register_operand" "")
8bc527af 15949 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
42fabf21 15950 (set (reg FLAGS_REG)
a3e991f2
ZW
15951 (compare (match_dup 7) (match_dup 8)))
15952 ]
244ec848 15953 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
a3e991f2 15954 [(parallel[
8bc527af 15955 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
15956 (if_then_else:CC (ne (match_dup 6)
15957 (const_int 0))
15958 (compare:CC (mem:BLK (match_dup 4))
15959 (mem:BLK (match_dup 5)))
15960 (const_int 0)))
15961 (use (match_dup 3))
8bc527af 15962 (use (reg:CC FLAGS_REG))
a3e991f2
ZW
15963 (clobber (match_dup 0))
15964 (clobber (match_dup 1))
cfc20f00 15965 (clobber (match_dup 2))])])
e075ae69
RH
15966\f
15967;; Conditional move instructions.
726e2d54 15968
bfb59746
UB
15969(define_expand "mov<mode>cc"
15970 [(set (match_operand:SWIM 0 "register_operand" "")
f53ea4f0 15971 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
bfb59746
UB
15972 (match_operand:SWIM 2 "general_operand" "")
15973 (match_operand:SWIM 3 "general_operand" "")))]
15974 ""
85845bb9 15975 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
885a70fd 15976
bfb59746
UB
15977;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15978;; the register first winds up with `sbbl $0,reg', which is also weird.
15979;; So just document what we're doing explicitly.
15980
c84f4042
UB
15981(define_expand "x86_mov<mode>cc_0_m1"
15982 [(parallel
15983 [(set (match_operand:SWI48 0 "register_operand" "")
15984 (if_then_else:SWI48
15985 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15986 [(match_operand 1 "flags_reg_operand" "")
15987 (const_int 0)])
15988 (const_int -1)
15989 (const_int 0)))
a427621f 15990 (clobber (reg:CC FLAGS_REG))])])
c84f4042
UB
15991
15992(define_insn "*x86_mov<mode>cc_0_m1"
bfb59746 15993 [(set (match_operand:SWI48 0 "register_operand" "=r")
c84f4042
UB
15994 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15995 [(reg FLAGS_REG) (const_int 0)])
885a70fd
JH
15996 (const_int -1)
15997 (const_int 0)))
8bc527af 15998 (clobber (reg:CC FLAGS_REG))]
bfb59746
UB
15999 ""
16000 "sbb{<imodesuffix>}\t%0, %0"
885a70fd
JH
16001 ; Since we don't have the proper number of operands for an alu insn,
16002 ; fill in all the blanks.
16003 [(set_attr "type" "alu")
b6837b94 16004 (set_attr "use_carry" "1")
890d52e8 16005 (set_attr "pent_pair" "pu")
885a70fd
JH
16006 (set_attr "memory" "none")
16007 (set_attr "imm_disp" "false")
bfb59746 16008 (set_attr "mode" "<MODE>")
0e93e1b4
UB
16009 (set_attr "length_immediate" "0")])
16010
bfb59746
UB
16011(define_insn "*x86_mov<mode>cc_0_m1_se"
16012 [(set (match_operand:SWI48 0 "register_operand" "=r")
c84f4042
UB
16013 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16014 [(reg FLAGS_REG) (const_int 0)])
bfb59746
UB
16015 (const_int 1)
16016 (const_int 0)))
8bc527af 16017 (clobber (reg:CC FLAGS_REG))]
e075ae69 16018 ""
bfb59746 16019 "sbb{<imodesuffix>}\t%0, %0"
e075ae69 16020 [(set_attr "type" "alu")
b6837b94 16021 (set_attr "use_carry" "1")
890d52e8 16022 (set_attr "pent_pair" "pu")
e075ae69
RH
16023 (set_attr "memory" "none")
16024 (set_attr "imm_disp" "false")
bfb59746 16025 (set_attr "mode" "<MODE>")
6ef67412 16026 (set_attr "length_immediate" "0")])
e075ae69 16027
bfb59746
UB
16028(define_insn "*x86_mov<mode>cc_0_m1_neg"
16029 [(set (match_operand:SWI48 0 "register_operand" "=r")
c84f4042
UB
16030 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16031 [(reg FLAGS_REG) (const_int 0)])))]
0e93e1b4 16032 ""
bfb59746 16033 "sbb{<imodesuffix>}\t%0, %0"
0e93e1b4 16034 [(set_attr "type" "alu")
b6837b94 16035 (set_attr "use_carry" "1")
0e93e1b4
UB
16036 (set_attr "pent_pair" "pu")
16037 (set_attr "memory" "none")
16038 (set_attr "imm_disp" "false")
bfb59746 16039 (set_attr "mode" "<MODE>")
0e93e1b4
UB
16040 (set_attr "length_immediate" "0")])
16041
bfb59746
UB
16042(define_insn "*mov<mode>cc_noc"
16043 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16044 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16045 [(reg FLAGS_REG) (const_int 0)])
16046 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16047 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16048 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
e075ae69 16049 "@
048b1c95
JJ
16050 cmov%O2%C1\t{%2, %0|%0, %2}
16051 cmov%O2%c1\t{%3, %0|%0, %3}"
6ef67412 16052 [(set_attr "type" "icmov")
bfb59746 16053 (set_attr "mode" "<MODE>")])
4977bab6
ZW
16054
16055(define_insn_and_split "*movqicc_noc"
16056 [(set (match_operand:QI 0 "register_operand" "=r,r")
6300f037 16057 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
bfb59746
UB
16058 [(match_operand 4 "flags_reg_operand" "")
16059 (const_int 0)])
4977bab6
ZW
16060 (match_operand:QI 2 "register_operand" "r,0")
16061 (match_operand:QI 3 "register_operand" "0,r")))]
16062 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16063 "#"
16064 "&& reload_completed"
16065 [(set (match_dup 0)
16066 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16067 (match_dup 2)
16068 (match_dup 3)))]
16069 "operands[0] = gen_lowpart (SImode, operands[0]);
16070 operands[2] = gen_lowpart (SImode, operands[2]);
16071 operands[3] = gen_lowpart (SImode, operands[3]);"
16072 [(set_attr "type" "icmov")
16073 (set_attr "mode" "SI")])
16074
85845bb9
UB
16075(define_expand "mov<mode>cc"
16076 [(set (match_operand:X87MODEF 0 "register_operand" "")
16077 (if_then_else:X87MODEF
0948ccb2 16078 (match_operand 1 "ix86_fp_comparison_operator" "")
85845bb9
UB
16079 (match_operand:X87MODEF 2 "register_operand" "")
16080 (match_operand:X87MODEF 3 "register_operand" "")))]
16081 "(TARGET_80387 && TARGET_CMOVE)
16082 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16083 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
726e2d54 16084
eaa49b49 16085(define_insn "*movsfcc_1_387"
b5c82fa1 16086 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
6300f037 16087 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
42fabf21 16088 [(reg FLAGS_REG) (const_int 0)])
b5c82fa1
PB
16089 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16090 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
eaa49b49 16091 "TARGET_80387 && TARGET_CMOVE
7656aee4 16092 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
e075ae69 16093 "@
0f40f9f7
ZW
16094 fcmov%F1\t{%2, %0|%0, %2}
16095 fcmov%f1\t{%3, %0|%0, %3}
048b1c95
JJ
16096 cmov%O2%C1\t{%2, %0|%0, %2}
16097 cmov%O2%c1\t{%3, %0|%0, %3}"
7093c9ea
JH
16098 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16099 (set_attr "mode" "SF,SF,SI,SI")])
56710e42 16100
6343a50e 16101(define_insn "*movdfcc_1"
b5c82fa1 16102 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
6300f037 16103 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
42fabf21 16104 [(reg FLAGS_REG) (const_int 0)])
b5c82fa1
PB
16105 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16106 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
eaa49b49 16107 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
7656aee4 16108 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
e075ae69 16109 "@
0f40f9f7
ZW
16110 fcmov%F1\t{%2, %0|%0, %2}
16111 fcmov%f1\t{%3, %0|%0, %3}
7093c9ea
JH
16112 #
16113 #"
16114 [(set_attr "type" "fcmov,fcmov,multi,multi")
6ef67412 16115 (set_attr "mode" "DF")])
56710e42 16116
1e07edd3 16117(define_insn "*movdfcc_1_rex64"
b5c82fa1 16118 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
6300f037 16119 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
42fabf21 16120 [(reg FLAGS_REG) (const_int 0)])
b5c82fa1
PB
16121 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16122 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
eaa49b49 16123 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
7656aee4 16124 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
1e07edd3 16125 "@
0f40f9f7
ZW
16126 fcmov%F1\t{%2, %0|%0, %2}
16127 fcmov%f1\t{%3, %0|%0, %3}
048b1c95
JJ
16128 cmov%O2%C1\t{%2, %0|%0, %2}
16129 cmov%O2%c1\t{%3, %0|%0, %3}"
1e07edd3
JH
16130 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16131 (set_attr "mode" "DF")])
16132
7093c9ea 16133(define_split
c3c637e3 16134 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
6300f037 16135 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
eaa49b49
RH
16136 [(match_operand 4 "flags_reg_operand" "")
16137 (const_int 0)])
7093c9ea
JH
16138 (match_operand:DF 2 "nonimmediate_operand" "")
16139 (match_operand:DF 3 "nonimmediate_operand" "")))]
c3c637e3 16140 "!TARGET_64BIT && reload_completed"
7093c9ea
JH
16141 [(set (match_dup 2)
16142 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16143 (match_dup 5)
c2b814b9 16144 (match_dup 6)))
7093c9ea
JH
16145 (set (match_dup 3)
16146 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
c2b814b9 16147 (match_dup 7)
7093c9ea 16148 (match_dup 8)))]
6a0447ba 16149{
b146446c
UB
16150 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16151 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
6a0447ba 16152})
7093c9ea 16153
6343a50e 16154(define_insn "*movxfcc_1"
3aeae608 16155 [(set (match_operand:XF 0 "register_operand" "=f,f")
6300f037 16156 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
42fabf21 16157 [(reg FLAGS_REG) (const_int 0)])
3aeae608
JW
16158 (match_operand:XF 2 "register_operand" "f,0")
16159 (match_operand:XF 3 "register_operand" "0,f")))]
eaa49b49 16160 "TARGET_80387 && TARGET_CMOVE"
2b589241 16161 "@
0f40f9f7
ZW
16162 fcmov%F1\t{%2, %0|%0, %2}
16163 fcmov%f1\t{%3, %0|%0, %3}"
2b589241
JH
16164 [(set_attr "type" "fcmov")
16165 (set_attr "mode" "XF")])
7ada6625 16166
43a8b705
HJ
16167;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16168;; the scalar versions to have only XMM registers as operands.
16169
16170;; XOP conditional move
16171(define_insn "*xop_pcmov_<mode>"
16172 [(set (match_operand:MODEF 0 "register_operand" "=x")
16173 (if_then_else:MODEF
16174 (match_operand:MODEF 1 "register_operand" "x")
16175 (match_operand:MODEF 2 "register_operand" "x")
16176 (match_operand:MODEF 3 "register_operand" "x")))]
4926bb1d 16177 "TARGET_XOP"
43a8b705
HJ
16178 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16179 [(set_attr "type" "sse4arg")])
16180
eaa49b49 16181;; These versions of the min/max patterns are intentionally ignorant of
35fd3193 16182;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
eaa49b49
RH
16183;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16184;; are undefined in this condition, we're certain this is correct.
7ada6625 16185
95879c72
L
16186(define_insn "*avx_<code><mode>3"
16187 [(set (match_operand:MODEF 0 "register_operand" "=x")
16188 (smaxmin:MODEF
16189 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16190 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16191 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4a5528cc 16192 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
95879c72
L
16193 [(set_attr "type" "sseadd")
16194 (set_attr "prefix" "vex")
16195 (set_attr "mode" "<MODE>")])
16196
78e8956b 16197(define_insn "<code><mode>3"
d6023b50 16198 [(set (match_operand:MODEF 0 "register_operand" "=x")
78e8956b 16199 (smaxmin:MODEF
d6023b50
UB
16200 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16201 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16202 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4a5528cc 16203 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
ab8efbd8 16204 [(set_attr "type" "sseadd")
d6023b50 16205 (set_attr "mode" "<MODE>")])
ab8efbd8
RH
16206
16207;; These versions of the min/max patterns implement exactly the operations
16208;; min = (op1 < op2 ? op1 : op2)
16209;; max = (!(op1 < op2) ? op1 : op2)
16210;; Their operands are not commutative, and thus they may be used in the
16211;; presence of -0.0 and NaN.
16212
95879c72
L
16213(define_insn "*avx_ieee_smin<mode>3"
16214 [(set (match_operand:MODEF 0 "register_operand" "=x")
16215 (unspec:MODEF
16216 [(match_operand:MODEF 1 "register_operand" "x")
16217 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16218 UNSPEC_IEEE_MIN))]
16219 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16220 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16221 [(set_attr "type" "sseadd")
16222 (set_attr "prefix" "vex")
16223 (set_attr "mode" "<MODE>")])
16224
d6023b50
UB
16225(define_insn "*ieee_smin<mode>3"
16226 [(set (match_operand:MODEF 0 "register_operand" "=x")
16227 (unspec:MODEF
16228 [(match_operand:MODEF 1 "register_operand" "0")
16229 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16230 UNSPEC_IEEE_MIN))]
16231 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16232 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
ab8efbd8 16233 [(set_attr "type" "sseadd")
d6023b50 16234 (set_attr "mode" "<MODE>")])
ab8efbd8 16235
95879c72
L
16236(define_insn "*avx_ieee_smax<mode>3"
16237 [(set (match_operand:MODEF 0 "register_operand" "=x")
16238 (unspec:MODEF
16239 [(match_operand:MODEF 1 "register_operand" "0")
16240 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16241 UNSPEC_IEEE_MAX))]
16242 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16243 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16244 [(set_attr "type" "sseadd")
16245 (set_attr "prefix" "vex")
16246 (set_attr "mode" "<MODE>")])
16247
d6023b50
UB
16248(define_insn "*ieee_smax<mode>3"
16249 [(set (match_operand:MODEF 0 "register_operand" "=x")
16250 (unspec:MODEF
16251 [(match_operand:MODEF 1 "register_operand" "0")
16252 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16253 UNSPEC_IEEE_MAX))]
16254 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16255 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
eaa49b49 16256 [(set_attr "type" "sseadd")
d6023b50 16257 (set_attr "mode" "<MODE>")])
7ada6625 16258
bab1de0a
PB
16259;; Make two stack loads independent:
16260;; fld aa fld aa
16261;; fld %st(0) -> fld bb
16262;; fmul bb fmul %st(1), %st
16263;;
16264;; Actually we only match the last two instructions for simplicity.
16265(define_peephole2
16266 [(set (match_operand 0 "fp_register_operand" "")
16267 (match_operand 1 "fp_register_operand" ""))
16268 (set (match_dup 0)
16269 (match_operator 2 "binary_fp_operator"
16270 [(match_dup 0)
16271 (match_operand 3 "memory_operand" "")]))]
16272 "REGNO (operands[0]) != REGNO (operands[1])"
16273 [(set (match_dup 0) (match_dup 3))
16274 (set (match_dup 0) (match_dup 4))]
16275
16276 ;; The % modifier is not operational anymore in peephole2's, so we have to
16277 ;; swap the operands manually in the case of addition and multiplication.
16278 "if (COMMUTATIVE_ARITH_P (operands[2]))
cfc20f00
UB
16279 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16280 GET_MODE (operands[2]),
16281 operands[0], operands[1]);
bab1de0a 16282 else
cfc20f00
UB
16283 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16284 GET_MODE (operands[2]),
16285 operands[1], operands[0]);")
bab1de0a 16286
7b52eede 16287;; Conditional addition patterns
62d2739a
UB
16288(define_expand "add<mode>cc"
16289 [(match_operand:SWI 0 "register_operand" "")
8aadc2f3 16290 (match_operand 1 "ordered_comparison_operator" "")
62d2739a
UB
16291 (match_operand:SWI 2 "register_operand" "")
16292 (match_operand:SWI 3 "const_int_operand" "")]
7b52eede 16293 ""
85845bb9 16294 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
e075ae69
RH
16295\f
16296;; Misc patterns (?)
726e2d54 16297
f5143c46 16298;; This pattern exists to put a dependency on all ebp-based memory accesses.
e075ae69 16299;; Otherwise there will be nothing to keep
6300f037 16300;;
e075ae69
RH
16301;; [(set (reg ebp) (reg esp))]
16302;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16303;; (clobber (eflags)]
16304;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16305;;
16306;; in proper program order.
578b58f5 16307
4470a3a3 16308(define_insn "pro_epilogue_adjust_stack_<mode>_add"
9aa5922d
UB
16309 [(set (match_operand:P 0 "register_operand" "=r,r")
16310 (plus:P (match_operand:P 1 "register_operand" "0,r")
4470a3a3 16311 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
8bc527af 16312 (clobber (reg:CC FLAGS_REG))
f2042df3 16313 (clobber (mem:BLK (scratch)))]
9aa5922d 16314 ""
8362f420
JH
16315{
16316 switch (get_attr_type (insn))
16317 {
16318 case TYPE_IMOV:
9aa5922d 16319 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
8362f420
JH
16320
16321 case TYPE_ALU:
3d25c396 16322 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9aa5922d
UB
16323 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16324 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
3d25c396 16325
9aa5922d 16326 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
8362f420 16327
3d25c396 16328 default:
8362f420 16329 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
9aa5922d 16330 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
8362f420 16331 }
0f40f9f7 16332}
8362f420 16333 [(set (attr "type")
b6837b94 16334 (cond [(and (eq_attr "alternative" "0")
9aa5922d 16335 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
8362f420 16336 (const_string "alu")
9aa5922d 16337 (match_operand:<MODE> 2 "const0_operand" "")
8362f420
JH
16338 (const_string "imov")
16339 ]
16340 (const_string "lea")))
a952487c
JJ
16341 (set (attr "length_immediate")
16342 (cond [(eq_attr "type" "imov")
16343 (const_string "0")
16344 (and (eq_attr "type" "alu")
16345 (match_operand 2 "const128_operand" ""))
16346 (const_string "1")
16347 ]
16348 (const_string "*")))
9aa5922d 16349 (set_attr "mode" "<MODE>")])
8362f420 16350
4470a3a3 16351(define_insn "pro_epilogue_adjust_stack_<mode>_sub"
174425ad
KT
16352 [(set (match_operand:P 0 "register_operand" "=r")
16353 (minus:P (match_operand:P 1 "register_operand" "0")
16354 (match_operand:P 2 "register_operand" "r")))
16355 (clobber (reg:CC FLAGS_REG))
16356 (clobber (mem:BLK (scratch)))]
16357 ""
16358 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16359 [(set_attr "type" "alu")
16360 (set_attr "mode" "<MODE>")])
885a70fd 16361
174425ad
KT
16362(define_insn "allocate_stack_worker_probe_<mode>"
16363 [(set (match_operand:P 0 "register_operand" "=a")
16364 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
6ea90eb7 16365 UNSPECV_STACK_PROBE))
8bc527af 16366 (clobber (reg:CC FLAGS_REG))]
174425ad
KT
16367 "ix86_target_stack_probe ()"
16368 "call\t___chkstk_ms"
e075ae69
RH
16369 [(set_attr "type" "multi")
16370 (set_attr "length" "5")])
578b58f5
RK
16371
16372(define_expand "allocate_stack"
ccf8e764
RH
16373 [(match_operand 0 "register_operand" "")
16374 (match_operand 1 "general_operand" "")]
2de710b9 16375 "ix86_target_stack_probe ()"
578b58f5 16376{
ccf8e764
RH
16377 rtx x;
16378
16379#ifndef CHECK_STACK_LIMIT
16380#define CHECK_STACK_LIMIT 0
16381#endif
16382
16383 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
e9a25f70 16384 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
ccf8e764
RH
16385 {
16386 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16387 stack_pointer_rtx, 0, OPTAB_DIRECT);
16388 if (x != stack_pointer_rtx)
16389 emit_move_insn (stack_pointer_rtx, x);
16390 }
6300f037 16391 else
ccf8e764 16392 {
174425ad 16393 x = copy_to_mode_reg (Pmode, operands[1]);
ccf8e764 16394 if (TARGET_64BIT)
174425ad 16395 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
ccf8e764 16396 else
174425ad
KT
16397 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16398 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16399 stack_pointer_rtx, 0, OPTAB_DIRECT);
16400 if (x != stack_pointer_rtx)
16401 emit_move_insn (stack_pointer_rtx, x);
ccf8e764 16402 }
578b58f5 16403
e9a25f70
JL
16404 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16405 DONE;
0f40f9f7 16406})
e31ca113 16407
35a07c37
EB
16408;; Use IOR for stack probes, this is shorter.
16409(define_expand "probe_stack"
16410 [(match_operand 0 "memory_operand" "")]
16411 ""
16412{
9aa5922d
UB
16413 rtx (*gen_ior3) (rtx, rtx, rtx);
16414
16415 gen_ior3 = (GET_MODE (operands[0]) == DImode
16416 ? gen_iordi3 : gen_iorsi3);
16417
16418 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
35a07c37
EB
16419 DONE;
16420})
16421
2de710b9
EB
16422(define_insn "adjust_stack_and_probe<mode>"
16423 [(set (match_operand:P 0 "register_operand" "=r")
16424 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16425 UNSPECV_PROBE_STACK_RANGE))
16426 (set (reg:P SP_REG)
16427 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16428 (clobber (reg:CC FLAGS_REG))
16429 (clobber (mem:BLK (scratch)))]
16430 ""
16431 "* return output_adjust_stack_and_probe (operands[0]);"
16432 [(set_attr "type" "multi")])
16433
16434(define_insn "probe_stack_range<mode>"
16435 [(set (match_operand:P 0 "register_operand" "=r")
16436 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16437 (match_operand:P 2 "const_int_operand" "n")]
16438 UNSPECV_PROBE_STACK_RANGE))
16439 (clobber (reg:CC FLAGS_REG))]
16440 ""
16441 "* return output_probe_stack_range (operands[0], operands[2]);"
16442 [(set_attr "type" "multi")])
16443
fb754025
AG
16444(define_expand "builtin_setjmp_receiver"
16445 [(label_ref (match_operand 0 "" ""))]
1b0c37d7 16446 "!TARGET_64BIT && flag_pic"
fb754025 16447{
08a6a74b 16448#if TARGET_MACHO
7d072037
SH
16449 if (TARGET_MACHO)
16450 {
16451 rtx xops[3];
16452 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16453 rtx label_rtx = gen_label_rtx ();
16454 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
7d072037 16455 xops[0] = xops[1] = picreg;
08a6a74b 16456 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
7d072037
SH
16457 ix86_expand_binary_operator (MINUS, SImode, xops);
16458 }
16459 else
08a6a74b 16460#endif
7d072037 16461 emit_insn (gen_set_got (pic_offset_table_rtx));
fb754025 16462 DONE;
0f40f9f7 16463})
e9e80858
JH
16464\f
16465;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16466
16467(define_split
16468 [(set (match_operand 0 "register_operand" "")
16469 (match_operator 3 "promotable_binary_operator"
16470 [(match_operand 1 "register_operand" "")
2247f6ed 16471 (match_operand 2 "aligned_operand" "")]))
8bc527af 16472 (clobber (reg:CC FLAGS_REG))]
e9e80858 16473 "! TARGET_PARTIAL_REG_STALL && reload_completed
6300f037 16474 && ((GET_MODE (operands[0]) == HImode
3debdc1e 16475 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
f38840db 16476 /* ??? next two lines just !satisfies_constraint_K (...) */
7656aee4 16477 || !CONST_INT_P (operands[2])
f38840db 16478 || satisfies_constraint_K (operands[2])))
6300f037 16479 || (GET_MODE (operands[0]) == QImode
3debdc1e 16480 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
e9e80858
JH
16481 [(parallel [(set (match_dup 0)
16482 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8bc527af 16483 (clobber (reg:CC FLAGS_REG))])]
e9e80858
JH
16484 "operands[0] = gen_lowpart (SImode, operands[0]);
16485 operands[1] = gen_lowpart (SImode, operands[1]);
16486 if (GET_CODE (operands[3]) != ASHIFT)
16487 operands[2] = gen_lowpart (SImode, operands[2]);
dbbbbf3b 16488 PUT_MODE (operands[3], SImode);")
e9e80858 16489
d2fc7725
EB
16490; Promote the QImode tests, as i386 has encoding of the AND
16491; instruction with 32-bit sign-extended immediate and thus the
16492; instruction size is unchanged, except in the %eax case for
16493; which it is increased by one byte, hence the ! optimize_size.
e9e80858 16494(define_split
25da5dc7
RH
16495 [(set (match_operand 0 "flags_reg_operand" "")
16496 (match_operator 2 "compare_operator"
16497 [(and (match_operand 3 "aligned_operand" "")
16498 (match_operand 4 "const_int_operand" ""))
16499 (const_int 0)]))
16500 (set (match_operand 1 "register_operand" "")
16501 (and (match_dup 3) (match_dup 4)))]
e9e80858 16502 "! TARGET_PARTIAL_REG_STALL && reload_completed
3debdc1e 16503 && optimize_insn_for_speed_p ()
25da5dc7 16504 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
d5d5d289
L
16505 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16506 /* Ensure that the operand will remain sign-extended immediate. */
16507 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
25da5dc7
RH
16508 [(parallel [(set (match_dup 0)
16509 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16510 (const_int 0)]))
16511 (set (match_dup 1)
16512 (and:SI (match_dup 3) (match_dup 4)))])]
16513{
16514 operands[4]
16515 = gen_int_mode (INTVAL (operands[4])
16516 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16517 operands[1] = gen_lowpart (SImode, operands[1]);
16518 operands[3] = gen_lowpart (SImode, operands[3]);
16519})
e9e80858 16520
d2fc7725
EB
16521; Don't promote the QImode tests, as i386 doesn't have encoding of
16522; the TEST instruction with 32-bit sign-extended immediate and thus
16523; the instruction size would at least double, which is not what we
16524; want even with ! optimize_size.
e9e80858 16525(define_split
25da5dc7
RH
16526 [(set (match_operand 0 "flags_reg_operand" "")
16527 (match_operator 1 "compare_operator"
16528 [(and (match_operand:HI 2 "aligned_operand" "")
16529 (match_operand:HI 3 "const_int_operand" ""))
16530 (const_int 0)]))]
e9e80858 16531 "! TARGET_PARTIAL_REG_STALL && reload_completed
d2fc7725 16532 && ! TARGET_FAST_PREFIX
b2077fd2 16533 && optimize_insn_for_speed_p ()
d5d5d289
L
16534 /* Ensure that the operand will remain sign-extended immediate. */
16535 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
25da5dc7
RH
16536 [(set (match_dup 0)
16537 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16538 (const_int 0)]))]
16539{
16540 operands[3]
16541 = gen_int_mode (INTVAL (operands[3])
16542 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16543 operands[2] = gen_lowpart (SImode, operands[2]);
16544})
e9e80858
JH
16545
16546(define_split
16547 [(set (match_operand 0 "register_operand" "")
16548 (neg (match_operand 1 "register_operand" "")))
8bc527af 16549 (clobber (reg:CC FLAGS_REG))]
e9e80858
JH
16550 "! TARGET_PARTIAL_REG_STALL && reload_completed
16551 && (GET_MODE (operands[0]) == HImode
6300f037 16552 || (GET_MODE (operands[0]) == QImode
b2077fd2
JH
16553 && (TARGET_PROMOTE_QImode
16554 || optimize_insn_for_size_p ())))"
e9e80858
JH
16555 [(parallel [(set (match_dup 0)
16556 (neg:SI (match_dup 1)))
8bc527af 16557 (clobber (reg:CC FLAGS_REG))])]
e9e80858
JH
16558 "operands[0] = gen_lowpart (SImode, operands[0]);
16559 operands[1] = gen_lowpart (SImode, operands[1]);")
16560
16561(define_split
16562 [(set (match_operand 0 "register_operand" "")
16563 (not (match_operand 1 "register_operand" "")))]
16564 "! TARGET_PARTIAL_REG_STALL && reload_completed
16565 && (GET_MODE (operands[0]) == HImode
6300f037 16566 || (GET_MODE (operands[0]) == QImode
b2077fd2
JH
16567 && (TARGET_PROMOTE_QImode
16568 || optimize_insn_for_size_p ())))"
e9e80858
JH
16569 [(set (match_dup 0)
16570 (not:SI (match_dup 1)))]
16571 "operands[0] = gen_lowpart (SImode, operands[0]);
16572 operands[1] = gen_lowpart (SImode, operands[1]);")
16573
6300f037 16574(define_split
e9e80858 16575 [(set (match_operand 0 "register_operand" "")
8aadc2f3 16576 (if_then_else (match_operator 1 "ordered_comparison_operator"
42fabf21 16577 [(reg FLAGS_REG) (const_int 0)])
e9e80858
JH
16578 (match_operand 2 "register_operand" "")
16579 (match_operand 3 "register_operand" "")))]
16580 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16581 && (GET_MODE (operands[0]) == HImode
6300f037 16582 || (GET_MODE (operands[0]) == QImode
b2077fd2
JH
16583 && (TARGET_PROMOTE_QImode
16584 || optimize_insn_for_size_p ())))"
e9e80858
JH
16585 [(set (match_dup 0)
16586 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16587 "operands[0] = gen_lowpart (SImode, operands[0]);
16588 operands[2] = gen_lowpart (SImode, operands[2]);
16589 operands[3] = gen_lowpart (SImode, operands[3]);")
e075ae69
RH
16590\f
16591;; RTL Peephole optimizations, run before sched2. These primarily look to
16592;; transform a complex memory operation into two memory to register operations.
16593
16594;; Don't push memory operands
16595(define_peephole2
cfc20f00
UB
16596 [(set (match_operand:SWI 0 "push_operand" "")
16597 (match_operand:SWI 1 "memory_operand" ""))
16598 (match_scratch:SWI 2 "<r>")]
b2077fd2 16599 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
150cdc9e 16600 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
e075ae69 16601 [(set (match_dup 2) (match_dup 1))
cfc20f00 16602 (set (match_dup 0) (match_dup 2))])
e075ae69 16603
cfc20f00 16604;; We need to handle SFmode only, because DFmode and XFmode are split to
e9e80858
JH
16605;; SImode pushes.
16606(define_peephole2
16607 [(set (match_operand:SF 0 "push_operand" "")
16608 (match_operand:SF 1 "memory_operand" ""))
16609 (match_scratch:SF 2 "r")]
b2077fd2 16610 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
150cdc9e 16611 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
e9e80858 16612 [(set (match_dup 2) (match_dup 1))
cfc20f00 16613 (set (match_dup 0) (match_dup 2))])
e075ae69
RH
16614
16615;; Don't move an immediate directly to memory when the instruction
16616;; gets too big.
16617(define_peephole2
cfc20f00
UB
16618 [(match_scratch:SWI124 1 "<r>")
16619 (set (match_operand:SWI124 0 "memory_operand" "")
e075ae69 16620 (const_int 0))]
b2077fd2 16621 "optimize_insn_for_speed_p ()
cfc20f00 16622 && !TARGET_USE_MOV0
23280139 16623 && TARGET_SPLIT_LONG_MOVES
b2077fd2 16624 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
23280139 16625 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 16626 [(parallel [(set (match_dup 2) (const_int 0))
8bc527af 16627 (clobber (reg:CC FLAGS_REG))])
e075ae69 16628 (set (match_dup 0) (match_dup 1))]
1e2115dc 16629 "operands[2] = gen_lowpart (SImode, operands[1]);")
e075ae69
RH
16630
16631(define_peephole2
cfc20f00
UB
16632 [(match_scratch:SWI124 2 "<r>")
16633 (set (match_operand:SWI124 0 "memory_operand" "")
16634 (match_operand:SWI124 1 "immediate_operand" ""))]
b2077fd2 16635 "optimize_insn_for_speed_p ()
d5d5d289 16636 && TARGET_SPLIT_LONG_MOVES
b2077fd2 16637 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
e075ae69 16638 [(set (match_dup 2) (match_dup 1))
cfc20f00 16639 (set (match_dup 0) (match_dup 2))])
e075ae69
RH
16640
16641;; Don't compare memory with zero, load and use a test instead.
16642(define_peephole2
25da5dc7
RH
16643 [(set (match_operand 0 "flags_reg_operand" "")
16644 (match_operator 1 "compare_operator"
16645 [(match_operand:SI 2 "memory_operand" "")
16646 (const_int 0)]))
3071fab5 16647 (match_scratch:SI 3 "r")]
b2077fd2 16648 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
25da5dc7 16649 [(set (match_dup 3) (match_dup 2))
cfc20f00 16650 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
e075ae69 16651
6300f037 16652;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
e075ae69 16653;; Don't split NOTs with a displacement operand, because resulting XOR
d1f87653 16654;; will not be pairable anyway.
e075ae69 16655;;
1e5f1716 16656;; On AMD K6, NOT is vector decoded with memory operand that cannot be
e075ae69
RH
16657;; represented using a modRM byte. The XOR replacement is long decoded,
16658;; so this split helps here as well.
16659;;
23280139
RH
16660;; Note: Can't do this as a regular split because we can't get proper
16661;; lifetime information then.
e075ae69
RH
16662
16663(define_peephole2
cfc20f00
UB
16664 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16665 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
b2077fd2 16666 "optimize_insn_for_speed_p ()
ddff69b9 16667 && ((TARGET_NOT_UNPAIRABLE
cfc20f00
UB
16668 && (!MEM_P (operands[0])
16669 || !memory_displacement_operand (operands[0], <MODE>mode)))
16670 || (TARGET_NOT_VECTORMODE
16671 && long_memory_operand (operands[0], <MODE>mode)))
d5d5d289 16672 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69 16673 [(parallel [(set (match_dup 0)
cfc20f00
UB
16674 (xor:SWI124 (match_dup 1) (const_int -1)))
16675 (clobber (reg:CC FLAGS_REG))])])
e075ae69
RH
16676
16677;; Non pairable "test imm, reg" instructions can be translated to
16678;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16679;; byte opcode instead of two, have a short form for byte operands),
16680;; so do it for other CPUs as well. Given that the value was dead,
f5143c46 16681;; this should not create any new dependencies. Pass on the sub-word
e075ae69
RH
16682;; versions if we're concerned about partial register stalls.
16683
16684(define_peephole2
25da5dc7
RH
16685 [(set (match_operand 0 "flags_reg_operand" "")
16686 (match_operator 1 "compare_operator"
16687 [(and:SI (match_operand:SI 2 "register_operand" "")
16688 (match_operand:SI 3 "immediate_operand" ""))
16689 (const_int 0)]))]
16189740 16690 "ix86_match_ccmode (insn, CCNOmode)
29b74761 16691 && (true_regnum (operands[2]) != AX_REG
f38840db 16692 || satisfies_constraint_K (operands[3]))
25da5dc7 16693 && peep2_reg_dead_p (1, operands[2])"
e075ae69 16694 [(parallel
25da5dc7
RH
16695 [(set (match_dup 0)
16696 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16697 (const_int 0)]))
16698 (set (match_dup 2)
cfc20f00 16699 (and:SI (match_dup 2) (match_dup 3)))])])
e075ae69 16700
e9e80858
JH
16701;; We don't need to handle HImode case, because it will be promoted to SImode
16702;; on ! TARGET_PARTIAL_REG_STALL
e075ae69
RH
16703
16704(define_peephole2
25da5dc7
RH
16705 [(set (match_operand 0 "flags_reg_operand" "")
16706 (match_operator 1 "compare_operator"
16707 [(and:QI (match_operand:QI 2 "register_operand" "")
16708 (match_operand:QI 3 "immediate_operand" ""))
16709 (const_int 0)]))]
e075ae69 16710 "! TARGET_PARTIAL_REG_STALL
16189740 16711 && ix86_match_ccmode (insn, CCNOmode)
29b74761 16712 && true_regnum (operands[2]) != AX_REG
25da5dc7 16713 && peep2_reg_dead_p (1, operands[2])"
e075ae69 16714 [(parallel
25da5dc7
RH
16715 [(set (match_dup 0)
16716 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16717 (const_int 0)]))
16718 (set (match_dup 2)
cfc20f00 16719 (and:QI (match_dup 2) (match_dup 3)))])])
e075ae69
RH
16720
16721(define_peephole2
25da5dc7
RH
16722 [(set (match_operand 0 "flags_reg_operand" "")
16723 (match_operator 1 "compare_operator"
16724 [(and:SI
16725 (zero_extract:SI
16726 (match_operand 2 "ext_register_operand" "")
16727 (const_int 8)
16728 (const_int 8))
16729 (match_operand 3 "const_int_operand" ""))
16730 (const_int 0)]))]
e075ae69 16731 "! TARGET_PARTIAL_REG_STALL
16189740 16732 && ix86_match_ccmode (insn, CCNOmode)
29b74761 16733 && true_regnum (operands[2]) != AX_REG
25da5dc7
RH
16734 && peep2_reg_dead_p (1, operands[2])"
16735 [(parallel [(set (match_dup 0)
16736 (match_op_dup 1
16737 [(and:SI
16738 (zero_extract:SI
16739 (match_dup 2)
16740 (const_int 8)
16741 (const_int 8))
16742 (match_dup 3))
16743 (const_int 0)]))
16744 (set (zero_extract:SI (match_dup 2)
e075ae69
RH
16745 (const_int 8)
16746 (const_int 8))
6300f037 16747 (and:SI
e075ae69 16748 (zero_extract:SI
25da5dc7 16749 (match_dup 2)
e075ae69
RH
16750 (const_int 8)
16751 (const_int 8))
cfc20f00 16752 (match_dup 3)))])])
e075ae69
RH
16753
16754;; Don't do logical operations with memory inputs.
16755(define_peephole2
16756 [(match_scratch:SI 2 "r")
16757 (parallel [(set (match_operand:SI 0 "register_operand" "")
16758 (match_operator:SI 3 "arith_or_logical_operator"
16759 [(match_dup 0)
16760 (match_operand:SI 1 "memory_operand" "")]))
8bc527af 16761 (clobber (reg:CC FLAGS_REG))])]
3cdf0c62 16762 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
e075ae69
RH
16763 [(set (match_dup 2) (match_dup 1))
16764 (parallel [(set (match_dup 0)
16765 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
cfc20f00 16766 (clobber (reg:CC FLAGS_REG))])])
e075ae69
RH
16767
16768(define_peephole2
16769 [(match_scratch:SI 2 "r")
16770 (parallel [(set (match_operand:SI 0 "register_operand" "")
16771 (match_operator:SI 3 "arith_or_logical_operator"
16772 [(match_operand:SI 1 "memory_operand" "")
16773 (match_dup 0)]))
8bc527af 16774 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 16775 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
e075ae69
RH
16776 [(set (match_dup 2) (match_dup 1))
16777 (parallel [(set (match_dup 0)
16778 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
cfc20f00 16779 (clobber (reg:CC FLAGS_REG))])])
e075ae69 16780
bab64f23
PB
16781;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16782;; refers to the destination of the load!
16783
16784(define_peephole2
16785 [(set (match_operand:SI 0 "register_operand" "")
16786 (match_operand:SI 1 "register_operand" ""))
16787 (parallel [(set (match_dup 0)
16788 (match_operator:SI 3 "commutative_operator"
16789 [(match_dup 0)
16790 (match_operand:SI 2 "memory_operand" "")]))
16791 (clobber (reg:CC FLAGS_REG))])]
bbb52802 16792 "REGNO (operands[0]) != REGNO (operands[1])
72f4e3a7
L
16793 && GENERAL_REGNO_P (REGNO (operands[0]))
16794 && GENERAL_REGNO_P (REGNO (operands[1]))"
bab64f23
PB
16795 [(set (match_dup 0) (match_dup 4))
16796 (parallel [(set (match_dup 0)
16797 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16798 (clobber (reg:CC FLAGS_REG))])]
12019aec 16799 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
bab64f23
PB
16800
16801(define_peephole2
16802 [(set (match_operand 0 "register_operand" "")
16803 (match_operand 1 "register_operand" ""))
16804 (set (match_dup 0)
16805 (match_operator 3 "commutative_operator"
16806 [(match_dup 0)
16807 (match_operand 2 "memory_operand" "")]))]
bbb52802 16808 "REGNO (operands[0]) != REGNO (operands[1])
47f5a48f
L
16809 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16810 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
bab64f23
PB
16811 [(set (match_dup 0) (match_dup 2))
16812 (set (match_dup 0)
cfc20f00 16813 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
bab64f23 16814
e075ae69
RH
16815; Don't do logical operations with memory outputs
16816;
16817; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16818; instruction into two 1-uop insns plus a 2-uop insn. That last has
16819; the same decoder scheduling characteristics as the original.
16820
16821(define_peephole2
16822 [(match_scratch:SI 2 "r")
16823 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16824 (match_operator:SI 3 "arith_or_logical_operator"
16825 [(match_dup 0)
16826 (match_operand:SI 1 "nonmemory_operand" "")]))
8bc527af 16827 (clobber (reg:CC FLAGS_REG))])]
35a07c37
EB
16828 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16829 /* Do not split stack checking probes. */
16830 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
e075ae69
RH
16831 [(set (match_dup 2) (match_dup 0))
16832 (parallel [(set (match_dup 2)
16833 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
8bc527af 16834 (clobber (reg:CC FLAGS_REG))])
cfc20f00 16835 (set (match_dup 0) (match_dup 2))])
e075ae69
RH
16836
16837(define_peephole2
16838 [(match_scratch:SI 2 "r")
16839 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16840 (match_operator:SI 3 "arith_or_logical_operator"
16841 [(match_operand:SI 1 "nonmemory_operand" "")
16842 (match_dup 0)]))
8bc527af 16843 (clobber (reg:CC FLAGS_REG))])]
35a07c37
EB
16844 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16845 /* Do not split stack checking probes. */
16846 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
e075ae69
RH
16847 [(set (match_dup 2) (match_dup 0))
16848 (parallel [(set (match_dup 2)
16849 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8bc527af 16850 (clobber (reg:CC FLAGS_REG))])
cfc20f00 16851 (set (match_dup 0) (match_dup 2))])
e075ae69
RH
16852
16853;; Attempt to always use XOR for zeroing registers.
16854(define_peephole2
16855 [(set (match_operand 0 "register_operand" "")
b4e82619
RH
16856 (match_operand 1 "const0_operand" ""))]
16857 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
b2077fd2 16858 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
f75959a6 16859 && GENERAL_REG_P (operands[0])
23280139 16860 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69 16861 [(parallel [(set (match_dup 0) (const_int 0))
8bc527af 16862 (clobber (reg:CC FLAGS_REG))])]
cfc20f00 16863 "operands[0] = gen_lowpart (word_mode, operands[0]);")
d3a923ee 16864
6ef67412
JH
16865(define_peephole2
16866 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16867 (const_int 0))]
16868 "(GET_MODE (operands[0]) == QImode
16869 || GET_MODE (operands[0]) == HImode)
b2077fd2 16870 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
6ef67412
JH
16871 && peep2_regno_dead_p (0, FLAGS_REG)"
16872 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
8bc527af 16873 (clobber (reg:CC FLAGS_REG))])])
6ef67412 16874
cfc20f00 16875;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
e075ae69 16876(define_peephole2
cfc20f00 16877 [(set (match_operand:SWI248 0 "register_operand" "")
e075ae69 16878 (const_int -1))]
cfc20f00 16879 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
23280139 16880 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 16881 [(parallel [(set (match_dup 0) (const_int -1))
8bc527af 16882 (clobber (reg:CC FLAGS_REG))])]
cfc20f00
UB
16883{
16884 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16885 operands[0] = gen_lowpart (SImode, operands[0]);
16886})
16887
16888;; Attempt to convert simple lea to add/shift.
16889;; These can be created by move expanders.
1c27d4b2 16890
1c27d4b2 16891(define_peephole2
cfc20f00
UB
16892 [(set (match_operand:SWI48 0 "register_operand" "")
16893 (plus:SWI48 (match_dup 0)
16894 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
23280139 16895 "peep2_regno_dead_p (0, FLAGS_REG)"
cfc20f00
UB
16896 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16897 (clobber (reg:CC FLAGS_REG))])])
1c27d4b2 16898
cc2e591b
JH
16899(define_peephole2
16900 [(set (match_operand:SI 0 "register_operand" "")
16901 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16902 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
cfc20f00
UB
16903 "TARGET_64BIT
16904 && peep2_regno_dead_p (0, FLAGS_REG)
16905 && REGNO (operands[0]) == REGNO (operands[1])"
cc2e591b 16906 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
8bc527af 16907 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
16908 "operands[2] = gen_lowpart (SImode, operands[2]);")
16909
16910(define_peephole2
cfc20f00
UB
16911 [(set (match_operand:SWI48 0 "register_operand" "")
16912 (mult:SWI48 (match_dup 0)
16913 (match_operand:SWI48 1 "const_int_operand" "")))]
cc2e591b
JH
16914 "exact_log2 (INTVAL (operands[1])) >= 0
16915 && peep2_regno_dead_p (0, FLAGS_REG)"
cfc20f00 16916 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
8bc527af 16917 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
16918 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16919
16920(define_peephole2
16921 [(set (match_operand:SI 0 "register_operand" "")
16922 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16923 (match_operand:DI 2 "const_int_operand" "")) 0))]
cfc20f00
UB
16924 "TARGET_64BIT
16925 && exact_log2 (INTVAL (operands[2])) >= 0
cc2e591b
JH
16926 && REGNO (operands[0]) == REGNO (operands[1])
16927 && peep2_regno_dead_p (0, FLAGS_REG)"
16928 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
8bc527af 16929 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
16930 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16931
bdeb029c 16932;; The ESP adjustments can be done by the push and pop instructions. Resulting
7d2c38c0
UB
16933;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16934;; On many CPUs it is also faster, since special hardware to avoid esp
f5143c46 16935;; dependencies is present.
bdeb029c 16936
7d2c38c0
UB
16937;; While some of these conversions may be done using splitters, we use
16938;; peepholes in order to allow combine_stack_adjustments pass to see
16939;; nonobfuscated RTL.
bdeb029c 16940
f5143c46 16941;; Convert prologue esp subtractions to push.
bdeb029c
JH
16942;; We need register to push. In order to keep verify_flow_info happy we have
16943;; two choices
16944;; - use scratch and clobber it in order to avoid dependencies
16945;; - use already live register
16946;; We can't use the second way right now, since there is no reliable way how to
16947;; verify that given register is live. First choice will also most likely in
16948;; fewer dependencies. On the place of esp adjustments it is very likely that
16949;; call clobbered registers are dead. We may want to use base pointer as an
16950;; alternative when no register is available later.
16951
16952(define_peephole2
d8b08ecd
UB
16953 [(match_scratch:P 1 "r")
16954 (parallel [(set (reg:P SP_REG)
16955 (plus:P (reg:P SP_REG)
16956 (match_operand:P 0 "const_int_operand" "")))
8bc527af 16957 (clobber (reg:CC FLAGS_REG))
f2042df3 16958 (clobber (mem:BLK (scratch)))])]
d8b08ecd
UB
16959 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16960 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16961 [(clobber (match_dup 1))
16962 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
f2042df3 16963 (clobber (mem:BLK (scratch)))])])
bdeb029c
JH
16964
16965(define_peephole2
d8b08ecd
UB
16966 [(match_scratch:P 1 "r")
16967 (parallel [(set (reg:P SP_REG)
16968 (plus:P (reg:P SP_REG)
16969 (match_operand:P 0 "const_int_operand" "")))
8bc527af 16970 (clobber (reg:CC FLAGS_REG))
f2042df3 16971 (clobber (mem:BLK (scratch)))])]
d8b08ecd
UB
16972 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16973 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16974 [(clobber (match_dup 1))
16975 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16976 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
f2042df3 16977 (clobber (mem:BLK (scratch)))])])
bdeb029c 16978
f5143c46 16979;; Convert esp subtractions to push.
bdeb029c 16980(define_peephole2
d8b08ecd
UB
16981 [(match_scratch:P 1 "r")
16982 (parallel [(set (reg:P SP_REG)
16983 (plus:P (reg:P SP_REG)
16984 (match_operand:P 0 "const_int_operand" "")))
8bc527af 16985 (clobber (reg:CC FLAGS_REG))])]
d8b08ecd
UB
16986 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16987 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16988 [(clobber (match_dup 1))
16989 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
bdeb029c
JH
16990
16991(define_peephole2
d8b08ecd
UB
16992 [(match_scratch:P 1 "r")
16993 (parallel [(set (reg:P SP_REG)
16994 (plus:P (reg:P SP_REG)
16995 (match_operand:P 0 "const_int_operand" "")))
8bc527af 16996 (clobber (reg:CC FLAGS_REG))])]
d8b08ecd
UB
16997 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16998 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16999 [(clobber (match_dup 1))
17000 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17001 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
bdeb029c
JH
17002
17003;; Convert epilogue deallocator to pop.
17004(define_peephole2
d8b08ecd
UB
17005 [(match_scratch:P 1 "r")
17006 (parallel [(set (reg:P SP_REG)
17007 (plus:P (reg:P SP_REG)
17008 (match_operand:P 0 "const_int_operand" "")))
8bc527af 17009 (clobber (reg:CC FLAGS_REG))
f2042df3 17010 (clobber (mem:BLK (scratch)))])]
d8b08ecd
UB
17011 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17012 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17013 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
7d2c38c0 17014 (clobber (mem:BLK (scratch)))])])
bdeb029c 17015
7d2c38c0
UB
17016;; Two pops case is tricky, since pop causes dependency
17017;; on destination register. We use two registers if available.
bdeb029c 17018(define_peephole2
d8b08ecd
UB
17019 [(match_scratch:P 1 "r")
17020 (match_scratch:P 2 "r")
17021 (parallel [(set (reg:P SP_REG)
17022 (plus:P (reg:P SP_REG)
17023 (match_operand:P 0 "const_int_operand" "")))
8bc527af 17024 (clobber (reg:CC FLAGS_REG))
f2042df3 17025 (clobber (mem:BLK (scratch)))])]
d8b08ecd
UB
17026 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17027 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17028 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
f2042df3 17029 (clobber (mem:BLK (scratch)))])
d8b08ecd 17030 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
bdeb029c
JH
17031
17032(define_peephole2
d8b08ecd
UB
17033 [(match_scratch:P 1 "r")
17034 (parallel [(set (reg:P SP_REG)
17035 (plus:P (reg:P SP_REG)
17036 (match_operand:P 0 "const_int_operand" "")))
8bc527af 17037 (clobber (reg:CC FLAGS_REG))
f2042df3 17038 (clobber (mem:BLK (scratch)))])]
d8b08ecd
UB
17039 "optimize_insn_for_size_p ()
17040 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17041 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
f2042df3 17042 (clobber (mem:BLK (scratch)))])
d8b08ecd 17043 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
bdeb029c
JH
17044
17045;; Convert esp additions to pop.
17046(define_peephole2
d8b08ecd
UB
17047 [(match_scratch:P 1 "r")
17048 (parallel [(set (reg:P SP_REG)
17049 (plus:P (reg:P SP_REG)
17050 (match_operand:P 0 "const_int_operand" "")))
8bc527af 17051 (clobber (reg:CC FLAGS_REG))])]
d8b08ecd
UB
17052 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17053 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
bdeb029c 17054
7d2c38c0
UB
17055;; Two pops case is tricky, since pop causes dependency
17056;; on destination register. We use two registers if available.
bdeb029c 17057(define_peephole2
d8b08ecd
UB
17058 [(match_scratch:P 1 "r")
17059 (match_scratch:P 2 "r")
17060 (parallel [(set (reg:P SP_REG)
17061 (plus:P (reg:P SP_REG)
17062 (match_operand:P 0 "const_int_operand" "")))
8bc527af 17063 (clobber (reg:CC FLAGS_REG))])]
d8b08ecd
UB
17064 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17065 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17066 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
cc2e591b
JH
17067
17068(define_peephole2
d8b08ecd
UB
17069 [(match_scratch:P 1 "r")
17070 (parallel [(set (reg:P SP_REG)
17071 (plus:P (reg:P SP_REG)
17072 (match_operand:P 0 "const_int_operand" "")))
8bc527af 17073 (clobber (reg:CC FLAGS_REG))])]
d8b08ecd
UB
17074 "optimize_insn_for_size_p ()
17075 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17076 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17077 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
cc2e591b 17078\f
3727f434
UB
17079;; Convert compares with 1 to shorter inc/dec operations when CF is not
17080;; required and register dies. Similarly for 128 to -128.
17081(define_peephole2
17082 [(set (match_operand 0 "flags_reg_operand" "")
17083 (match_operator 1 "compare_operator"
17084 [(match_operand 2 "register_operand" "")
17085 (match_operand 3 "const_int_operand" "")]))]
17086 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17087 && incdec_operand (operands[3], GET_MODE (operands[3])))
17088 || (!TARGET_FUSE_CMP_AND_BRANCH
17089 && INTVAL (operands[3]) == 128))
17090 && ix86_match_ccmode (insn, CCGCmode)
17091 && peep2_reg_dead_p (1, operands[2])"
17092 [(parallel [(set (match_dup 0)
17093 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17094 (clobber (match_dup 2))])])
17095\f
cf14e33d
RS
17096;; Convert imul by three, five and nine into lea
17097(define_peephole2
17098 [(parallel
cfc20f00
UB
17099 [(set (match_operand:SWI48 0 "register_operand" "")
17100 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17101 (match_operand:SWI48 2 "const_int_operand" "")))
cf14e33d
RS
17102 (clobber (reg:CC FLAGS_REG))])]
17103 "INTVAL (operands[2]) == 3
17104 || INTVAL (operands[2]) == 5
17105 || INTVAL (operands[2]) == 9"
17106 [(set (match_dup 0)
cfc20f00
UB
17107 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17108 (match_dup 1)))]
9aa5922d 17109 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
cf14e33d
RS
17110
17111(define_peephole2
17112 [(parallel
cfc20f00
UB
17113 [(set (match_operand:SWI48 0 "register_operand" "")
17114 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17115 (match_operand:SWI48 2 "const_int_operand" "")))
cf14e33d 17116 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 17117 "optimize_insn_for_speed_p ()
cf14e33d
RS
17118 && (INTVAL (operands[2]) == 3
17119 || INTVAL (operands[2]) == 5
17120 || INTVAL (operands[2]) == 9)"
17121 [(set (match_dup 0) (match_dup 1))
17122 (set (match_dup 0)
cfc20f00
UB
17123 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17124 (match_dup 0)))]
9aa5922d 17125 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
cf14e33d 17126
cfc20f00 17127;; imul $32bit_imm, mem, reg is vector decoded, while
f56e86bd
JH
17128;; imul $32bit_imm, reg, reg is direct decoded.
17129(define_peephole2
cfc20f00
UB
17130 [(match_scratch:SWI48 3 "r")
17131 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17132 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17133 (match_operand:SWI48 2 "immediate_operand" "")))
8bc527af 17134 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 17135 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
f38840db 17136 && !satisfies_constraint_K (operands[2])"
f56e86bd 17137 [(set (match_dup 3) (match_dup 1))
cfc20f00
UB
17138 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17139 (clobber (reg:CC FLAGS_REG))])])
f56e86bd
JH
17140
17141(define_peephole2
17142 [(match_scratch:SI 3 "r")
17143 (parallel [(set (match_operand:DI 0 "register_operand" "")
17144 (zero_extend:DI
17145 (mult:SI (match_operand:SI 1 "memory_operand" "")
17146 (match_operand:SI 2 "immediate_operand" ""))))
8bc527af 17147 (clobber (reg:CC FLAGS_REG))])]
cfc20f00
UB
17148 "TARGET_64BIT
17149 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
f38840db 17150 && !satisfies_constraint_K (operands[2])"
f56e86bd 17151 [(set (match_dup 3) (match_dup 1))
9aa5922d
UB
17152 (parallel [(set (match_dup 0)
17153 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
cfc20f00 17154 (clobber (reg:CC FLAGS_REG))])])
f56e86bd
JH
17155
17156;; imul $8/16bit_imm, regmem, reg is vector decoded.
17157;; Convert it into imul reg, reg
17158;; It would be better to force assembler to encode instruction using long
17159;; immediate, but there is apparently no way to do so.
17160(define_peephole2
cfc20f00
UB
17161 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17162 (mult:SWI248
17163 (match_operand:SWI248 1 "nonimmediate_operand" "")
17164 (match_operand:SWI248 2 "const_int_operand" "")))
8bc527af 17165 (clobber (reg:CC FLAGS_REG))])
cfc20f00 17166 (match_scratch:SWI248 3 "r")]
b2077fd2 17167 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
f38840db 17168 && satisfies_constraint_K (operands[2])"
f56e86bd 17169 [(set (match_dup 3) (match_dup 2))
cfc20f00 17170 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
8bc527af 17171 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
17172{
17173 if (!rtx_equal_p (operands[0], operands[1]))
17174 emit_move_insn (operands[0], operands[1]);
17175})
fb530c72
JH
17176
17177;; After splitting up read-modify operations, array accesses with memory
17178;; operands might end up in form:
17179;; sall $2, %eax
17180;; movl 4(%esp), %edx
17181;; addl %edx, %eax
17182;; instead of pre-splitting:
17183;; sall $2, %eax
17184;; addl 4(%esp), %eax
17185;; Turn it into:
17186;; movl 4(%esp), %edx
17187;; leal (%edx,%eax,4), %eax
17188
17189(define_peephole2
ed1db000 17190 [(match_scratch:P 5 "r")
ee932b8f 17191 (parallel [(set (match_operand 0 "register_operand" "")
fb530c72
JH
17192 (ashift (match_operand 1 "register_operand" "")
17193 (match_operand 2 "const_int_operand" "")))
17194 (clobber (reg:CC FLAGS_REG))])
ee932b8f
BS
17195 (parallel [(set (match_operand 3 "register_operand" "")
17196 (plus (match_dup 0)
17197 (match_operand 4 "x86_64_general_operand" "")))
fb530c72
JH
17198 (clobber (reg:CC FLAGS_REG))])]
17199 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17200 /* Validate MODE for lea. */
17201 && ((!TARGET_PARTIAL_REG_STALL
17202 && (GET_MODE (operands[0]) == QImode
17203 || GET_MODE (operands[0]) == HImode))
6300f037 17204 || GET_MODE (operands[0]) == SImode
fb530c72 17205 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
cc9568ba
BS
17206 && (rtx_equal_p (operands[0], operands[3])
17207 || peep2_reg_dead_p (2, operands[0]))
fb530c72 17208 /* We reorder load and the shift. */
ee932b8f
BS
17209 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17210 [(set (match_dup 5) (match_dup 4))
fb530c72
JH
17211 (set (match_dup 0) (match_dup 1))]
17212{
ee932b8f 17213 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
fb530c72
JH
17214 int scale = 1 << INTVAL (operands[2]);
17215 rtx index = gen_lowpart (Pmode, operands[1]);
ee932b8f
BS
17216 rtx base = gen_lowpart (Pmode, operands[5]);
17217 rtx dest = gen_lowpart (mode, operands[3]);
fb530c72
JH
17218
17219 operands[1] = gen_rtx_PLUS (Pmode, base,
17220 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
ee932b8f 17221 operands[5] = base;
ed1db000
L
17222 if (mode != Pmode)
17223 {
17224 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17225 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17226 }
fb530c72
JH
17227 operands[0] = dest;
17228})
f56e86bd 17229\f
69404d6f
RH
17230;; Call-value patterns last so that the wildcard operand does not
17231;; disrupt insn-recog's switch tables.
17232
94bb5d0c
RH
17233(define_insn "*call_value_pop_0"
17234 [(set (match_operand 0 "" "")
e1ff012c 17235 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c 17236 (match_operand:SI 2 "" "")))
8410737a
UB
17237 (set (reg:SI SP_REG)
17238 (plus:SI (reg:SI SP_REG)
17239 (match_operand:SI 3 "immediate_operand" "")))]
1e07edd3 17240 "!TARGET_64BIT"
94bb5d0c
RH
17241{
17242 if (SIBLING_CALL_P (insn))
0f40f9f7 17243 return "jmp\t%P1";
94bb5d0c 17244 else
0f40f9f7
ZW
17245 return "call\t%P1";
17246}
94bb5d0c
RH
17247 [(set_attr "type" "callv")])
17248
55a19d49
UB
17249(define_insn "*call_value_pop_1"
17250 [(set (match_operand 0 "" "")
17251 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17252 (match_operand:SI 2 "" "")))
8410737a
UB
17253 (set (reg:SI SP_REG)
17254 (plus:SI (reg:SI SP_REG)
17255 (match_operand:SI 3 "immediate_operand" "i")))]
17256 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
69404d6f 17257{
e427abbf 17258 if (constant_call_address_operand (operands[1], Pmode))
fe62197b
UB
17259 return "call\t%P1";
17260 return "call\t%A1";
0f40f9f7 17261}
94bb5d0c
RH
17262 [(set_attr "type" "callv")])
17263
fe62197b
UB
17264(define_insn "*sibcall_value_pop_1"
17265 [(set (match_operand 0 "" "")
61ae58d4 17266 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
fe62197b 17267 (match_operand:SI 2 "" "")))
8410737a
UB
17268 (set (reg:SI SP_REG)
17269 (plus:SI (reg:SI SP_REG)
17270 (match_operand:SI 3 "immediate_operand" "i,i")))]
55a19d49 17271 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
fe62197b
UB
17272 "@
17273 jmp\t%P1
17274 jmp\t%A1"
17275 [(set_attr "type" "callv")])
17276
94bb5d0c
RH
17277(define_insn "*call_value_0"
17278 [(set (match_operand 0 "" "")
e1ff012c 17279 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c 17280 (match_operand:SI 2 "" "")))]
32ee7d1d 17281 "!TARGET_64BIT"
32ee7d1d
JH
17282{
17283 if (SIBLING_CALL_P (insn))
0f40f9f7 17284 return "jmp\t%P1";
32ee7d1d 17285 else
0f40f9f7
ZW
17286 return "call\t%P1";
17287}
32ee7d1d
JH
17288 [(set_attr "type" "callv")])
17289
17290(define_insn "*call_value_0_rex64"
17291 [(set (match_operand 0 "" "")
17292 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17293 (match_operand:DI 2 "const_int_operand" "")))]
17294 "TARGET_64BIT"
94bb5d0c
RH
17295{
17296 if (SIBLING_CALL_P (insn))
0f40f9f7 17297 return "jmp\t%P1";
94bb5d0c 17298 else
0f40f9f7
ZW
17299 return "call\t%P1";
17300}
69404d6f
RH
17301 [(set_attr "type" "callv")])
17302
924eabec
JH
17303(define_insn "*call_value_0_rex64_ms_sysv"
17304 [(set (match_operand 0 "" "")
17305 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17306 (match_operand:DI 2 "const_int_operand" "")))
17307 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
78168632
UB
17308 (clobber (reg:TI XMM6_REG))
17309 (clobber (reg:TI XMM7_REG))
17310 (clobber (reg:TI XMM8_REG))
17311 (clobber (reg:TI XMM9_REG))
17312 (clobber (reg:TI XMM10_REG))
17313 (clobber (reg:TI XMM11_REG))
17314 (clobber (reg:TI XMM12_REG))
17315 (clobber (reg:TI XMM13_REG))
17316 (clobber (reg:TI XMM14_REG))
17317 (clobber (reg:TI XMM15_REG))
924eabec
JH
17318 (clobber (reg:DI SI_REG))
17319 (clobber (reg:DI DI_REG))]
55a19d49 17320 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
924eabec
JH
17321{
17322 if (SIBLING_CALL_P (insn))
17323 return "jmp\t%P1";
17324 else
17325 return "call\t%P1";
17326}
17327 [(set_attr "type" "callv")])
17328
55a19d49
UB
17329(define_insn "*call_value_1"
17330 [(set (match_operand 0 "" "")
17331 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17332 (match_operand:SI 2 "" "")))]
8410737a 17333 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
32ee7d1d 17334{
e427abbf 17335 if (constant_call_address_operand (operands[1], Pmode))
4977bab6 17336 return "call\t%P1";
6a46f71d 17337 return "call\t%A1";
4977bab6
ZW
17338}
17339 [(set_attr "type" "callv")])
17340
17341(define_insn "*sibcall_value_1"
17342 [(set (match_operand 0 "" "")
ac2e563f 17343 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
4977bab6 17344 (match_operand:SI 2 "" "")))]
55a19d49 17345 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
ac2e563f
RH
17346 "@
17347 jmp\t%P1
17348 jmp\t%A1"
32ee7d1d
JH
17349 [(set_attr "type" "callv")])
17350
17351(define_insn "*call_value_1_rex64"
17352 [(set (match_operand 0 "" "")
17353 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17354 (match_operand:DI 2 "" "")))]
55a19d49 17355 "TARGET_64BIT && !SIBLING_CALL_P (insn)
dc4d7240 17356 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
924eabec
JH
17357{
17358 if (constant_call_address_operand (operands[1], Pmode))
17359 return "call\t%P1";
17360 return "call\t%A1";
17361}
17362 [(set_attr "type" "callv")])
17363
17364(define_insn "*call_value_1_rex64_ms_sysv"
17365 [(set (match_operand 0 "" "")
17366 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17367 (match_operand:DI 2 "" "")))
17368 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
9d1a9845
UB
17369 (clobber (reg:TI XMM6_REG))
17370 (clobber (reg:TI XMM7_REG))
17371 (clobber (reg:TI XMM8_REG))
17372 (clobber (reg:TI XMM9_REG))
17373 (clobber (reg:TI XMM10_REG))
17374 (clobber (reg:TI XMM11_REG))
17375 (clobber (reg:TI XMM12_REG))
17376 (clobber (reg:TI XMM13_REG))
17377 (clobber (reg:TI XMM14_REG))
17378 (clobber (reg:TI XMM15_REG))
924eabec
JH
17379 (clobber (reg:DI SI_REG))
17380 (clobber (reg:DI DI_REG))]
9d1a9845 17381 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
69404d6f 17382{
e427abbf 17383 if (constant_call_address_operand (operands[1], Pmode))
4977bab6
ZW
17384 return "call\t%P1";
17385 return "call\t%A1";
0f40f9f7 17386}
69404d6f 17387 [(set_attr "type" "callv")])
4977bab6 17388
dc4d7240
JH
17389(define_insn "*call_value_1_rex64_large"
17390 [(set (match_operand 0 "" "")
17391 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17392 (match_operand:DI 2 "" "")))]
55a19d49 17393 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
dc4d7240
JH
17394 "call\t%A1"
17395 [(set_attr "type" "callv")])
17396
4977bab6
ZW
17397(define_insn "*sibcall_value_1_rex64"
17398 [(set (match_operand 0 "" "")
ac2e563f 17399 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
4977bab6 17400 (match_operand:DI 2 "" "")))]
55a19d49 17401 "TARGET_64BIT && SIBLING_CALL_P (insn)"
ac2e563f
RH
17402 "@
17403 jmp\t%P1
17404 jmp\t%A1"
4977bab6 17405 [(set_attr "type" "callv")])
9e3e266c 17406\f
7d69de61 17407;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
6300f037 17408;; That, however, is usually mapped by the OS to SIGSEGV, which is often
7d69de61
RH
17409;; caught for use by garbage collectors and the like. Using an insn that
17410;; maps to SIGILL makes it more likely the program will rightfully die.
17411;; Keeping with tradition, "6" is in honor of #UD.
9e3e266c 17412(define_insn "trap"
7d69de61 17413 [(trap_if (const_int 1) (const_int 6))]
9e3e266c 17414 ""
45050557 17415 { return ASM_SHORT "0x0b0f"; }
7d69de61 17416 [(set_attr "length" "2")])
915119a5 17417
ef719a44
RH
17418(define_expand "prefetch"
17419 [(prefetch (match_operand 0 "address_operand" "")
17420 (match_operand:SI 1 "const_int_operand" "")
17421 (match_operand:SI 2 "const_int_operand" ""))]
17422 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
1c47af84 17423{
ef719a44
RH
17424 int rw = INTVAL (operands[1]);
17425 int locality = INTVAL (operands[2]);
1c47af84 17426
7637e42c
NS
17427 gcc_assert (rw == 0 || rw == 1);
17428 gcc_assert (locality >= 0 && locality <= 3);
17429 gcc_assert (GET_MODE (operands[0]) == Pmode
17430 || GET_MODE (operands[0]) == VOIDmode);
1c47af84 17431
ef719a44 17432 /* Use 3dNOW prefetch in case we are asking for write prefetch not
aabcd309 17433 supported by SSE counterpart or the SSE prefetch is not available
ef719a44
RH
17434 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17435 of locality. */
17436 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17437 operands[2] = GEN_INT (3);
17438 else
17439 operands[1] = const0_rtx;
1c47af84
RH
17440})
17441
f582a3aa
UB
17442(define_insn "*prefetch_sse_<mode>"
17443 [(prefetch (match_operand:P 0 "address_operand" "p")
ef719a44
RH
17444 (const_int 0)
17445 (match_operand:SI 1 "const_int_operand" ""))]
f582a3aa 17446 "TARGET_PREFETCH_SSE"
4977bab6 17447{
ef719a44
RH
17448 static const char * const patterns[4] = {
17449 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17450 };
fbe5eb6d 17451
ef719a44 17452 int locality = INTVAL (operands[1]);
7637e42c 17453 gcc_assert (locality >= 0 && locality <= 3);
fbe5eb6d 17454
6300f037 17455 return patterns[locality];
ef719a44 17456}
fbe5eb6d 17457 [(set_attr "type" "sse")
b6837b94 17458 (set_attr "atom_sse_attr" "prefetch")
f582a3aa
UB
17459 (set (attr "length_address")
17460 (symbol_ref "memory_address_length (operands[0])"))
ef719a44 17461 (set_attr "memory" "none")])
fbe5eb6d 17462
f582a3aa
UB
17463(define_insn "*prefetch_3dnow_<mode>"
17464 [(prefetch (match_operand:P 0 "address_operand" "p")
ef719a44
RH
17465 (match_operand:SI 1 "const_int_operand" "n")
17466 (const_int 3))]
f582a3aa 17467 "TARGET_3DNOW"
ef719a44
RH
17468{
17469 if (INTVAL (operands[1]) == 0)
17470 return "prefetch\t%a0";
17471 else
17472 return "prefetchw\t%a0";
17473}
17474 [(set_attr "type" "mmx")
f582a3aa
UB
17475 (set (attr "length_address")
17476 (symbol_ref "memory_address_length (operands[0])"))
ef719a44 17477 (set_attr "memory" "none")])
22c7c85e 17478
7d69de61
RH
17479(define_expand "stack_protect_set"
17480 [(match_operand 0 "memory_operand" "")
17481 (match_operand 1 "memory_operand" "")]
17482 ""
17483{
d1e74401
UB
17484 rtx (*insn)(rtx, rtx);
17485
77008252 17486#ifdef TARGET_THREAD_SSP_OFFSET
d1e74401
UB
17487 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17488 insn = (TARGET_64BIT
17489 ? gen_stack_tls_protect_set_di
17490 : gen_stack_tls_protect_set_si);
77008252 17491#else
d1e74401
UB
17492 insn = (TARGET_64BIT
17493 ? gen_stack_protect_set_di
17494 : gen_stack_protect_set_si);
77008252 17495#endif
d1e74401
UB
17496
17497 emit_insn (insn (operands[0], operands[1]));
7d69de61
RH
17498 DONE;
17499})
17500
d1e74401
UB
17501(define_insn "stack_protect_set_<mode>"
17502 [(set (match_operand:P 0 "memory_operand" "=m")
17503 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17504 (set (match_scratch:P 2 "=&r") (const_int 0))
7d69de61
RH
17505 (clobber (reg:CC FLAGS_REG))]
17506 ""
d1e74401 17507 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
7d69de61
RH
17508 [(set_attr "type" "multi")])
17509
d1e74401
UB
17510(define_insn "stack_tls_protect_set_<mode>"
17511 [(set (match_operand:P 0 "memory_operand" "=m")
17512 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17513 UNSPEC_SP_TLS_SET))
17514 (set (match_scratch:P 2 "=&r") (const_int 0))
77008252
JJ
17515 (clobber (reg:CC FLAGS_REG))]
17516 ""
d1e74401 17517 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
77008252
JJ
17518 [(set_attr "type" "multi")])
17519
7d69de61
RH
17520(define_expand "stack_protect_test"
17521 [(match_operand 0 "memory_operand" "")
3aebbe5f
JJ
17522 (match_operand 1 "memory_operand" "")
17523 (match_operand 2 "" "")]
7d69de61
RH
17524 ""
17525{
17526 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
7d69de61 17527
d1e74401
UB
17528 rtx (*insn)(rtx, rtx, rtx);
17529
77008252 17530#ifdef TARGET_THREAD_SSP_OFFSET
d1e74401
UB
17531 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17532 insn = (TARGET_64BIT
17533 ? gen_stack_tls_protect_test_di
17534 : gen_stack_tls_protect_test_si);
77008252 17535#else
d1e74401
UB
17536 insn = (TARGET_64BIT
17537 ? gen_stack_protect_test_di
17538 : gen_stack_protect_test_si);
77008252 17539#endif
67b8f1c1 17540
d1e74401
UB
17541 emit_insn (insn (flags, operands[0], operands[1]));
17542
f90b7a5a
PB
17543 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17544 flags, const0_rtx, operands[2]));
7d69de61
RH
17545 DONE;
17546})
17547
d1e74401 17548(define_insn "stack_protect_test_<mode>"
7d69de61 17549 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
d1e74401
UB
17550 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17551 (match_operand:P 2 "memory_operand" "m")]
7d69de61 17552 UNSPEC_SP_TEST))
d1e74401 17553 (clobber (match_scratch:P 3 "=&r"))]
7d69de61 17554 ""
d1e74401 17555 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
7d69de61
RH
17556 [(set_attr "type" "multi")])
17557
d1e74401 17558(define_insn "stack_tls_protect_test_<mode>"
7d69de61 17559 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
d1e74401
UB
17560 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17561 (match_operand:P 2 "const_int_operand" "i")]
77008252 17562 UNSPEC_SP_TLS_TEST))
d1e74401 17563 (clobber (match_scratch:P 3 "=r"))]
77008252 17564 ""
d1e74401 17565 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
77008252
JJ
17566 [(set_attr "type" "multi")])
17567
3b8dd071
L
17568(define_insn "sse4_2_crc32<mode>"
17569 [(set (match_operand:SI 0 "register_operand" "=r")
17570 (unspec:SI
17571 [(match_operand:SI 1 "register_operand" "0")
79564f1e 17572 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
3b8dd071 17573 UNSPEC_CRC32))]
8ed0ce99 17574 "TARGET_SSE4_2 || TARGET_CRC32"
79564f1e 17575 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
3b8dd071
L
17576 [(set_attr "type" "sselog1")
17577 (set_attr "prefix_rep" "1")
17578 (set_attr "prefix_extra" "1")
725fd454
JJ
17579 (set (attr "prefix_data16")
17580 (if_then_else (match_operand:HI 2 "" "")
17581 (const_string "1")
17582 (const_string "*")))
17583 (set (attr "prefix_rex")
17584 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17585 (const_string "1")
17586 (const_string "*")))
3b8dd071
L
17587 (set_attr "mode" "SI")])
17588
17589(define_insn "sse4_2_crc32di"
17590 [(set (match_operand:DI 0 "register_operand" "=r")
17591 (unspec:DI
17592 [(match_operand:DI 1 "register_operand" "0")
17593 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17594 UNSPEC_CRC32))]
8ed0ce99 17595 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
72b2bc46 17596 "crc32{q}\t{%2, %0|%0, %2}"
3b8dd071
L
17597 [(set_attr "type" "sselog1")
17598 (set_attr "prefix_rep" "1")
17599 (set_attr "prefix_extra" "1")
17600 (set_attr "mode" "DI")])
17601
7c45393e
L
17602(define_expand "rdpmc"
17603 [(match_operand:DI 0 "register_operand" "")
17604 (match_operand:SI 1 "register_operand" "")]
17605 ""
17606{
17607 rtx reg = gen_reg_rtx (DImode);
17608 rtx si;
17609
17610 /* Force operand 1 into ECX. */
17611 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17612 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17613 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17614 UNSPECV_RDPMC);
17615
17616 if (TARGET_64BIT)
17617 {
17618 rtvec vec = rtvec_alloc (2);
17619 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17620 rtx upper = gen_reg_rtx (DImode);
17621 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17622 gen_rtvec (1, const0_rtx),
17623 UNSPECV_RDPMC);
17624 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17625 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17626 emit_insn (load);
17627 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17628 NULL, 1, OPTAB_DIRECT);
17629 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17630 OPTAB_DIRECT);
17631 }
17632 else
17633 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17634 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17635 DONE;
17636})
17637
17638(define_insn "*rdpmc"
17639 [(set (match_operand:DI 0 "register_operand" "=A")
17640 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17641 UNSPECV_RDPMC))]
17642 "!TARGET_64BIT"
17643 "rdpmc"
17644 [(set_attr "type" "other")
17645 (set_attr "length" "2")])
17646
17647(define_insn "*rdpmc_rex64"
17648 [(set (match_operand:DI 0 "register_operand" "=a")
17649 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17650 UNSPECV_RDPMC))
17651 (set (match_operand:DI 1 "register_operand" "=d")
17652 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17653 "TARGET_64BIT"
17654 "rdpmc"
17655 [(set_attr "type" "other")
17656 (set_attr "length" "2")])
17657
17658(define_expand "rdtsc"
17659 [(set (match_operand:DI 0 "register_operand" "")
17660 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17661 ""
17662{
17663 if (TARGET_64BIT)
17664 {
17665 rtvec vec = rtvec_alloc (2);
17666 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17667 rtx upper = gen_reg_rtx (DImode);
17668 rtx lower = gen_reg_rtx (DImode);
17669 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17670 gen_rtvec (1, const0_rtx),
17671 UNSPECV_RDTSC);
17672 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17673 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17674 emit_insn (load);
17675 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17676 NULL, 1, OPTAB_DIRECT);
17677 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17678 OPTAB_DIRECT);
17679 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17680 DONE;
17681 }
17682})
17683
17684(define_insn "*rdtsc"
17685 [(set (match_operand:DI 0 "register_operand" "=A")
17686 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17687 "!TARGET_64BIT"
17688 "rdtsc"
17689 [(set_attr "type" "other")
17690 (set_attr "length" "2")])
17691
17692(define_insn "*rdtsc_rex64"
17693 [(set (match_operand:DI 0 "register_operand" "=a")
17694 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17695 (set (match_operand:DI 1 "register_operand" "=d")
17696 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17697 "TARGET_64BIT"
17698 "rdtsc"
17699 [(set_attr "type" "other")
17700 (set_attr "length" "2")])
17701
17702(define_expand "rdtscp"
17703 [(match_operand:DI 0 "register_operand" "")
17704 (match_operand:SI 1 "memory_operand" "")]
17705 ""
17706{
17707 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17708 gen_rtvec (1, const0_rtx),
17709 UNSPECV_RDTSCP);
17710 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17711 gen_rtvec (1, const0_rtx),
17712 UNSPECV_RDTSCP);
17713 rtx reg = gen_reg_rtx (DImode);
17714 rtx tmp = gen_reg_rtx (SImode);
17715
17716 if (TARGET_64BIT)
17717 {
17718 rtvec vec = rtvec_alloc (3);
17719 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17720 rtx upper = gen_reg_rtx (DImode);
17721 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17722 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17723 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17724 emit_insn (load);
17725 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17726 NULL, 1, OPTAB_DIRECT);
17727 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17728 OPTAB_DIRECT);
17729 }
17730 else
17731 {
17732 rtvec vec = rtvec_alloc (2);
17733 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17734 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17735 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17736 emit_insn (load);
17737 }
17738 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17739 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17740 DONE;
17741})
17742
17743(define_insn "*rdtscp"
17744 [(set (match_operand:DI 0 "register_operand" "=A")
17745 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17746 (set (match_operand:SI 1 "register_operand" "=c")
17747 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17748 "!TARGET_64BIT"
17749 "rdtscp"
17750 [(set_attr "type" "other")
17751 (set_attr "length" "3")])
17752
17753(define_insn "*rdtscp_rex64"
17754 [(set (match_operand:DI 0 "register_operand" "=a")
17755 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17756 (set (match_operand:DI 1 "register_operand" "=d")
17757 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17758 (set (match_operand:SI 2 "register_operand" "=c")
17759 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17760 "TARGET_64BIT"
17761 "rdtscp"
17762 [(set_attr "type" "other")
17763 (set_attr "length" "3")])
17764
3e901069
HJ
17765;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17766;;
17767;; LWP instructions
17768;;
17769;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17770
519517fd
JJ
17771(define_expand "lwp_llwpcb"
17772 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17773 UNSPECV_LLWP_INTRINSIC)]
a427621f 17774 "TARGET_LWP")
3e901069 17775
519517fd
JJ
17776(define_insn "*lwp_llwpcb<mode>1"
17777 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17778 UNSPECV_LLWP_INTRINSIC)]
3e901069
HJ
17779 "TARGET_LWP"
17780 "llwpcb\t%0"
17781 [(set_attr "type" "lwp")
519517fd
JJ
17782 (set_attr "mode" "<MODE>")
17783 (set_attr "length" "5")])
3e901069 17784
519517fd
JJ
17785(define_expand "lwp_slwpcb"
17786 [(set (match_operand 0 "register_operand" "=r")
17787 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
3e901069 17788 "TARGET_LWP"
a427621f
UB
17789{
17790 if (TARGET_64BIT)
17791 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17792 else
17793 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17794 DONE;
17795})
519517fd
JJ
17796
17797(define_insn "lwp_slwpcb<mode>"
17798 [(set (match_operand:P 0 "register_operand" "=r")
17799 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
3e901069
HJ
17800 "TARGET_LWP"
17801 "slwpcb\t%0"
17802 [(set_attr "type" "lwp")
519517fd
JJ
17803 (set_attr "mode" "<MODE>")
17804 (set_attr "length" "5")])
3e901069 17805
519517fd
JJ
17806(define_expand "lwp_lwpval<mode>3"
17807 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17808 (match_operand:SI 2 "nonimmediate_operand" "rm")
17809 (match_operand:SI 3 "const_int_operand" "i")]
3e901069
HJ
17810 UNSPECV_LWPVAL_INTRINSIC)]
17811 "TARGET_LWP"
519517fd
JJ
17812 "/* Avoid unused variable warning. */
17813 (void) operand0;")
3e901069 17814
519517fd
JJ
17815(define_insn "*lwp_lwpval<mode>3_1"
17816 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17817 (match_operand:SI 1 "nonimmediate_operand" "rm")
17818 (match_operand:SI 2 "const_int_operand" "i")]
3e901069
HJ
17819 UNSPECV_LWPVAL_INTRINSIC)]
17820 "TARGET_LWP"
17821 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17822 [(set_attr "type" "lwp")
519517fd
JJ
17823 (set_attr "mode" "<MODE>")
17824 (set (attr "length")
17825 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
3e901069 17826
519517fd
JJ
17827(define_expand "lwp_lwpins<mode>3"
17828 [(set (reg:CCC FLAGS_REG)
17829 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17830 (match_operand:SI 2 "nonimmediate_operand" "rm")
17831 (match_operand:SI 3 "const_int_operand" "i")]
17832 UNSPECV_LWPINS_INTRINSIC))
17833 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17834 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
a427621f 17835 "TARGET_LWP")
3e901069 17836
519517fd
JJ
17837(define_insn "*lwp_lwpins<mode>3_1"
17838 [(set (reg:CCC FLAGS_REG)
17839 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17840 (match_operand:SI 1 "nonimmediate_operand" "rm")
17841 (match_operand:SI 2 "const_int_operand" "i")]
17842 UNSPECV_LWPINS_INTRINSIC))]
3e901069
HJ
17843 "TARGET_LWP"
17844 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17845 [(set_attr "type" "lwp")
519517fd
JJ
17846 (set_attr "mode" "<MODE>")
17847 (set (attr "length")
17848 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
3e901069 17849
4ee89d5f
L
17850(define_insn "rdfsbase<mode>"
17851 [(set (match_operand:SWI48 0 "register_operand" "=r")
17852 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17853 "TARGET_64BIT && TARGET_FSGSBASE"
17854 "rdfsbase %0"
17855 [(set_attr "type" "other")
17856 (set_attr "prefix_extra" "2")])
17857
17858(define_insn "rdgsbase<mode>"
17859 [(set (match_operand:SWI48 0 "register_operand" "=r")
17860 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17861 "TARGET_64BIT && TARGET_FSGSBASE"
17862 "rdgsbase %0"
17863 [(set_attr "type" "other")
17864 (set_attr "prefix_extra" "2")])
17865
17866(define_insn "wrfsbase<mode>"
17867 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17868 UNSPECV_WRFSBASE)]
17869 "TARGET_64BIT && TARGET_FSGSBASE"
17870 "wrfsbase %0"
17871 [(set_attr "type" "other")
17872 (set_attr "prefix_extra" "2")])
17873
17874(define_insn "wrgsbase<mode>"
17875 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17876 UNSPECV_WRGSBASE)]
17877 "TARGET_64BIT && TARGET_FSGSBASE"
17878 "wrgsbase %0"
17879 [(set_attr "type" "other")
17880 (set_attr "prefix_extra" "2")])
17881
5e86e540
L
17882(define_expand "rdrand<mode>"
17883 [(set (match_operand:SWI248 0 "register_operand" "=r")
17884 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17885 "TARGET_RDRND"
17886{
17887 rtx retry_label, insn, ccc;
17888
17889 retry_label = gen_label_rtx ();
17890
17891 emit_label (retry_label);
17892
17893 /* Generate rdrand. */
17894 emit_insn (gen_rdrand<mode>_1 (operands[0]));
17895
17896 /* Retry if the carry flag isn't valid. */
17897 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17898 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17899 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17900 gen_rtx_LABEL_REF (VOIDmode, retry_label));
17901 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17902 JUMP_LABEL (insn) = retry_label;
17903
17904 DONE;
17905})
17906
17907(define_insn "rdrand<mode>_1"
4ee89d5f
L
17908 [(set (match_operand:SWI248 0 "register_operand" "=r")
17909 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17910 "TARGET_RDRND"
17911 "rdrand %0"
17912 [(set_attr "type" "other")
17913 (set_attr "prefix_extra" "1")])
17914
80e8bb90 17915(include "mmx.md")
b1875f52 17916(include "sse.md")
1ef45b77 17917(include "sync.md")