]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.md
cfgcleanup.c (try_crossjump_to_edge): Only skip past NOTE_INSN_BASIC_BLOCK.
[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,
e47b7d04 3;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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
33;; E,e -- likewise, but for compare-and-branch fused insn.
34;; F,f -- likewise, but for floating-point.
35;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36;; otherwise nothing
37;; R -- print the prefix for register names.
38;; z -- print the opcode suffix for the size of the current operand.
b91322f2 39;; Z -- likewise, with special suffixes for x87 instructions.
a3a5e3d1
UB
40;; * -- print a star (in certain assembler syntax)
41;; A -- print an absolute memory reference.
42;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43;; s -- print a shift double count, followed by the assemblers argument
44;; delimiter.
45;; b -- print the QImode name of the register for the indicated operand.
46;; %b0 would print %al if operands[0] is reg 0.
47;; w -- likewise, print the HImode name of the register.
48;; k -- likewise, print the SImode name of the register.
49;; q -- likewise, print the DImode name of the register.
50;; x -- likewise, print the V4SFmode name of the register.
51;; t -- likewise, print the V8SFmode name of the register.
52;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53;; y -- print "st(0)" instead of "st" as a register.
54;; d -- print duplicated register operand for AVX instruction.
55;; D -- print condition for SSE cmp instruction.
56;; P -- if PIC, print an @PLT suffix.
57;; X -- don't print any sort of PIC '@' suffix for a symbol.
58;; & -- print some in-use local-dynamic symbol name.
59;; H -- print a memory address offset by 8; used for sse high-parts
60;; Y -- print condition for SSE5 com* instruction.
61;; + -- print a branch hint as 'cs' or 'ds' prefix
62;; ; -- print a semicolon (after prefixes due to bug in older gas).
8ee41eaf 63
4af3895e 64;; UNSPEC usage:
8ee41eaf
RH
65
66(define_constants
f996902d
RH
67 [; Relocation specifiers
68 (UNSPEC_GOT 0)
69 (UNSPEC_GOTOFF 1)
70 (UNSPEC_GOTPCREL 2)
71 (UNSPEC_GOTTPOFF 3)
72 (UNSPEC_TPOFF 4)
73 (UNSPEC_NTPOFF 5)
74 (UNSPEC_DTPOFF 6)
dea73790
JJ
75 (UNSPEC_GOTNTPOFF 7)
76 (UNSPEC_INDNTPOFF 8)
dc4d7240 77 (UNSPEC_PLTOFF 9)
08a6a74b 78 (UNSPEC_MACHOPIC_OFFSET 10)
f996902d
RH
79
80 ; Prologue support
f996902d
RH
81 (UNSPEC_STACK_ALLOC 11)
82 (UNSPEC_SET_GOT 12)
8ee41eaf 83 (UNSPEC_SSE_PROLOGUE_SAVE 13)
150cdc9e
RH
84 (UNSPEC_REG_SAVE 14)
85 (UNSPEC_DEF_CFA 15)
dc4d7240
JH
86 (UNSPEC_SET_RIP 16)
87 (UNSPEC_SET_GOT_OFFSET 17)
b058b753 88 (UNSPEC_MEMORY_BLOCKAGE 18)
f996902d
RH
89
90 ; TLS support
b058b753
UB
91 (UNSPEC_TP 20)
92 (UNSPEC_TLS_GD 21)
93 (UNSPEC_TLS_LD_BASE 22)
94 (UNSPEC_TLSDESC 23)
f996902d
RH
95
96 ; Other random patterns
dc4d7240
JH
97 (UNSPEC_SCAS 30)
98 (UNSPEC_FNSTSW 31)
99 (UNSPEC_SAHF 32)
100 (UNSPEC_FSTCW 33)
101 (UNSPEC_ADD_CARRY 34)
102 (UNSPEC_FLDCW 35)
103 (UNSPEC_REP 36)
dc4d7240
JH
104 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
105 (UNSPEC_TRUNC_NOOP 39)
8ee41eaf
RH
106
107 ; For SSE/MMX support:
dc4d7240
JH
108 (UNSPEC_FIX_NOTRUNC 40)
109 (UNSPEC_MASKMOV 41)
110 (UNSPEC_MOVMSK 42)
111 (UNSPEC_MOVNT 43)
112 (UNSPEC_MOVU 44)
113 (UNSPEC_RCP 45)
114 (UNSPEC_RSQRT 46)
115 (UNSPEC_SFENCE 47)
dc4d7240 116 (UNSPEC_PFRCP 49)
d7b4b07a
RH
117 (UNSPEC_PFRCPIT1 40)
118 (UNSPEC_PFRCPIT2 41)
119 (UNSPEC_PFRSQRT 42)
120 (UNSPEC_PFRSQIT1 43)
121 (UNSPEC_MFENCE 44)
122 (UNSPEC_LFENCE 45)
123 (UNSPEC_PSADBW 46)
96208aed 124 (UNSPEC_LDDQU 47)
924eabec 125 (UNSPEC_MS_TO_SYSV_CALL 48)
d7b4b07a
RH
126
127 ; Generic math support
128 (UNSPEC_COPYSIGN 50)
ab8efbd8
RH
129 (UNSPEC_IEEE_MIN 51) ; not commutative
130 (UNSPEC_IEEE_MAX 52) ; not commutative
1fb54135
RS
131
132 ; x87 Floating point
d7b4b07a
RH
133 (UNSPEC_SIN 60)
134 (UNSPEC_COS 61)
135 (UNSPEC_FPATAN 62)
136 (UNSPEC_FYL2X 63)
137 (UNSPEC_FYL2XP1 64)
138 (UNSPEC_FRNDINT 65)
139 (UNSPEC_FIST 66)
140 (UNSPEC_F2XM1 67)
d85c7550 141 (UNSPEC_TAN 68)
9ed4207f 142 (UNSPEC_FXAM 69)
d7b4b07a
RH
143
144 ; x87 Rounding
145 (UNSPEC_FRNDINT_FLOOR 70)
146 (UNSPEC_FRNDINT_CEIL 71)
147 (UNSPEC_FRNDINT_TRUNC 72)
148 (UNSPEC_FRNDINT_MASK_PM 73)
4a927664
UB
149 (UNSPEC_FIST_FLOOR 74)
150 (UNSPEC_FIST_CEIL 75)
253c7a00 151
a072d43b 152 ; x87 Double output FP
6c7cf1f0
UB
153 (UNSPEC_SINCOS_COS 80)
154 (UNSPEC_SINCOS_SIN 81)
88b28a31
UB
155 (UNSPEC_XTRACT_FRACT 84)
156 (UNSPEC_XTRACT_EXP 85)
f964bd29
UB
157 (UNSPEC_FSCALE_FRACT 86)
158 (UNSPEC_FSCALE_EXP 87)
5ae27cfa
UB
159 (UNSPEC_FPREM_F 88)
160 (UNSPEC_FPREM_U 89)
161 (UNSPEC_FPREM1_F 90)
162 (UNSPEC_FPREM1_U 91)
77008252 163
79cd820a 164 (UNSPEC_C2_FLAG 95)
6b67572e 165 (UNSPEC_FXAM_MEM 96)
79cd820a 166
77008252
JJ
167 ; SSP patterns
168 (UNSPEC_SP_SET 100)
169 (UNSPEC_SP_TEST 101)
170 (UNSPEC_SP_TLS_SET 102)
171 (UNSPEC_SP_TLS_TEST 103)
b1875f52
L
172
173 ; SSSE3
174 (UNSPEC_PSHUFB 120)
175 (UNSPEC_PSIGN 121)
176 (UNSPEC_PALIGNR 122)
21efb4d4
HJ
177
178 ; For SSE4A support
179 (UNSPEC_EXTRQI 130)
4f3f76e6 180 (UNSPEC_EXTRQ 131)
21efb4d4
HJ
181 (UNSPEC_INSERTQI 132)
182 (UNSPEC_INSERTQ 133)
9a5cee02
L
183
184 ; For SSE4.1 support
185 (UNSPEC_BLENDV 134)
186 (UNSPEC_INSERTPS 135)
187 (UNSPEC_DP 136)
188 (UNSPEC_MOVNTDQA 137)
189 (UNSPEC_MPSADBW 138)
190 (UNSPEC_PHMINPOSUW 139)
191 (UNSPEC_PTEST 140)
f28eb39c 192 (UNSPEC_ROUND 141)
3b8dd071
L
193
194 ; For SSE4.2 support
195 (UNSPEC_CRC32 143)
06f4e35d
L
196 (UNSPEC_PCMPESTR 144)
197 (UNSPEC_PCMPISTR 145)
04e1d06b
MM
198
199 ;; For SSE5
200 (UNSPEC_SSE5_INTRINSIC 150)
201 (UNSPEC_SSE5_UNSIGNED_CMP 151)
202 (UNSPEC_SSE5_TRUEFALSE 152)
203 (UNSPEC_SSE5_PERMUTE 153)
71d46ca5
MM
204 (UNSPEC_FRCZ 154)
205 (UNSPEC_CVTPH2PS 155)
206 (UNSPEC_CVTPS2PH 156)
8b96a312
L
207
208 ; For AES support
209 (UNSPEC_AESENC 159)
210 (UNSPEC_AESENCLAST 160)
211 (UNSPEC_AESDEC 161)
212 (UNSPEC_AESDECLAST 162)
213 (UNSPEC_AESIMC 163)
214 (UNSPEC_AESKEYGENASSIST 164)
215
216 ; For PCLMUL support
217 (UNSPEC_PCLMUL 165)
95879c72
L
218
219 ; For AVX support
220 (UNSPEC_PCMP 166)
221 (UNSPEC_VPERMIL 167)
e47b7d04
L
222 (UNSPEC_VPERMIL2F128 168)
223 (UNSPEC_MASKLOAD 169)
224 (UNSPEC_MASKSTORE 170)
225 (UNSPEC_CAST 171)
226 (UNSPEC_VTESTP 172)
8ee41eaf
RH
227 ])
228
229(define_constants
230 [(UNSPECV_BLOCKAGE 0)
d7b4b07a
RH
231 (UNSPECV_STACK_PROBE 1)
232 (UNSPECV_EMMS 2)
233 (UNSPECV_LDMXCSR 3)
234 (UNSPECV_STMXCSR 4)
235 (UNSPECV_FEMMS 5)
236 (UNSPECV_CLFLUSH 6)
237 (UNSPECV_ALIGN 7)
238 (UNSPECV_MONITOR 8)
239 (UNSPECV_MWAIT 9)
148153c1 240 (UNSPECV_CMPXCHG 10)
1ef45b77
RH
241 (UNSPECV_XCHG 12)
242 (UNSPECV_LOCK 13)
6fb5fa3c 243 (UNSPECV_PROLOGUE_USE 14)
922e3e33 244 (UNSPECV_CLD 15)
95879c72
L
245 (UNSPECV_VZEROALL 16)
246 (UNSPECV_VZEROUPPER 17)
8ee41eaf 247 ])
915119a5 248
84fbffb2 249;; Constants to represent pcomtrue/pcomfalse variants
04e1d06b
MM
250(define_constants
251 [(PCOM_FALSE 0)
252 (PCOM_TRUE 1)
253 (COM_FALSE_S 2)
254 (COM_FALSE_P 3)
255 (COM_TRUE_S 4)
256 (COM_TRUE_P 5)
257 ])
258
71d46ca5
MM
259;; Constants used in the SSE5 pperm instruction
260(define_constants
261 [(PPERM_SRC 0x00) /* copy source */
262 (PPERM_INVERT 0x20) /* invert source */
263 (PPERM_REVERSE 0x40) /* bit reverse source */
264 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
265 (PPERM_ZERO 0x80) /* all 0's */
266 (PPERM_ONES 0xa0) /* all 1's */
267 (PPERM_SIGN 0xc0) /* propagate sign bit */
268 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
269 (PPERM_SRC1 0x00) /* use first source byte */
270 (PPERM_SRC2 0x10) /* use second source byte */
271 ])
272
8bc527af
SB
273;; Registers by name.
274(define_constants
29b74761
UB
275 [(AX_REG 0)
276 (DX_REG 1)
277 (CX_REG 2)
2e3f842f 278 (BX_REG 3)
8ec12e35
NF
279 (SI_REG 4)
280 (DI_REG 5)
29b74761 281 (BP_REG 6)
8bc527af 282 (SP_REG 7)
78168632
UB
283 (ST0_REG 8)
284 (ST1_REG 9)
285 (ST2_REG 10)
286 (ST3_REG 11)
287 (ST4_REG 12)
288 (ST5_REG 13)
289 (ST6_REG 14)
290 (ST7_REG 15)
8bc527af
SB
291 (FLAGS_REG 17)
292 (FPSR_REG 18)
03c259ad 293 (FPCR_REG 19)
95879c72
L
294 (XMM0_REG 21)
295 (XMM1_REG 22)
296 (XMM2_REG 23)
297 (XMM3_REG 24)
298 (XMM4_REG 25)
299 (XMM5_REG 26)
300 (XMM6_REG 27)
301 (XMM7_REG 28)
78168632
UB
302 (MM0_REG 29)
303 (MM1_REG 30)
304 (MM2_REG 31)
305 (MM3_REG 32)
306 (MM4_REG 33)
307 (MM5_REG 34)
308 (MM6_REG 35)
309 (MM7_REG 36)
6c6094f1
UB
310 (R8_REG 37)
311 (R9_REG 38)
b0d95de8
UB
312 (R10_REG 39)
313 (R11_REG 40)
a952487c 314 (R12_REG 41)
2e3f842f 315 (R13_REG 42)
95879c72
L
316 (XMM8_REG 45)
317 (XMM9_REG 46)
318 (XMM10_REG 47)
319 (XMM11_REG 48)
320 (XMM12_REG 49)
321 (XMM13_REG 50)
322 (XMM14_REG 51)
323 (XMM15_REG 52)
8bc527af
SB
324 ])
325
6343a50e
ZW
326;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
327;; from i386.c.
328
1b0c37d7
ZW
329;; In C guard expressions, put expressions which may be compile-time
330;; constants first. This allows for better optimization. For
331;; example, write "TARGET_64BIT && reload_completed", not
332;; "reload_completed && TARGET_64BIT".
333
2ae0f82c 334\f
7ab91c5f 335;; Processor type.
b6837b94 336(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
7ab91c5f
L
337 generic64,amdfam10"
338 (const (symbol_ref "ix86_schedule")))
2ae0f82c 339
e075ae69
RH
340;; A basic instruction type. Refinements due to arguments to be
341;; provided in other attributes.
a269a03c 342(define_attr "type"
9a5834ae
ZW
343 "other,multi,
344 alu,alu1,negnot,imov,imovx,lea,
1b245ade 345 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
9a5834ae 346 icmp,test,ibr,setcc,icmov,
4977bab6 347 push,pop,call,callv,leave,
21efb4d4 348 str,bitmanip,
9199f050 349 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
04e1d06b
MM
350 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
351 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
352 ssemuladd,sse4arg,
9a5834ae 353 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
e075ae69
RH
354 (const_string "other"))
355
6ef67412 356;; Main data type used by the insn
9a5834ae 357(define_attr "mode"
95879c72 358 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
6ef67412
JH
359 (const_string "unknown"))
360
3d34cd91
JH
361;; The CPU unit operations uses.
362(define_attr "unit" "integer,i387,sse,mmx,unknown"
9199f050 363 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
3d34cd91 364 (const_string "i387")
04e1d06b
MM
365 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
366 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
367 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
3d34cd91 368 (const_string "sse")
9a5834ae 369 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
4c9c9a3d
JH
370 (const_string "mmx")
371 (eq_attr "type" "other")
372 (const_string "unknown")]
3d34cd91 373 (const_string "integer")))
6ef67412
JH
374
375;; The (bounding maximum) length of an instruction immediate.
376(define_attr "length_immediate" ""
21efb4d4
HJ
377 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
378 bitmanip")
6ef67412 379 (const_int 0)
3d34cd91 380 (eq_attr "unit" "i387,sse,mmx")
6ef67412 381 (const_int 0)
1b245ade
JH
382 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
383 imul,icmp,push,pop")
6ef67412
JH
384 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
385 (eq_attr "type" "imov,test")
386 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
387 (eq_attr "type" "call")
388 (if_then_else (match_operand 0 "constant_call_address_operand" "")
389 (const_int 4)
390 (const_int 0))
391 (eq_attr "type" "callv")
392 (if_then_else (match_operand 1 "constant_call_address_operand" "")
393 (const_int 4)
394 (const_int 0))
efcc7037
JH
395 ;; We don't know the size before shorten_branches. Expect
396 ;; the instruction to fit for better scheduling.
6ef67412 397 (eq_attr "type" "ibr")
efcc7037 398 (const_int 1)
6ef67412 399 ]
9a5834ae 400 (symbol_ref "/* Update immediate_length and other attributes! */
7637e42c 401 gcc_unreachable (),1")))
e075ae69 402
6ef67412
JH
403;; The (bounding maximum) length of an instruction address.
404(define_attr "length_address" ""
90c56b45 405 (cond [(eq_attr "type" "str,other,multi,fxch")
6ef67412
JH
406 (const_int 0)
407 (and (eq_attr "type" "call")
c7375e61 408 (match_operand 0 "constant_call_address_operand" ""))
6ef67412
JH
409 (const_int 0)
410 (and (eq_attr "type" "callv")
411 (match_operand 1 "constant_call_address_operand" ""))
412 (const_int 0)
413 ]
414 (symbol_ref "ix86_attr_length_address_default (insn)")))
415
416;; Set when length prefix is used.
417(define_attr "prefix_data16" ""
725fd454
JJ
418 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
419 (const_int 0)
420 (eq_attr "mode" "HI")
421 (const_int 1)
422 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
423 (const_int 1)
424 ]
425 (const_int 0)))
6ef67412
JH
426
427;; Set when string REP prefix is used.
6300f037 428(define_attr "prefix_rep" ""
725fd454
JJ
429 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
430 (const_int 0)
431 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
432 (const_int 1)
433 ]
434 (const_int 0)))
6ef67412
JH
435
436;; Set when 0f opcode prefix is used.
437(define_attr "prefix_0f" ""
6300f037 438 (if_then_else
21efb4d4 439 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
cb297538 440 (eq_attr "unit" "sse,mmx"))
6ef67412
JH
441 (const_int 1)
442 (const_int 0)))
443
56bab446 444;; Set when REX opcode prefix is used.
4977bab6 445(define_attr "prefix_rex" ""
a952487c
JJ
446 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
447 (const_int 0)
448 (and (eq_attr "mode" "DI")
725fd454
JJ
449 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
450 (eq_attr "unit" "!mmx")))
4977bab6
ZW
451 (const_int 1)
452 (and (eq_attr "mode" "QI")
453 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
454 (const_int 0)))
455 (const_int 1)
456 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
457 (const_int 0))
458 (const_int 1)
a952487c
JJ
459 (and (eq_attr "type" "imovx")
460 (match_operand:QI 1 "ext_QIreg_operand" ""))
461 (const_int 1)
4977bab6
ZW
462 ]
463 (const_int 0)))
464
725fd454
JJ
465;; There are also additional prefixes in 3DNOW, SSSE3 or SSE5.
466;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
467;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
468;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
469(define_attr "prefix_extra" ""
470 (cond [(eq_attr "type" "ssemuladd,sse4arg")
471 (const_int 2)
472 (eq_attr "type" "sseiadd1,ssecvt1")
473 (const_int 1)
474 ]
475 (const_int 0)))
10e4d956 476
95879c72
L
477;; Prefix used: original, VEX or maybe VEX.
478(define_attr "prefix" "orig,vex,maybe_vex"
479 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
480 (const_string "vex")
481 (const_string "orig")))
482
95879c72
L
483;; VEX W bit is used.
484(define_attr "prefix_vex_w" "" (const_int 0))
485
486;; The length of VEX prefix
725fd454
JJ
487;; Only instructions with 0f prefix can have 2 byte VEX prefix,
488;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
489;; still prefix_0f 1, with prefix_extra 1.
95879c72 490(define_attr "length_vex" ""
725fd454
JJ
491 (if_then_else (and (eq_attr "prefix_0f" "1")
492 (eq_attr "prefix_extra" "0"))
95879c72
L
493 (if_then_else (eq_attr "prefix_vex_w" "1")
494 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
495 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
496 (if_then_else (eq_attr "prefix_vex_w" "1")
497 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
498 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
499
6ef67412
JH
500;; Set when modrm byte is used.
501(define_attr "modrm" ""
90c56b45 502 (cond [(eq_attr "type" "str,leave")
6ef67412 503 (const_int 0)
3d34cd91 504 (eq_attr "unit" "i387")
6ef67412 505 (const_int 0)
e075ae69 506 (and (eq_attr "type" "incdec")
725fd454
JJ
507 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
508 (ior (match_operand:SI 1 "register_operand" "")
509 (match_operand:HI 1 "register_operand" ""))))
6ef67412 510 (const_int 0)
e075ae69
RH
511 (and (eq_attr "type" "push")
512 (not (match_operand 1 "memory_operand" "")))
6ef67412 513 (const_int 0)
e075ae69
RH
514 (and (eq_attr "type" "pop")
515 (not (match_operand 0 "memory_operand" "")))
6ef67412 516 (const_int 0)
e075ae69 517 (and (eq_attr "type" "imov")
a952487c
JJ
518 (and (not (eq_attr "mode" "DI"))
519 (ior (and (match_operand 0 "register_operand" "")
520 (match_operand 1 "immediate_operand" ""))
521 (ior (and (match_operand 0 "ax_reg_operand" "")
522 (match_operand 1 "memory_displacement_only_operand" ""))
523 (and (match_operand 0 "memory_displacement_only_operand" "")
524 (match_operand 1 "ax_reg_operand" ""))))))
6ef67412 525 (const_int 0)
c7375e61
EB
526 (and (eq_attr "type" "call")
527 (match_operand 0 "constant_call_address_operand" ""))
528 (const_int 0)
529 (and (eq_attr "type" "callv")
530 (match_operand 1 "constant_call_address_operand" ""))
531 (const_int 0)
a952487c
JJ
532 (and (eq_attr "type" "alu,alu1,icmp,test")
533 (match_operand 0 "ax_reg_operand" ""))
534 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
e075ae69 535 ]
6ef67412
JH
536 (const_int 1)))
537
538;; The (bounding maximum) length of an instruction in bytes.
edeacc14
UB
539;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
540;; Later we may want to split them and compute proper length as for
541;; other insns.
6ef67412 542(define_attr "length" ""
edeacc14 543 (cond [(eq_attr "type" "other,multi,fistp,frndint")
6ef67412 544 (const_int 16)
a3033f34
EB
545 (eq_attr "type" "fcmp")
546 (const_int 4)
3d34cd91
JH
547 (eq_attr "unit" "i387")
548 (plus (const_int 2)
549 (plus (attr "prefix_data16")
95879c72
L
550 (attr "length_address")))
551 (ior (eq_attr "prefix" "vex")
552 (and (eq_attr "prefix" "maybe_vex")
553 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
554 (plus (attr "length_vex")
725fd454 555 (plus (attr "length_immediate")
95879c72
L
556 (plus (attr "modrm")
557 (attr "length_address"))))]
6ef67412
JH
558 (plus (plus (attr "modrm")
559 (plus (attr "prefix_0f")
4977bab6 560 (plus (attr "prefix_rex")
10e4d956
L
561 (plus (attr "prefix_extra")
562 (const_int 1)))))
6ef67412
JH
563 (plus (attr "prefix_rep")
564 (plus (attr "prefix_data16")
565 (plus (attr "length_immediate")
566 (attr "length_address")))))))
e075ae69
RH
567
568;; The `memory' attribute is `none' if no memory is referenced, `load' or
569;; `store' if there is a simple memory reference therein, or `unknown'
570;; if the instruction is complex.
571
572(define_attr "memory" "none,load,store,both,unknown"
7c7ef435 573 (cond [(eq_attr "type" "other,multi,str")
e075ae69 574 (const_string "unknown")
90c56b45 575 (eq_attr "type" "lea,fcmov,fpspc")
e075ae69 576 (const_string "none")
4977bab6 577 (eq_attr "type" "fistp,leave")
22fb740d 578 (const_string "both")
edeacc14
UB
579 (eq_attr "type" "frndint")
580 (const_string "load")
e075ae69
RH
581 (eq_attr "type" "push")
582 (if_then_else (match_operand 1 "memory_operand" "")
583 (const_string "both")
584 (const_string "store"))
abd2dd6d 585 (eq_attr "type" "pop")
e075ae69
RH
586 (if_then_else (match_operand 0 "memory_operand" "")
587 (const_string "both")
588 (const_string "load"))
abd2dd6d
JH
589 (eq_attr "type" "setcc")
590 (if_then_else (match_operand 0 "memory_operand" "")
591 (const_string "store")
592 (const_string "none"))
f56e86bd 593 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
e075ae69
RH
594 (if_then_else (ior (match_operand 0 "memory_operand" "")
595 (match_operand 1 "memory_operand" ""))
596 (const_string "load")
597 (const_string "none"))
598 (eq_attr "type" "ibr")
599 (if_then_else (match_operand 0 "memory_operand" "")
600 (const_string "load")
601 (const_string "none"))
602 (eq_attr "type" "call")
603 (if_then_else (match_operand 0 "constant_call_address_operand" "")
604 (const_string "none")
605 (const_string "load"))
606 (eq_attr "type" "callv")
607 (if_then_else (match_operand 1 "constant_call_address_operand" "")
608 (const_string "none")
609 (const_string "load"))
ef719a44 610 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
a269a03c 611 (match_operand 1 "memory_operand" ""))
e075ae69
RH
612 (const_string "both")
613 (and (match_operand 0 "memory_operand" "")
614 (match_operand 1 "memory_operand" ""))
615 (const_string "both")
616 (match_operand 0 "memory_operand" "")
617 (const_string "store")
618 (match_operand 1 "memory_operand" "")
619 (const_string "load")
9a5834ae 620 (and (eq_attr "type"
f527d196 621 "!alu1,negnot,ishift1,
21efb4d4 622 imov,imovx,icmp,test,bitmanip,
9a5834ae 623 fmov,fcmp,fsgn,
04e1d06b
MM
624 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
625 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
e075ae69
RH
626 (match_operand 2 "memory_operand" ""))
627 (const_string "load")
04e1d06b 628 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
e075ae69
RH
629 (match_operand 3 "memory_operand" ""))
630 (const_string "load")
631 ]
a269a03c
JC
632 (const_string "none")))
633
e075ae69
RH
634;; Indicates if an instruction has both an immediate and a displacement.
635
636(define_attr "imm_disp" "false,true,unknown"
637 (cond [(eq_attr "type" "other,multi")
638 (const_string "unknown")
1b245ade 639 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
e075ae69
RH
640 (and (match_operand 0 "memory_displacement_operand" "")
641 (match_operand 1 "immediate_operand" "")))
642 (const_string "true")
890d52e8 643 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
e075ae69
RH
644 (and (match_operand 0 "memory_displacement_operand" "")
645 (match_operand 2 "immediate_operand" "")))
646 (const_string "true")
647 ]
648 (const_string "false")))
649
650;; Indicates if an FP operation has an integer source.
651
652(define_attr "fp_int_src" "false,true"
653 (const_string "false"))
654
edeacc14
UB
655;; Defines rounding mode of an FP operation.
656
ff680eb1 657(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
edeacc14
UB
658 (const_string "any"))
659
b6837b94
JY
660;; Define attribute to classify add/sub insns that consumes carry flag (CF)
661(define_attr "use_carry" "0,1" (const_string "0"))
662
663;; Define attribute to indicate unaligned ssemov insns
664(define_attr "movu" "0,1" (const_string "0"))
665
e075ae69
RH
666;; Describe a user's asm statement.
667(define_asm_attributes
668 [(set_attr "length" "128")
669 (set_attr "type" "multi")])
0e8c2b0d 670
a7438d6d
UB
671;; All integer comparison codes.
672(define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
673
674;; All floating-point comparison codes.
675(define_code_iterator fp_cond [unordered ordered
676 uneq unge ungt unle unlt ltgt ])
677
3abcb3a7 678(define_code_iterator plusminus [plus minus])
d39d658d 679
d1c3b587
L
680(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
681
682;; Base name for define_insn
683(define_code_attr plusminus_insn
684 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
685 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
686
687;; Base name for insn mnemonic.
688(define_code_attr plusminus_mnemonic
689 [(plus "add") (ss_plus "adds") (us_plus "addus")
690 (minus "sub") (ss_minus "subs") (us_minus "subus")])
d39d658d
RIL
691
692;; Mark commutative operators as such in constraints.
d1c3b587
L
693(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
694 (minus "") (ss_minus "") (us_minus "")])
d39d658d 695
78e8956b
L
696;; Mapping of signed max and min
697(define_code_iterator smaxmin [smax smin])
698
699;; Mapping of unsigned max and min
700(define_code_iterator umaxmin [umax umin])
701
95879c72
L
702;; Mapping of signed/unsigned max and min
703(define_code_iterator maxmin [smax smin umax umin])
704
78e8956b 705;; Base name for integer and FP insn mnemonic
6dd18eb1
UB
706(define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
707 (umax "maxu") (umin "minu")])
78e8956b
L
708(define_code_attr maxminfprefix [(smax "max") (smin "min")])
709
94237c92
L
710;; Mapping of parallel logic operators
711(define_code_iterator plogic [and ior xor])
712
713;; Base name for insn mnemonic.
714(define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
715
6dd18eb1
UB
716;; Mapping of abs neg operators
717(define_code_iterator absneg [abs neg])
718
719;; Base name for x87 insn mnemonic.
720(define_code_attr absnegprefix [(abs "abs") (neg "chs")])
721
d39d658d 722;; All single word integer modes.
3abcb3a7 723(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
d39d658d 724
a00ce5fe
UB
725;; Single word integer modes without QImode.
726(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
4e7f50e5 727
d39d658d
RIL
728;; Instruction suffix for integer modes.
729(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
730
731;; Register class for integer modes.
732(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
733
734;; Immediate operand constraint for integer modes.
0edb82cb 735(define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
d39d658d
RIL
736
737;; General operand predicate for integer modes.
738(define_mode_attr general_operand
739 [(QI "general_operand")
740 (HI "general_operand")
741 (SI "general_operand")
742 (DI "x86_64_general_operand")])
743
00188daa
UB
744;; SSE and x87 SFmode and DFmode floating point modes
745(define_mode_iterator MODEF [SF DF])
746
9199f050 747;; All x87 floating point modes
3abcb3a7 748(define_mode_iterator X87MODEF [SF DF XF])
6300f037 749
9199f050 750;; All integer modes handled by x87 fisttp operator.
3abcb3a7 751(define_mode_iterator X87MODEI [HI SI DI])
9199f050 752
0e8c2b0d 753;; All integer modes handled by integer x87 operators.
3abcb3a7 754(define_mode_iterator X87MODEI12 [HI SI])
9199f050 755
9199f050 756;; All integer modes handled by SSE cvtts?2si* operators.
3abcb3a7 757(define_mode_iterator SSEMODEI24 [SI DI])
9199f050 758
01302104
UB
759;; SSE asm suffix for floating point modes
760(define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
761
174c12c7
RH
762;; SSE vector mode corresponding to a scalar mode
763(define_mode_attr ssevecmode
764 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
380edc9f
UB
765
766;; Instruction suffix for REX 64bit operators.
767(define_mode_attr rex64suffix [(SI "") (DI "{q}")])
90b48492
KT
768
769;; This mode iterator allows :P to be used for patterns that operate on
770;; pointer-sized quantities. Exactly one of the two alternatives will match.
771(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
772
e075ae69 773\f
8fe75e43
RH
774;; Scheduling descriptions
775
af2728a4
JL
776(include "pentium.md")
777(include "ppro.md")
778(include "k6.md")
779(include "athlon.md")
cfe1b18f 780(include "geode.md")
b6837b94 781(include "atom.md")
8fe75e43
RH
782
783\f
08b1e29a 784;; Operand and operator predicates and constraints
8fe75e43
RH
785
786(include "predicates.md")
08b1e29a 787(include "constraints.md")
8fe75e43 788
309ada50 789\f
f90b7a5a 790;; Compare and branch/compare and store instructions.
886c62d1 791
f90b7a5a
PB
792(define_expand "cbranchti4"
793 [(set (reg:CC FLAGS_REG)
794 (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
795 (match_operand:TI 2 "x86_64_general_operand" "")))
796 (set (pc) (if_then_else
797 (match_operator 0 "comparison_operator"
798 [(reg:CC FLAGS_REG)
799 (const_int 0)])
800 (label_ref (match_operand 3 "" ""))
801 (pc)))]
802 "TARGET_64BIT"
803{
804 if (MEM_P (operands[1]) && MEM_P (operands[2]))
805 operands[1] = force_reg (TImode, operands[1]);
806 ix86_compare_op0 = operands[1];
807 ix86_compare_op1 = operands[2];
808 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
809 DONE;
810})
886c62d1 811
f90b7a5a 812(define_expand "cbranchdi4"
28356f52 813 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
814 (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
815 (match_operand:DI 2 "x86_64_general_operand" "")))
816 (set (pc) (if_then_else
817 (match_operator 0 "comparison_operator"
818 [(reg:CC FLAGS_REG)
819 (const_int 0)])
820 (label_ref (match_operand 3 "" ""))
821 (pc)))]
822 ""
823{
824 if (MEM_P (operands[1]) && MEM_P (operands[2]))
825 operands[1] = force_reg (DImode, operands[1]);
826 ix86_compare_op0 = operands[1];
827 ix86_compare_op1 = operands[2];
828 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
829 DONE;
830})
831
832(define_expand "cstoredi4"
833 [(set (reg:CC FLAGS_REG)
834 (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
835 (match_operand:DI 3 "x86_64_general_operand" "")))
836 (set (match_operand:QI 0 "register_operand" "")
837 (match_operator 1 "comparison_operator"
838 [(reg:CC FLAGS_REG)
839 (const_int 0)]))]
28356f52
JB
840 "TARGET_64BIT"
841{
f90b7a5a
PB
842 if (MEM_P (operands[2]) && MEM_P (operands[3]))
843 operands[2] = force_reg (DImode, operands[2]);
844 ix86_compare_op0 = operands[2];
845 ix86_compare_op1 = operands[3];
846 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
28356f52
JB
847 DONE;
848})
849
f90b7a5a 850(define_expand "cbranchsi4"
8bc527af 851 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
852 (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
853 (match_operand:SI 2 "general_operand" "")))
854 (set (pc) (if_then_else
855 (match_operator 0 "comparison_operator"
856 [(reg:CC FLAGS_REG)
857 (const_int 0)])
858 (label_ref (match_operand 3 "" ""))
859 (pc)))]
c572e5ba 860 ""
c572e5ba 861{
f90b7a5a
PB
862 if (MEM_P (operands[1]) && MEM_P (operands[2]))
863 operands[1] = force_reg (SImode, operands[1]);
864 ix86_compare_op0 = operands[1];
865 ix86_compare_op1 = operands[2];
866 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
c572e5ba 867 DONE;
0f40f9f7 868})
c572e5ba 869
f90b7a5a 870(define_expand "cstoresi4"
8bc527af 871 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
872 (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
873 (match_operand:SI 3 "general_operand" "")))
874 (set (match_operand:QI 0 "register_operand" "")
875 (match_operator 1 "comparison_operator"
876 [(reg:CC FLAGS_REG)
877 (const_int 0)]))]
c572e5ba 878 ""
c572e5ba 879{
f90b7a5a
PB
880 if (MEM_P (operands[2]) && MEM_P (operands[3]))
881 operands[2] = force_reg (SImode, operands[2]);
882 ix86_compare_op0 = operands[2];
883 ix86_compare_op1 = operands[3];
884 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
c572e5ba 885 DONE;
0f40f9f7 886})
c572e5ba 887
f90b7a5a 888(define_expand "cbranchhi4"
8bc527af 889 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
890 (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
891 (match_operand:HI 2 "general_operand" "")))
892 (set (pc) (if_then_else
893 (match_operator 0 "comparison_operator"
894 [(reg:CC FLAGS_REG)
895 (const_int 0)])
896 (label_ref (match_operand 3 "" ""))
897 (pc)))]
c572e5ba 898 ""
c572e5ba 899{
f90b7a5a
PB
900 if (MEM_P (operands[1]) && MEM_P (operands[2]))
901 operands[1] = force_reg (HImode, operands[1]);
902 ix86_compare_op0 = operands[1];
903 ix86_compare_op1 = operands[2];
904 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
c572e5ba 905 DONE;
0f40f9f7 906})
c572e5ba 907
f90b7a5a 908(define_expand "cstorehi4"
8bc527af 909 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
910 (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
911 (match_operand:HI 3 "general_operand" "")))
912 (set (match_operand:QI 0 "register_operand" "")
913 (match_operator 1 "comparison_operator"
914 [(reg:CC FLAGS_REG)
915 (const_int 0)]))]
916 ""
c572e5ba 917{
f90b7a5a
PB
918 if (MEM_P (operands[2]) && MEM_P (operands[3]))
919 operands[2] = force_reg (HImode, operands[2]);
920 ix86_compare_op0 = operands[2];
921 ix86_compare_op1 = operands[3];
922 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
923 DONE;
924})
925
926
927(define_expand "cbranchqi4"
928 [(set (reg:CC FLAGS_REG)
929 (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
930 (match_operand:QI 2 "general_operand" "")))
931 (set (pc) (if_then_else
932 (match_operator 0 "comparison_operator"
933 [(reg:CC FLAGS_REG)
934 (const_int 0)])
935 (label_ref (match_operand 3 "" ""))
936 (pc)))]
937 ""
938{
939 if (MEM_P (operands[1]) && MEM_P (operands[2]))
940 operands[1] = force_reg (QImode, operands[1]);
941 ix86_compare_op0 = operands[1];
942 ix86_compare_op1 = operands[2];
943 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
944 DONE;
945})
946
947
948(define_expand "cstoreqi4"
949 [(set (reg:CC FLAGS_REG)
950 (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
951 (match_operand:QI 3 "general_operand" "")))
952 (set (match_operand:QI 0 "register_operand" "")
953 (match_operator 1 "comparison_operator"
954 [(reg:CC FLAGS_REG)
955 (const_int 0)]))]
956 ""
957{
958 if (MEM_P (operands[2]) && MEM_P (operands[3]))
959 operands[2] = force_reg (QImode, operands[2]);
960 ix86_compare_op0 = operands[2];
961 ix86_compare_op1 = operands[3];
962 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
c572e5ba 963 DONE;
0f40f9f7 964})
886c62d1 965
f90b7a5a 966
9b70259d 967(define_insn "cmpdi_ccno_1_rex64"
42fabf21 968 [(set (reg FLAGS_REG)
9b70259d 969 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
0edb82cb 970 (match_operand:DI 1 "const0_operand" "")))]
9b70259d
JH
971 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
972 "@
a23132e1 973 test{q}\t%0, %0
0f40f9f7 974 cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
975 [(set_attr "type" "test,icmp")
976 (set_attr "length_immediate" "0,1")
977 (set_attr "mode" "DI")])
978
979(define_insn "*cmpdi_minus_1_rex64"
42fabf21 980 [(set (reg FLAGS_REG)
9b70259d
JH
981 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
982 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
983 (const_int 0)))]
1b0c37d7 984 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 985 "cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
986 [(set_attr "type" "icmp")
987 (set_attr "mode" "DI")])
988
989(define_expand "cmpdi_1_rex64"
8bc527af 990 [(set (reg:CC FLAGS_REG)
9b70259d
JH
991 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
992 (match_operand:DI 1 "general_operand" "")))]
1b0c37d7 993 "TARGET_64BIT"
9b70259d
JH
994 "")
995
996(define_insn "cmpdi_1_insn_rex64"
42fabf21 997 [(set (reg FLAGS_REG)
9b70259d
JH
998 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
999 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1000 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1001 "cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
1002 [(set_attr "type" "icmp")
1003 (set_attr "mode" "DI")])
1004
1005
9076b9c1 1006(define_insn "*cmpsi_ccno_1"
42fabf21 1007 [(set (reg FLAGS_REG)
9076b9c1 1008 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
0edb82cb 1009 (match_operand:SI 1 "const0_operand" "")))]
9076b9c1 1010 "ix86_match_ccmode (insn, CCNOmode)"
16189740 1011 "@
a23132e1 1012 test{l}\t%0, %0
0f40f9f7 1013 cmp{l}\t{%1, %0|%0, %1}"
6ef67412
JH
1014 [(set_attr "type" "test,icmp")
1015 (set_attr "length_immediate" "0,1")
1016 (set_attr "mode" "SI")])
16189740 1017
9076b9c1 1018(define_insn "*cmpsi_minus_1"
42fabf21 1019 [(set (reg FLAGS_REG)
9076b9c1
JH
1020 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1021 (match_operand:SI 1 "general_operand" "ri,mr"))
1022 (const_int 0)))]
1023 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 1024 "cmp{l}\t{%1, %0|%0, %1}"
9076b9c1 1025 [(set_attr "type" "icmp")
6ef67412 1026 (set_attr "mode" "SI")])
886c62d1 1027
9076b9c1 1028(define_expand "cmpsi_1"
8bc527af 1029 [(set (reg:CC FLAGS_REG)
00188daa
UB
1030 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1031 (match_operand:SI 1 "general_operand" "")))]
9076b9c1
JH
1032 ""
1033 "")
1034
1035(define_insn "*cmpsi_1_insn"
42fabf21 1036 [(set (reg FLAGS_REG)
9076b9c1
JH
1037 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1038 (match_operand:SI 1 "general_operand" "ri,mr")))]
7656aee4 1039 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9076b9c1 1040 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1041 "cmp{l}\t{%1, %0|%0, %1}"
6ef67412
JH
1042 [(set_attr "type" "icmp")
1043 (set_attr "mode" "SI")])
886c62d1 1044
9076b9c1 1045(define_insn "*cmphi_ccno_1"
42fabf21 1046 [(set (reg FLAGS_REG)
16189740 1047 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
0edb82cb 1048 (match_operand:HI 1 "const0_operand" "")))]
16189740 1049 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 1050 "@
a23132e1 1051 test{w}\t%0, %0
0f40f9f7 1052 cmp{w}\t{%1, %0|%0, %1}"
6ef67412
JH
1053 [(set_attr "type" "test,icmp")
1054 (set_attr "length_immediate" "0,1")
1055 (set_attr "mode" "HI")])
886c62d1 1056
9076b9c1 1057(define_insn "*cmphi_minus_1"
42fabf21 1058 [(set (reg FLAGS_REG)
9076b9c1 1059 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
0edb82cb 1060 (match_operand:HI 1 "general_operand" "rn,mr"))
9076b9c1
JH
1061 (const_int 0)))]
1062 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 1063 "cmp{w}\t{%1, %0|%0, %1}"
6ef67412
JH
1064 [(set_attr "type" "icmp")
1065 (set_attr "mode" "HI")])
e075ae69 1066
9076b9c1 1067(define_insn "*cmphi_1"
42fabf21 1068 [(set (reg FLAGS_REG)
9076b9c1 1069 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
0edb82cb 1070 (match_operand:HI 1 "general_operand" "rn,mr")))]
7656aee4 1071 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9076b9c1 1072 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1073 "cmp{w}\t{%1, %0|%0, %1}"
9076b9c1
JH
1074 [(set_attr "type" "icmp")
1075 (set_attr "mode" "HI")])
16189740
RH
1076
1077(define_insn "*cmpqi_ccno_1"
42fabf21 1078 [(set (reg FLAGS_REG)
9076b9c1 1079 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
0edb82cb 1080 (match_operand:QI 1 "const0_operand" "")))]
9076b9c1 1081 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 1082 "@
a23132e1 1083 test{b}\t%0, %0
0f40f9f7 1084 cmp{b}\t{$0, %0|%0, 0}"
6ef67412
JH
1085 [(set_attr "type" "test,icmp")
1086 (set_attr "length_immediate" "0,1")
1087 (set_attr "mode" "QI")])
886c62d1 1088
16189740 1089(define_insn "*cmpqi_1"
42fabf21 1090 [(set (reg FLAGS_REG)
9076b9c1 1091 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
0edb82cb 1092 (match_operand:QI 1 "general_operand" "qn,mq")))]
7656aee4 1093 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9076b9c1 1094 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1095 "cmp{b}\t{%1, %0|%0, %1}"
6ef67412
JH
1096 [(set_attr "type" "icmp")
1097 (set_attr "mode" "QI")])
e075ae69 1098
9076b9c1 1099(define_insn "*cmpqi_minus_1"
42fabf21 1100 [(set (reg FLAGS_REG)
d70401eb 1101 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
0edb82cb 1102 (match_operand:QI 1 "general_operand" "qn,mq"))
9076b9c1
JH
1103 (const_int 0)))]
1104 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 1105 "cmp{b}\t{%1, %0|%0, %1}"
9076b9c1
JH
1106 [(set_attr "type" "icmp")
1107 (set_attr "mode" "QI")])
1108
e075ae69 1109(define_insn "*cmpqi_ext_1"
42fabf21 1110 [(set (reg FLAGS_REG)
9076b9c1 1111 (compare
d2836273 1112 (match_operand:QI 0 "general_operand" "Qm")
e075ae69
RH
1113 (subreg:QI
1114 (zero_extract:SI
d2836273 1115 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1116 (const_int 8)
1117 (const_int 8)) 0)))]
d2836273 1118 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1119 "cmp{b}\t{%h1, %0|%0, %h1}"
d2836273
JH
1120 [(set_attr "type" "icmp")
1121 (set_attr "mode" "QI")])
1122
1123(define_insn "*cmpqi_ext_1_rex64"
42fabf21 1124 [(set (reg FLAGS_REG)
d2836273 1125 (compare
3522082b 1126 (match_operand:QI 0 "register_operand" "Q")
d2836273
JH
1127 (subreg:QI
1128 (zero_extract:SI
1129 (match_operand 1 "ext_register_operand" "Q")
1130 (const_int 8)
1131 (const_int 8)) 0)))]
1132 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1133 "cmp{b}\t{%h1, %0|%0, %h1}"
6ef67412
JH
1134 [(set_attr "type" "icmp")
1135 (set_attr "mode" "QI")])
e075ae69
RH
1136
1137(define_insn "*cmpqi_ext_2"
42fabf21 1138 [(set (reg FLAGS_REG)
16189740 1139 (compare
e075ae69
RH
1140 (subreg:QI
1141 (zero_extract:SI
d2836273 1142 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
1143 (const_int 8)
1144 (const_int 8)) 0)
0edb82cb 1145 (match_operand:QI 1 "const0_operand" "")))]
16189740 1146 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 1147 "test{b}\t%h0, %h0"
6ef67412
JH
1148 [(set_attr "type" "test")
1149 (set_attr "length_immediate" "0")
1150 (set_attr "mode" "QI")])
e075ae69 1151
9076b9c1 1152(define_expand "cmpqi_ext_3"
8bc527af 1153 [(set (reg:CC FLAGS_REG)
e075ae69
RH
1154 (compare:CC
1155 (subreg:QI
1156 (zero_extract:SI
d2836273 1157 (match_operand 0 "ext_register_operand" "")
e075ae69
RH
1158 (const_int 8)
1159 (const_int 8)) 0)
d2836273 1160 (match_operand:QI 1 "general_operand" "")))]
e075ae69 1161 ""
9076b9c1
JH
1162 "")
1163
1164(define_insn "cmpqi_ext_3_insn"
42fabf21 1165 [(set (reg FLAGS_REG)
9076b9c1
JH
1166 (compare
1167 (subreg:QI
1168 (zero_extract:SI
d2836273 1169 (match_operand 0 "ext_register_operand" "Q")
9076b9c1
JH
1170 (const_int 8)
1171 (const_int 8)) 0)
d2836273
JH
1172 (match_operand:QI 1 "general_operand" "Qmn")))]
1173 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1174 "cmp{b}\t{%1, %h0|%h0, %1}"
d2836273 1175 [(set_attr "type" "icmp")
725fd454 1176 (set_attr "modrm" "1")
d2836273
JH
1177 (set_attr "mode" "QI")])
1178
1179(define_insn "cmpqi_ext_3_insn_rex64"
42fabf21 1180 [(set (reg FLAGS_REG)
d2836273
JH
1181 (compare
1182 (subreg:QI
1183 (zero_extract:SI
1184 (match_operand 0 "ext_register_operand" "Q")
1185 (const_int 8)
1186 (const_int 8)) 0)
1187 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1188 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1189 "cmp{b}\t{%1, %h0|%h0, %1}"
6ef67412 1190 [(set_attr "type" "icmp")
725fd454 1191 (set_attr "modrm" "1")
6ef67412 1192 (set_attr "mode" "QI")])
e075ae69
RH
1193
1194(define_insn "*cmpqi_ext_4"
42fabf21 1195 [(set (reg FLAGS_REG)
9076b9c1 1196 (compare
e075ae69
RH
1197 (subreg:QI
1198 (zero_extract:SI
d2836273 1199 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
1200 (const_int 8)
1201 (const_int 8)) 0)
1202 (subreg:QI
1203 (zero_extract:SI
d2836273 1204 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1205 (const_int 8)
1206 (const_int 8)) 0)))]
9076b9c1 1207 "ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1208 "cmp{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
1209 [(set_attr "type" "icmp")
1210 (set_attr "mode" "QI")])
e075ae69
RH
1211
1212;; These implement float point compares.
1213;; %%% See if we can get away with VOIDmode operands on the actual insns,
1214;; which would allow mix and match FP modes on the compares. Which is what
1215;; the old patterns did, but with many more of them.
c572e5ba 1216
f90b7a5a
PB
1217(define_expand "cbranchxf4"
1218 [(set (reg:CC FLAGS_REG)
1219 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1220 (match_operand:XF 2 "nonmemory_operand" "")))
1221 (set (pc) (if_then_else
1222 (match_operator 0 "comparison_operator"
1223 [(reg:CC FLAGS_REG)
1224 (const_int 0)])
1225 (label_ref (match_operand 3 "" ""))
1226 (pc)))]
1227 "TARGET_80387"
1228{
1229 ix86_compare_op0 = operands[1];
1230 ix86_compare_op1 = operands[2];
1231 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1232 DONE;
1233})
1234
1235(define_expand "cstorexf4"
8bc527af 1236 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
1237 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1238 (match_operand:XF 3 "nonmemory_operand" "")))
1239 (set (match_operand:QI 0 "register_operand" "")
1240 (match_operator 1 "comparison_operator"
1241 [(reg:CC FLAGS_REG)
1242 (const_int 0)]))]
2b589241 1243 "TARGET_80387"
2b589241 1244{
f90b7a5a
PB
1245 ix86_compare_op0 = operands[2];
1246 ix86_compare_op1 = operands[3];
1247 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
2b589241 1248 DONE;
0f40f9f7 1249})
2b589241 1250
f90b7a5a 1251(define_expand "cbranch<mode>4"
8bc527af 1252 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
1253 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1254 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1255 (set (pc) (if_then_else
1256 (match_operator 0 "comparison_operator"
1257 [(reg:CC FLAGS_REG)
1258 (const_int 0)])
1259 (label_ref (match_operand 3 "" ""))
1260 (pc)))]
8766652c 1261 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
c572e5ba 1262{
f90b7a5a
PB
1263 ix86_compare_op0 = operands[1];
1264 ix86_compare_op1 = operands[2];
1265 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
c572e5ba 1266 DONE;
0f40f9f7 1267})
c572e5ba 1268
f90b7a5a 1269(define_expand "cstore<mode>4"
4a77c72b 1270 [(set (reg:CC FLAGS_REG)
f90b7a5a
PB
1271 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1272 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1273 (set (match_operand:QI 0 "register_operand" "")
1274 (match_operator 1 "comparison_operator"
1275 [(reg:CC FLAGS_REG)
1276 (const_int 0)]))]
1277 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1278{
1279 ix86_compare_op0 = operands[2];
1280 ix86_compare_op1 = operands[3];
1281 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1282 DONE;
1283})
1284
1285(define_expand "cbranchcc4"
1286 [(set (pc) (if_then_else
1287 (match_operator 0 "comparison_operator"
1288 [(match_operand 1 "flags_reg_operand" "")
1289 (match_operand 2 "const0_operand" "")])
1290 (label_ref (match_operand 3 "" ""))
1291 (pc)))]
1292 ""
1293{
1294 ix86_compare_op0 = operands[1];
1295 ix86_compare_op1 = operands[2];
1296 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1297 DONE;
1298})
1299
1300(define_expand "cstorecc4"
1301 [(set (match_operand:QI 0 "register_operand" "")
1302 (match_operator 1 "comparison_operator"
1303 [(match_operand 2 "flags_reg_operand" "")
1304 (match_operand 3 "const0_operand" "")]))]
4a77c72b
PB
1305 ""
1306{
f90b7a5a
PB
1307 ix86_compare_op0 = operands[2];
1308 ix86_compare_op1 = operands[3];
1309 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
4a77c72b
PB
1310 DONE;
1311})
1312
f90b7a5a 1313
e075ae69
RH
1314;; FP compares, step 1:
1315;; Set the FP condition codes.
1316;;
1317;; CCFPmode compare with exceptions
1318;; CCFPUmode compare with no exceptions
fe4435d9 1319
7c82106f
UB
1320;; We may not use "#" to split and emit these, since the REG_DEAD notes
1321;; used to manage the reg stack popping would not be preserved.
1322
af12f8ea 1323(define_insn "*cmpfp_0"
45c8c47f
UB
1324 [(set (match_operand:HI 0 "register_operand" "=a")
1325 (unspec:HI
1326 [(compare:CCFP
af12f8ea 1327 (match_operand 1 "register_operand" "f")
0edb82cb 1328 (match_operand 2 "const0_operand" ""))]
45c8c47f 1329 UNSPEC_FNSTSW))]
27ac40e2 1330 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
af12f8ea 1331 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7c82106f 1332 "* return output_fp_compare (insn, operands, 0, 0);"
45c8c47f 1333 [(set_attr "type" "multi")
af12f8ea
UB
1334 (set_attr "unit" "i387")
1335 (set (attr "mode")
1336 (cond [(match_operand:SF 1 "" "")
1337 (const_string "SF")
1338 (match_operand:DF 1 "" "")
1339 (const_string "DF")
1340 ]
1341 (const_string "XF")))])
c572e5ba 1342
1406ee90
UB
1343(define_insn_and_split "*cmpfp_0_cc"
1344 [(set (reg:CCFP FLAGS_REG)
1345 (compare:CCFP
1346 (match_operand 1 "register_operand" "f")
0edb82cb 1347 (match_operand 2 "const0_operand" "")))
1406ee90
UB
1348 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1349 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1350 && TARGET_SAHF && !TARGET_CMOVE
1351 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1352 "#"
1353 "&& reload_completed"
1354 [(set (match_dup 0)
1355 (unspec:HI
1356 [(compare:CCFP (match_dup 1)(match_dup 2))]
1357 UNSPEC_FNSTSW))
1358 (set (reg:CC FLAGS_REG)
1359 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1360 ""
1361 [(set_attr "type" "multi")
1362 (set_attr "unit" "i387")
1363 (set (attr "mode")
1364 (cond [(match_operand:SF 1 "" "")
1365 (const_string "SF")
1366 (match_operand:DF 1 "" "")
1367 (const_string "DF")
1368 ]
1369 (const_string "XF")))])
1370
8766652c 1371(define_insn "*cmpfp_xf"
e075ae69
RH
1372 [(set (match_operand:HI 0 "register_operand" "=a")
1373 (unspec:HI
1374 [(compare:CCFP
8766652c
UB
1375 (match_operand:XF 1 "register_operand" "f")
1376 (match_operand:XF 2 "register_operand" "f"))]
8ee41eaf 1377 UNSPEC_FNSTSW))]
4fb21e90 1378 "TARGET_80387"
7c82106f 1379 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412 1380 [(set_attr "type" "multi")
af12f8ea 1381 (set_attr "unit" "i387")
8766652c 1382 (set_attr "mode" "XF")])
e075ae69 1383
1406ee90
UB
1384(define_insn_and_split "*cmpfp_xf_cc"
1385 [(set (reg:CCFP FLAGS_REG)
1386 (compare:CCFP
1387 (match_operand:XF 1 "register_operand" "f")
1388 (match_operand:XF 2 "register_operand" "f")))
1389 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1390 "TARGET_80387
1391 && TARGET_SAHF && !TARGET_CMOVE"
1392 "#"
1393 "&& reload_completed"
1394 [(set (match_dup 0)
1395 (unspec:HI
1396 [(compare:CCFP (match_dup 1)(match_dup 2))]
1397 UNSPEC_FNSTSW))
1398 (set (reg:CC FLAGS_REG)
1399 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1400 ""
1401 [(set_attr "type" "multi")
1402 (set_attr "unit" "i387")
1403 (set_attr "mode" "XF")])
1404
8766652c 1405(define_insn "*cmpfp_<mode>"
e075ae69
RH
1406 [(set (match_operand:HI 0 "register_operand" "=a")
1407 (unspec:HI
1408 [(compare:CCFP
00188daa
UB
1409 (match_operand:MODEF 1 "register_operand" "f")
1410 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
8ee41eaf 1411 UNSPEC_FNSTSW))]
2b589241 1412 "TARGET_80387"
7c82106f 1413 "* return output_fp_compare (insn, operands, 0, 0);"
2b589241 1414 [(set_attr "type" "multi")
af12f8ea 1415 (set_attr "unit" "i387")
8766652c 1416 (set_attr "mode" "<MODE>")])
2b589241 1417
1406ee90
UB
1418(define_insn_and_split "*cmpfp_<mode>_cc"
1419 [(set (reg:CCFP FLAGS_REG)
1420 (compare:CCFP
00188daa
UB
1421 (match_operand:MODEF 1 "register_operand" "f")
1422 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1406ee90
UB
1423 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1424 "TARGET_80387
1425 && TARGET_SAHF && !TARGET_CMOVE"
1426 "#"
1427 "&& reload_completed"
1428 [(set (match_dup 0)
1429 (unspec:HI
1430 [(compare:CCFP (match_dup 1)(match_dup 2))]
1431 UNSPEC_FNSTSW))
1432 (set (reg:CC FLAGS_REG)
1433 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1434 ""
1435 [(set_attr "type" "multi")
1436 (set_attr "unit" "i387")
1437 (set_attr "mode" "<MODE>")])
1438
7c82106f 1439(define_insn "*cmpfp_u"
e075ae69
RH
1440 [(set (match_operand:HI 0 "register_operand" "=a")
1441 (unspec:HI
1442 [(compare:CCFPU
1443 (match_operand 1 "register_operand" "f")
8ee41eaf
RH
1444 (match_operand 2 "register_operand" "f"))]
1445 UNSPEC_FNSTSW))]
27ac40e2 1446 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
e075ae69 1447 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7c82106f 1448 "* return output_fp_compare (insn, operands, 0, 1);"
6ef67412 1449 [(set_attr "type" "multi")
af12f8ea 1450 (set_attr "unit" "i387")
4977bab6
ZW
1451 (set (attr "mode")
1452 (cond [(match_operand:SF 1 "" "")
1453 (const_string "SF")
1454 (match_operand:DF 1 "" "")
1455 (const_string "DF")
1456 ]
1457 (const_string "XF")))])
08a7baac 1458
1406ee90
UB
1459(define_insn_and_split "*cmpfp_u_cc"
1460 [(set (reg:CCFPU FLAGS_REG)
1461 (compare:CCFPU
1462 (match_operand 1 "register_operand" "f")
1463 (match_operand 2 "register_operand" "f")))
1464 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1465 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1466 && TARGET_SAHF && !TARGET_CMOVE
1467 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1468 "#"
1469 "&& reload_completed"
1470 [(set (match_dup 0)
1471 (unspec:HI
1472 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1473 UNSPEC_FNSTSW))
1474 (set (reg:CC FLAGS_REG)
1475 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1476 ""
1477 [(set_attr "type" "multi")
1478 (set_attr "unit" "i387")
1479 (set (attr "mode")
1480 (cond [(match_operand:SF 1 "" "")
1481 (const_string "SF")
1482 (match_operand:DF 1 "" "")
1483 (const_string "DF")
1484 ]
1485 (const_string "XF")))])
1486
0e8c2b0d 1487(define_insn "*cmpfp_<mode>"
7c82106f
UB
1488 [(set (match_operand:HI 0 "register_operand" "=a")
1489 (unspec:HI
1490 [(compare:CCFP
1491 (match_operand 1 "register_operand" "f")
1492 (match_operator 3 "float_operator"
0e8c2b0d 1493 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
7c82106f 1494 UNSPEC_FNSTSW))]
27ac40e2 1495 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
3debdc1e 1496 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
7c82106f
UB
1497 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1498 "* return output_fp_compare (insn, operands, 0, 0);"
1499 [(set_attr "type" "multi")
af12f8ea 1500 (set_attr "unit" "i387")
7c82106f 1501 (set_attr "fp_int_src" "true")
0e8c2b0d 1502 (set_attr "mode" "<MODE>")])
e075ae69 1503
1406ee90
UB
1504(define_insn_and_split "*cmpfp_<mode>_cc"
1505 [(set (reg:CCFP FLAGS_REG)
1506 (compare:CCFP
1507 (match_operand 1 "register_operand" "f")
1508 (match_operator 3 "float_operator"
1509 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1510 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1511 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1512 && TARGET_SAHF && !TARGET_CMOVE
3debdc1e 1513 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1406ee90
UB
1514 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1515 "#"
1516 "&& reload_completed"
1517 [(set (match_dup 0)
1518 (unspec:HI
1519 [(compare:CCFP
1520 (match_dup 1)
1521 (match_op_dup 3 [(match_dup 2)]))]
1522 UNSPEC_FNSTSW))
1523 (set (reg:CC FLAGS_REG)
1524 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1525 ""
1526 [(set_attr "type" "multi")
1527 (set_attr "unit" "i387")
1528 (set_attr "fp_int_src" "true")
1529 (set_attr "mode" "<MODE>")])
1530
e075ae69
RH
1531;; FP compares, step 2
1532;; Move the fpsw to ax.
1533
5ae27cfa 1534(define_insn "x86_fnstsw_1"
e075ae69 1535 [(set (match_operand:HI 0 "register_operand" "=a")
8bc527af 1536 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
2ae0f82c 1537 "TARGET_80387"
0f40f9f7 1538 "fnstsw\t%0"
725fd454 1539 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
6ef67412 1540 (set_attr "mode" "SI")
56bab446 1541 (set_attr "unit" "i387")])
e075ae69
RH
1542
1543;; FP compares, step 3
1544;; Get ax into flags, general case.
1545
1546(define_insn "x86_sahf_1"
8bc527af 1547 [(set (reg:CC FLAGS_REG)
3c2d980c
UB
1548 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1549 UNSPEC_SAHF))]
1550 "TARGET_SAHF"
419452fe
UB
1551{
1552#ifdef HAVE_AS_IX86_SAHF
1553 return "sahf";
1554#else
1555 return ".byte\t0x9e";
1556#endif
1557}
e075ae69 1558 [(set_attr "length" "1")
0b5107cf 1559 (set_attr "athlon_decode" "vector")
21efb4d4 1560 (set_attr "amdfam10_decode" "direct")
56bab446 1561 (set_attr "mode" "SI")])
e075ae69
RH
1562
1563;; Pentium Pro can do steps 1 through 3 in one go.
4f3f76e6 1564;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
eaa49b49 1565(define_insn "*cmpfp_i_mixed"
8bc527af 1566 [(set (reg:CCFP FLAGS_REG)
b5c82fa1
PB
1567 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1568 (match_operand 1 "nonimmediate_operand" "f,xm")))]
eaa49b49 1569 "TARGET_MIX_SSE_I387
0644b628 1570 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
869d095e 1571 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
0644b628 1572 "* return output_fp_compare (insn, operands, 1, 0);"
26771da7 1573 [(set_attr "type" "fcmp,ssecomi")
95879c72 1574 (set_attr "prefix" "orig,maybe_vex")
4977bab6
ZW
1575 (set (attr "mode")
1576 (if_then_else (match_operand:SF 1 "" "")
1577 (const_string "SF")
1578 (const_string "DF")))
725fd454
JJ
1579 (set (attr "prefix_rep")
1580 (if_then_else (eq_attr "type" "ssecomi")
1581 (const_string "0")
1582 (const_string "*")))
1583 (set (attr "prefix_data16")
1584 (cond [(eq_attr "type" "fcmp")
1585 (const_string "*")
1586 (eq_attr "mode" "DF")
1587 (const_string "1")
1588 ]
1589 (const_string "0")))
21efb4d4
HJ
1590 (set_attr "athlon_decode" "vector")
1591 (set_attr "amdfam10_decode" "direct")])
0644b628 1592
eaa49b49 1593(define_insn "*cmpfp_i_sse"
8bc527af 1594 [(set (reg:CCFP FLAGS_REG)
0644b628
JH
1595 (compare:CCFP (match_operand 0 "register_operand" "x")
1596 (match_operand 1 "nonimmediate_operand" "xm")))]
eaa49b49
RH
1597 "TARGET_SSE_MATH
1598 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
869d095e 1599 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
0644b628 1600 "* return output_fp_compare (insn, operands, 1, 0);"
26771da7 1601 [(set_attr "type" "ssecomi")
95879c72 1602 (set_attr "prefix" "maybe_vex")
4977bab6
ZW
1603 (set (attr "mode")
1604 (if_then_else (match_operand:SF 1 "" "")
1605 (const_string "SF")
1606 (const_string "DF")))
725fd454
JJ
1607 (set_attr "prefix_rep" "0")
1608 (set (attr "prefix_data16")
1609 (if_then_else (eq_attr "mode" "DF")
1610 (const_string "1")
1611 (const_string "0")))
21efb4d4
HJ
1612 (set_attr "athlon_decode" "vector")
1613 (set_attr "amdfam10_decode" "direct")])
0644b628 1614
eaa49b49
RH
1615(define_insn "*cmpfp_i_i387"
1616 [(set (reg:CCFP FLAGS_REG)
1617 (compare:CCFP (match_operand 0 "register_operand" "f")
1618 (match_operand 1 "register_operand" "f")))]
27ac40e2
UB
1619 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1620 && TARGET_CMOVE
00188daa 1621 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
e075ae69 1622 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
eaa49b49 1623 "* return output_fp_compare (insn, operands, 1, 0);"
309ada50 1624 [(set_attr "type" "fcmp")
4977bab6
ZW
1625 (set (attr "mode")
1626 (cond [(match_operand:SF 1 "" "")
1627 (const_string "SF")
1628 (match_operand:DF 1 "" "")
1629 (const_string "DF")
1630 ]
1631 (const_string "XF")))
21efb4d4
HJ
1632 (set_attr "athlon_decode" "vector")
1633 (set_attr "amdfam10_decode" "direct")])
0644b628 1634
eaa49b49 1635(define_insn "*cmpfp_iu_mixed"
8bc527af 1636 [(set (reg:CCFPU FLAGS_REG)
b5c82fa1
PB
1637 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1638 (match_operand 1 "nonimmediate_operand" "f,xm")))]
eaa49b49 1639 "TARGET_MIX_SSE_I387
0644b628
JH
1640 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1641 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1642 "* return output_fp_compare (insn, operands, 1, 1);"
26771da7 1643 [(set_attr "type" "fcmp,ssecomi")
95879c72 1644 (set_attr "prefix" "orig,maybe_vex")
4977bab6
ZW
1645 (set (attr "mode")
1646 (if_then_else (match_operand:SF 1 "" "")
1647 (const_string "SF")
1648 (const_string "DF")))
725fd454
JJ
1649 (set (attr "prefix_rep")
1650 (if_then_else (eq_attr "type" "ssecomi")
1651 (const_string "0")
1652 (const_string "*")))
1653 (set (attr "prefix_data16")
1654 (cond [(eq_attr "type" "fcmp")
1655 (const_string "*")
1656 (eq_attr "mode" "DF")
1657 (const_string "1")
1658 ]
1659 (const_string "0")))
21efb4d4
HJ
1660 (set_attr "athlon_decode" "vector")
1661 (set_attr "amdfam10_decode" "direct")])
0644b628 1662
eaa49b49 1663(define_insn "*cmpfp_iu_sse"
8bc527af 1664 [(set (reg:CCFPU FLAGS_REG)
0644b628
JH
1665 (compare:CCFPU (match_operand 0 "register_operand" "x")
1666 (match_operand 1 "nonimmediate_operand" "xm")))]
eaa49b49
RH
1667 "TARGET_SSE_MATH
1668 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
0644b628
JH
1669 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1670 "* return output_fp_compare (insn, operands, 1, 1);"
26771da7 1671 [(set_attr "type" "ssecomi")
95879c72 1672 (set_attr "prefix" "maybe_vex")
4977bab6
ZW
1673 (set (attr "mode")
1674 (if_then_else (match_operand:SF 1 "" "")
1675 (const_string "SF")
1676 (const_string "DF")))
725fd454
JJ
1677 (set_attr "prefix_rep" "0")
1678 (set (attr "prefix_data16")
1679 (if_then_else (eq_attr "mode" "DF")
1680 (const_string "1")
1681 (const_string "0")))
21efb4d4
HJ
1682 (set_attr "athlon_decode" "vector")
1683 (set_attr "amdfam10_decode" "direct")])
eaa49b49
RH
1684
1685(define_insn "*cmpfp_iu_387"
1686 [(set (reg:CCFPU FLAGS_REG)
1687 (compare:CCFPU (match_operand 0 "register_operand" "f")
1688 (match_operand 1 "register_operand" "f")))]
27ac40e2
UB
1689 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1690 && TARGET_CMOVE
00188daa 1691 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
eaa49b49
RH
1692 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1693 "* return output_fp_compare (insn, operands, 1, 1);"
1694 [(set_attr "type" "fcmp")
1695 (set (attr "mode")
1696 (cond [(match_operand:SF 1 "" "")
1697 (const_string "SF")
1698 (match_operand:DF 1 "" "")
1699 (const_string "DF")
1700 ]
1701 (const_string "XF")))
21efb4d4
HJ
1702 (set_attr "athlon_decode" "vector")
1703 (set_attr "amdfam10_decode" "direct")])
e075ae69
RH
1704\f
1705;; Move instructions.
2ae0f82c 1706
e075ae69 1707;; General case of fullword move.
886c62d1 1708
e075ae69
RH
1709(define_expand "movsi"
1710 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1711 (match_operand:SI 1 "general_operand" ""))]
1712 ""
1713 "ix86_expand_move (SImode, operands); DONE;")
08a7baac 1714
e075ae69
RH
1715;; Push/pop instructions. They are separate since autoinc/dec is not a
1716;; general_operand.
1717;;
6300f037 1718;; %%% We don't use a post-inc memory reference because x86 is not a
e075ae69
RH
1719;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1720;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1721;; targets without our curiosities, and it is just as easy to represent
1722;; this differently.
886c62d1 1723
a4414093 1724(define_insn "*pushsi2"
e075ae69 1725 [(set (match_operand:SI 0 "push_operand" "=<")
2c5a510c 1726 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
0ec259ed 1727 "!TARGET_64BIT"
0f40f9f7 1728 "push{l}\t%1"
6ef67412
JH
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
4fb21e90 1731
0ec259ed
JH
1732;; For 64BIT abi we always round up to 8 bytes.
1733(define_insn "*pushsi2_rex64"
1734 [(set (match_operand:SI 0 "push_operand" "=X")
1735 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1736 "TARGET_64BIT"
0f40f9f7 1737 "push{q}\t%q1"
0ec259ed
JH
1738 [(set_attr "type" "push")
1739 (set_attr "mode" "SI")])
1740
bdeb029c
JH
1741(define_insn "*pushsi2_prologue"
1742 [(set (match_operand:SI 0 "push_operand" "=<")
1743 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
f2042df3 1744 (clobber (mem:BLK (scratch)))]
0ec259ed 1745 "!TARGET_64BIT"
0f40f9f7 1746 "push{l}\t%1"
6ef67412
JH
1747 [(set_attr "type" "push")
1748 (set_attr "mode" "SI")])
bdeb029c
JH
1749
1750(define_insn "*popsi1_epilogue"
1751 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
1752 (mem:SI (reg:SI SP_REG)))
1753 (set (reg:SI SP_REG)
1754 (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 1755 (clobber (mem:BLK (scratch)))]
1e07edd3 1756 "!TARGET_64BIT"
0f40f9f7 1757 "pop{l}\t%0"
6ef67412
JH
1758 [(set_attr "type" "pop")
1759 (set_attr "mode" "SI")])
bdeb029c 1760
e075ae69
RH
1761(define_insn "popsi1"
1762 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
1763 (mem:SI (reg:SI SP_REG)))
1764 (set (reg:SI SP_REG)
1765 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1e07edd3 1766 "!TARGET_64BIT"
0f40f9f7 1767 "pop{l}\t%0"
6ef67412
JH
1768 [(set_attr "type" "pop")
1769 (set_attr "mode" "SI")])
c572e5ba 1770
a8bac9ab 1771(define_insn "*movsi_xor"
591702de 1772 [(set (match_operand:SI 0 "register_operand" "=r")
0edb82cb 1773 (match_operand:SI 1 "const0_operand" ""))
8bc527af 1774 (clobber (reg:CC FLAGS_REG))]
18bd082d 1775 "reload_completed"
a23132e1 1776 "xor{l}\t%0, %0"
591702de 1777 [(set_attr "type" "alu1")
6ef67412
JH
1778 (set_attr "mode" "SI")
1779 (set_attr "length_immediate" "0")])
6300f037 1780
591702de
JH
1781(define_insn "*movsi_or"
1782 [(set (match_operand:SI 0 "register_operand" "=r")
1783 (match_operand:SI 1 "immediate_operand" "i"))
8bc527af 1784 (clobber (reg:CC FLAGS_REG))]
87d9741e 1785 "reload_completed
18bd082d 1786 && operands[1] == constm1_rtx"
c572e5ba 1787{
591702de 1788 operands[1] = constm1_rtx;
0f40f9f7
ZW
1789 return "or{l}\t{%1, %0|%0, %1}";
1790}
591702de 1791 [(set_attr "type" "alu1")
6ef67412
JH
1792 (set_attr "mode" "SI")
1793 (set_attr "length_immediate" "1")])
e075ae69 1794
591702de 1795(define_insn "*movsi_1"
6c4ccfd8 1796 [(set (match_operand:SI 0 "nonimmediate_operand"
0edb82cb 1797 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
6c4ccfd8 1798 (match_operand:SI 1 "general_operand"
0edb82cb 1799 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
f75959a6 1800 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
8f62128d
JH
1801{
1802 switch (get_attr_type (insn))
1803 {
f75959a6 1804 case TYPE_SSELOG1:
1d5b4e0b 1805 if (get_attr_mode (insn) == MODE_TI)
95879c72
L
1806 return "%vpxor\t%0, %d0";
1807 return "%vxorps\t%0, %d0";
8f62128d 1808
5f90a099 1809 case TYPE_SSEMOV:
f75959a6
RH
1810 switch (get_attr_mode (insn))
1811 {
1812 case MODE_TI:
95879c72 1813 return "%vmovdqa\t{%1, %0|%0, %1}";
f75959a6 1814 case MODE_V4SF:
95879c72 1815 return "%vmovaps\t{%1, %0|%0, %1}";
f75959a6 1816 case MODE_SI:
95879c72 1817 return "%vmovd\t{%1, %0|%0, %1}";
f75959a6 1818 case MODE_SF:
95879c72 1819 return "%vmovss\t{%1, %0|%0, %1}";
f75959a6
RH
1820 default:
1821 gcc_unreachable ();
1822 }
1823
87673f84 1824 case TYPE_MMX:
f75959a6 1825 return "pxor\t%0, %0";
141e454b 1826
5f90a099 1827 case TYPE_MMXMOV:
1d5b4e0b 1828 if (get_attr_mode (insn) == MODE_DI)
e5a20888 1829 return "movq\t{%1, %0|%0, %1}";
0f40f9f7 1830 return "movd\t{%1, %0|%0, %1}";
915119a5 1831
e075ae69 1832 case TYPE_LEA:
0f40f9f7 1833 return "lea{l}\t{%1, %0|%0, %1}";
915119a5 1834
e075ae69 1835 default:
7637e42c 1836 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
0f40f9f7 1837 return "mov{l}\t{%1, %0|%0, %1}";
886c62d1 1838 }
0f40f9f7 1839}
e075ae69 1840 [(set (attr "type")
f75959a6 1841 (cond [(eq_attr "alternative" "2")
87673f84 1842 (const_string "mmx")
f75959a6 1843 (eq_attr "alternative" "3,4,5")
3d34cd91 1844 (const_string "mmxmov")
f75959a6
RH
1845 (eq_attr "alternative" "6")
1846 (const_string "sselog1")
1847 (eq_attr "alternative" "7,8,9,10,11")
3d34cd91 1848 (const_string "ssemov")
47efdea4 1849 (match_operand:DI 1 "pic_32bit_operand" "")
e075ae69
RH
1850 (const_string "lea")
1851 ]
6ef67412 1852 (const_string "imov")))
95879c72
L
1853 (set (attr "prefix")
1854 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1855 (const_string "orig")
1856 (const_string "maybe_vex")))
725fd454
JJ
1857 (set (attr "prefix_data16")
1858 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1859 (const_string "1")
1860 (const_string "*")))
f75959a6
RH
1861 (set (attr "mode")
1862 (cond [(eq_attr "alternative" "2,3")
1863 (const_string "DI")
1864 (eq_attr "alternative" "6,7")
1865 (if_then_else
1866 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1867 (const_string "V4SF")
1868 (const_string "TI"))
1869 (and (eq_attr "alternative" "8,9,10,11")
1870 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1871 (const_string "SF")
1872 ]
1873 (const_string "SI")))])
e075ae69 1874
d1f87653 1875;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
1876;; We fake an second form of instruction to force reload to load address
1877;; into register when rax is not available
1878(define_insn "*movabssi_1_rex64"
7e6dc358
JJ
1879 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1880 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1881 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 1882 "@
0f40f9f7 1883 movabs{l}\t{%1, %P0|%P0, %1}
7e6dc358 1884 mov{l}\t{%1, %a0|%a0, %1}"
0ec259ed 1885 [(set_attr "type" "imov")
7e6dc358
JJ
1886 (set_attr "modrm" "0,*")
1887 (set_attr "length_address" "8,0")
1888 (set_attr "length_immediate" "0,*")
0ec259ed
JH
1889 (set_attr "memory" "store")
1890 (set_attr "mode" "SI")])
1891
1892(define_insn "*movabssi_2_rex64"
1893 [(set (match_operand:SI 0 "register_operand" "=a,r")
1894 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 1895 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 1896 "@
0f40f9f7
ZW
1897 movabs{l}\t{%P1, %0|%0, %P1}
1898 mov{l}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
1899 [(set_attr "type" "imov")
1900 (set_attr "modrm" "0,*")
1901 (set_attr "length_address" "8,0")
1902 (set_attr "length_immediate" "0")
1903 (set_attr "memory" "load")
1904 (set_attr "mode" "SI")])
1905
e075ae69
RH
1906(define_insn "*swapsi"
1907 [(set (match_operand:SI 0 "register_operand" "+r")
1908 (match_operand:SI 1 "register_operand" "+r"))
1909 (set (match_dup 1)
1910 (match_dup 0))]
2bb7a0f5 1911 ""
0f40f9f7 1912 "xchg{l}\t%1, %0"
e075ae69 1913 [(set_attr "type" "imov")
6ef67412 1914 (set_attr "mode" "SI")
7cc6af0c 1915 (set_attr "pent_pair" "np")
21efb4d4 1916 (set_attr "athlon_decode" "vector")
4f3f76e6 1917 (set_attr "amdfam10_decode" "double")])
886c62d1 1918
e075ae69
RH
1919(define_expand "movhi"
1920 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1921 (match_operand:HI 1 "general_operand" ""))]
ca097615 1922 ""
e075ae69 1923 "ix86_expand_move (HImode, operands); DONE;")
2f2a49e8 1924
a4414093 1925(define_insn "*pushhi2"
6541fe75
JJ
1926 [(set (match_operand:HI 0 "push_operand" "=X")
1927 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1e07edd3 1928 "!TARGET_64BIT"
6541fe75 1929 "push{l}\t%k1"
6ef67412 1930 [(set_attr "type" "push")
6541fe75 1931 (set_attr "mode" "SI")])
e075ae69 1932
b3298882
JH
1933;; For 64BIT abi we always round up to 8 bytes.
1934(define_insn "*pushhi2_rex64"
1935 [(set (match_operand:HI 0 "push_operand" "=X")
0edb82cb 1936 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
b3298882 1937 "TARGET_64BIT"
0f40f9f7 1938 "push{q}\t%q1"
b3298882 1939 [(set_attr "type" "push")
6541fe75 1940 (set_attr "mode" "DI")])
b3298882 1941
e075ae69 1942(define_insn "*movhi_1"
9b73c90a
EB
1943 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1944 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
7656aee4 1945 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
886c62d1 1946{
e075ae69 1947 switch (get_attr_type (insn))
886c62d1 1948 {
e075ae69
RH
1949 case TYPE_IMOVX:
1950 /* movzwl is faster than movw on p2 due to partial word stalls,
1951 though not as fast as an aligned movl. */
0f40f9f7 1952 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
e075ae69 1953 default:
6ef67412 1954 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 1955 return "mov{l}\t{%k1, %k0|%k0, %k1}";
e075ae69 1956 else
0f40f9f7 1957 return "mov{w}\t{%1, %0|%0, %1}";
886c62d1 1958 }
0f40f9f7 1959}
e075ae69 1960 [(set (attr "type")
3debdc1e 1961 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
68f48f39
RS
1962 (const_string "imov")
1963 (and (eq_attr "alternative" "0")
0b5107cf
JH
1964 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1965 (const_int 0))
1966 (eq (symbol_ref "TARGET_HIMODE_MATH")
1967 (const_int 0))))
369e59b1 1968 (const_string "imov")
9b73c90a 1969 (and (eq_attr "alternative" "1,2")
2247f6ed 1970 (match_operand:HI 1 "aligned_operand" ""))
e075ae69
RH
1971 (const_string "imov")
1972 (and (ne (symbol_ref "TARGET_MOVX")
1973 (const_int 0))
9b73c90a 1974 (eq_attr "alternative" "0,2"))
e075ae69
RH
1975 (const_string "imovx")
1976 ]
1977 (const_string "imov")))
6ef67412 1978 (set (attr "mode")
e075ae69 1979 (cond [(eq_attr "type" "imovx")
6ef67412 1980 (const_string "SI")
9b73c90a 1981 (and (eq_attr "alternative" "1,2")
369e59b1 1982 (match_operand:HI 1 "aligned_operand" ""))
6ef67412 1983 (const_string "SI")
9b73c90a 1984 (and (eq_attr "alternative" "0")
0b5107cf
JH
1985 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1986 (const_int 0))
1987 (eq (symbol_ref "TARGET_HIMODE_MATH")
1988 (const_int 0))))
6ef67412 1989 (const_string "SI")
e075ae69 1990 ]
9b73c90a 1991 (const_string "HI")))])
e075ae69 1992
d1f87653 1993;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
1994;; We fake an second form of instruction to force reload to load address
1995;; into register when rax is not available
1996(define_insn "*movabshi_1_rex64"
7e6dc358
JJ
1997 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1998 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1999 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 2000 "@
0f40f9f7 2001 movabs{w}\t{%1, %P0|%P0, %1}
7e6dc358 2002 mov{w}\t{%1, %a0|%a0, %1}"
0ec259ed 2003 [(set_attr "type" "imov")
7e6dc358
JJ
2004 (set_attr "modrm" "0,*")
2005 (set_attr "length_address" "8,0")
2006 (set_attr "length_immediate" "0,*")
0ec259ed
JH
2007 (set_attr "memory" "store")
2008 (set_attr "mode" "HI")])
2009
2010(define_insn "*movabshi_2_rex64"
2011 [(set (match_operand:HI 0 "register_operand" "=a,r")
2012 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 2013 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 2014 "@
0f40f9f7
ZW
2015 movabs{w}\t{%P1, %0|%0, %P1}
2016 mov{w}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
2017 [(set_attr "type" "imov")
2018 (set_attr "modrm" "0,*")
2019 (set_attr "length_address" "8,0")
2020 (set_attr "length_immediate" "0")
2021 (set_attr "memory" "load")
2022 (set_attr "mode" "HI")])
2023
e075ae69
RH
2024(define_insn "*swaphi_1"
2025 [(set (match_operand:HI 0 "register_operand" "+r")
2026 (match_operand:HI 1 "register_operand" "+r"))
2027 (set (match_dup 1)
2028 (match_dup 0))]
3debdc1e 2029 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7cc6af0c 2030 "xchg{l}\t%k1, %k0"
e075ae69 2031 [(set_attr "type" "imov")
7cc6af0c 2032 (set_attr "mode" "SI")
e075ae69 2033 (set_attr "pent_pair" "np")
21efb4d4 2034 (set_attr "athlon_decode" "vector")
4f3f76e6 2035 (set_attr "amdfam10_decode" "double")])
e075ae69 2036
21efb4d4 2037;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
e075ae69
RH
2038(define_insn "*swaphi_2"
2039 [(set (match_operand:HI 0 "register_operand" "+r")
2040 (match_operand:HI 1 "register_operand" "+r"))
2041 (set (match_dup 1)
2042 (match_dup 0))]
7cc6af0c
RH
2043 "TARGET_PARTIAL_REG_STALL"
2044 "xchg{w}\t%1, %0"
e075ae69 2045 [(set_attr "type" "imov")
7cc6af0c 2046 (set_attr "mode" "HI")
e075ae69 2047 (set_attr "pent_pair" "np")
7cc6af0c 2048 (set_attr "athlon_decode" "vector")])
886c62d1 2049
2f2a49e8 2050(define_expand "movstricthi"
e075ae69 2051 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2f2a49e8 2052 (match_operand:HI 1 "general_operand" ""))]
3debdc1e 2053 ""
2f2a49e8 2054{
3debdc1e
JH
2055 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2056 FAIL;
2f2a49e8 2057 /* Don't generate memory->memory moves, go through a register */
7656aee4 2058 if (MEM_P (operands[0]) && MEM_P (operands[1]))
e075ae69 2059 operands[1] = force_reg (HImode, operands[1]);
0f40f9f7 2060})
2f2a49e8 2061
e075ae69 2062(define_insn "*movstricthi_1"
fc524c1c 2063 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
e075ae69 2064 (match_operand:HI 1 "general_operand" "rn,m"))]
3debdc1e 2065 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 2066 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 2067 "mov{w}\t{%1, %0|%0, %1}"
6ef67412
JH
2068 [(set_attr "type" "imov")
2069 (set_attr "mode" "HI")])
2070
2071(define_insn "*movstricthi_xor"
208b0ab1 2072 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
0edb82cb 2073 (match_operand:HI 1 "const0_operand" ""))
8bc527af 2074 (clobber (reg:CC FLAGS_REG))]
18bd082d 2075 "reload_completed"
a23132e1 2076 "xor{w}\t%0, %0"
6ef67412
JH
2077 [(set_attr "type" "alu1")
2078 (set_attr "mode" "HI")
2079 (set_attr "length_immediate" "0")])
886c62d1 2080
2f2a49e8 2081(define_expand "movqi"
4cbfbb1b 2082 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2f2a49e8
MM
2083 (match_operand:QI 1 "general_operand" ""))]
2084 ""
e075ae69
RH
2085 "ix86_expand_move (QImode, operands); DONE;")
2086
7dd4b4a3 2087;; emit_push_insn when it calls move_by_pieces requires an insn to
6541fe75
JJ
2088;; "push a byte". But actually we use pushl, which has the effect
2089;; of rounding the amount pushed up to a word.
7dd4b4a3
JH
2090
2091(define_insn "*pushqi2"
6541fe75
JJ
2092 [(set (match_operand:QI 0 "push_operand" "=X")
2093 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
7dd4b4a3 2094 "!TARGET_64BIT"
6541fe75 2095 "push{l}\t%k1"
7dd4b4a3 2096 [(set_attr "type" "push")
6541fe75 2097 (set_attr "mode" "SI")])
7dd4b4a3 2098
b3298882
JH
2099;; For 64BIT abi we always round up to 8 bytes.
2100(define_insn "*pushqi2_rex64"
2101 [(set (match_operand:QI 0 "push_operand" "=X")
0edb82cb 2102 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
b3298882 2103 "TARGET_64BIT"
0f40f9f7 2104 "push{q}\t%q1"
b3298882 2105 [(set_attr "type" "push")
6541fe75 2106 (set_attr "mode" "DI")])
b3298882 2107
0b5107cf
JH
2108;; Situation is quite tricky about when to choose full sized (SImode) move
2109;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2110;; partial register dependency machines (such as AMD Athlon), where QImode
2111;; moves issue extra dependency and for partial register stalls machines
2112;; that don't use QImode patterns (and QImode move cause stall on the next
2113;; instruction).
2114;;
2115;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2116;; register stall machines with, where we use QImode instructions, since
2117;; partial register stall can be caused there. Then we use movzx.
e075ae69 2118(define_insn "*movqi_1"
0b5107cf 2119 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
0cd0c6fb 2120 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
7656aee4 2121 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
886c62d1 2122{
e075ae69 2123 switch (get_attr_type (insn))
b76c90cf 2124 {
e075ae69 2125 case TYPE_IMOVX:
7656aee4 2126 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
0f40f9f7 2127 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
e075ae69 2128 default:
6ef67412 2129 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 2130 return "mov{l}\t{%k1, %k0|%k0, %k1}";
b76c90cf 2131 else
0f40f9f7 2132 return "mov{b}\t{%1, %0|%0, %1}";
b76c90cf 2133 }
0f40f9f7 2134}
e075ae69 2135 [(set (attr "type")
0cd0c6fb
JJ
2136 (cond [(and (eq_attr "alternative" "5")
2137 (not (match_operand:QI 1 "aligned_operand" "")))
f66eb2af 2138 (const_string "imovx")
3debdc1e 2139 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
68f48f39
RS
2140 (const_string "imov")
2141 (and (eq_attr "alternative" "3")
0b5107cf
JH
2142 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2143 (const_int 0))
2144 (eq (symbol_ref "TARGET_QIMODE_MATH")
2145 (const_int 0))))
2146 (const_string "imov")
0cd0c6fb 2147 (eq_attr "alternative" "3,5")
e075ae69
RH
2148 (const_string "imovx")
2149 (and (ne (symbol_ref "TARGET_MOVX")
2150 (const_int 0))
0b5107cf 2151 (eq_attr "alternative" "2"))
e075ae69
RH
2152 (const_string "imovx")
2153 ]
2154 (const_string "imov")))
6ef67412
JH
2155 (set (attr "mode")
2156 (cond [(eq_attr "alternative" "3,4,5")
2157 (const_string "SI")
2158 (eq_attr "alternative" "6")
2159 (const_string "QI")
2160 (eq_attr "type" "imovx")
2161 (const_string "SI")
0b5107cf 2162 (and (eq_attr "type" "imov")
d49b398c 2163 (and (eq_attr "alternative" "0,1")
d326eaf0
JH
2164 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2165 (const_int 0))
3debdc1e 2166 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
d326eaf0
JH
2167 (const_int 0))
2168 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2169 (const_int 0))))))
6ef67412 2170 (const_string "SI")
0b5107cf
JH
2171 ;; Avoid partial register stalls when not using QImode arithmetic
2172 (and (eq_attr "type" "imov")
d49b398c 2173 (and (eq_attr "alternative" "0,1")
0b5107cf
JH
2174 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2175 (const_int 0))
2176 (eq (symbol_ref "TARGET_QIMODE_MATH")
2177 (const_int 0)))))
6ef67412
JH
2178 (const_string "SI")
2179 ]
2180 (const_string "QI")))])
e075ae69 2181
7cc6af0c 2182(define_insn "*swapqi_1"
e075ae69
RH
2183 [(set (match_operand:QI 0 "register_operand" "+r")
2184 (match_operand:QI 1 "register_operand" "+r"))
2185 (set (match_dup 1)
2186 (match_dup 0))]
3debdc1e 2187 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7cc6af0c 2188 "xchg{l}\t%k1, %k0"
e075ae69 2189 [(set_attr "type" "imov")
7cc6af0c 2190 (set_attr "mode" "SI")
e075ae69 2191 (set_attr "pent_pair" "np")
21efb4d4 2192 (set_attr "athlon_decode" "vector")
4f3f76e6 2193 (set_attr "amdfam10_decode" "vector")])
7cc6af0c 2194
21efb4d4 2195;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
7cc6af0c
RH
2196(define_insn "*swapqi_2"
2197 [(set (match_operand:QI 0 "register_operand" "+q")
2198 (match_operand:QI 1 "register_operand" "+q"))
2199 (set (match_dup 1)
2200 (match_dup 0))]
2201 "TARGET_PARTIAL_REG_STALL"
2202 "xchg{b}\t%1, %0"
2203 [(set_attr "type" "imov")
6ef67412 2204 (set_attr "mode" "QI")
7cc6af0c
RH
2205 (set_attr "pent_pair" "np")
2206 (set_attr "athlon_decode" "vector")])
886c62d1 2207
2f2a49e8 2208(define_expand "movstrictqi"
4cbfbb1b 2209 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2f2a49e8 2210 (match_operand:QI 1 "general_operand" ""))]
3debdc1e 2211 ""
2f2a49e8 2212{
3debdc1e
JH
2213 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2214 FAIL;
e03f5d43 2215 /* Don't generate memory->memory moves, go through a register. */
7656aee4 2216 if (MEM_P (operands[0]) && MEM_P (operands[1]))
e075ae69 2217 operands[1] = force_reg (QImode, operands[1]);
0f40f9f7 2218})
2f2a49e8 2219
e075ae69 2220(define_insn "*movstrictqi_1"
2ae0f82c 2221 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
c0f06344 2222 (match_operand:QI 1 "general_operand" "*qn,m"))]
3debdc1e 2223 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 2224 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 2225 "mov{b}\t{%1, %0|%0, %1}"
6ef67412
JH
2226 [(set_attr "type" "imov")
2227 (set_attr "mode" "QI")])
2228
2229(define_insn "*movstrictqi_xor"
5e6d6bf0 2230 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
0edb82cb 2231 (match_operand:QI 1 "const0_operand" ""))
8bc527af 2232 (clobber (reg:CC FLAGS_REG))]
18bd082d 2233 "reload_completed"
a23132e1 2234 "xor{b}\t%0, %0"
6ef67412
JH
2235 [(set_attr "type" "alu1")
2236 (set_attr "mode" "QI")
2237 (set_attr "length_immediate" "0")])
e075ae69
RH
2238
2239(define_insn "*movsi_extv_1"
d2836273 2240 [(set (match_operand:SI 0 "register_operand" "=R")
3522082b 2241 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
2242 (const_int 8)
2243 (const_int 8)))]
2244 ""
0f40f9f7 2245 "movs{bl|x}\t{%h1, %0|%0, %h1}"
6ef67412
JH
2246 [(set_attr "type" "imovx")
2247 (set_attr "mode" "SI")])
e075ae69
RH
2248
2249(define_insn "*movhi_extv_1"
d2836273 2250 [(set (match_operand:HI 0 "register_operand" "=R")
3522082b 2251 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
2252 (const_int 8)
2253 (const_int 8)))]
2254 ""
0f40f9f7 2255 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
6ef67412
JH
2256 [(set_attr "type" "imovx")
2257 (set_attr "mode" "SI")])
e075ae69
RH
2258
2259(define_insn "*movqi_extv_1"
0ec259ed 2260 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
3522082b 2261 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
e075ae69
RH
2262 (const_int 8)
2263 (const_int 8)))]
0ec259ed 2264 "!TARGET_64BIT"
886c62d1 2265{
e075ae69 2266 switch (get_attr_type (insn))
886c62d1 2267 {
e075ae69 2268 case TYPE_IMOVX:
0f40f9f7 2269 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
e075ae69 2270 default:
0f40f9f7 2271 return "mov{b}\t{%h1, %0|%0, %h1}";
886c62d1 2272 }
0f40f9f7 2273}
e075ae69
RH
2274 [(set (attr "type")
2275 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2276 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2277 (ne (symbol_ref "TARGET_MOVX")
2278 (const_int 0))))
2279 (const_string "imovx")
6ef67412
JH
2280 (const_string "imov")))
2281 (set (attr "mode")
2282 (if_then_else (eq_attr "type" "imovx")
2283 (const_string "SI")
2284 (const_string "QI")))])
e075ae69 2285
0ec259ed
JH
2286(define_insn "*movqi_extv_1_rex64"
2287 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
3522082b 2288 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
0ec259ed
JH
2289 (const_int 8)
2290 (const_int 8)))]
2291 "TARGET_64BIT"
0ec259ed
JH
2292{
2293 switch (get_attr_type (insn))
2294 {
2295 case TYPE_IMOVX:
0f40f9f7 2296 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
0ec259ed 2297 default:
0f40f9f7 2298 return "mov{b}\t{%h1, %0|%0, %h1}";
0ec259ed 2299 }
0f40f9f7 2300}
0ec259ed
JH
2301 [(set (attr "type")
2302 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2303 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2304 (ne (symbol_ref "TARGET_MOVX")
2305 (const_int 0))))
2306 (const_string "imovx")
2307 (const_string "imov")))
2308 (set (attr "mode")
2309 (if_then_else (eq_attr "type" "imovx")
2310 (const_string "SI")
2311 (const_string "QI")))])
2312
d1f87653 2313;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
2314;; We fake an second form of instruction to force reload to load address
2315;; into register when rax is not available
2316(define_insn "*movabsqi_1_rex64"
7e6dc358
JJ
2317 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2318 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2319 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 2320 "@
5e2ce672 2321 movabs{b}\t{%1, %P0|%P0, %1}
7e6dc358 2322 mov{b}\t{%1, %a0|%a0, %1}"
0ec259ed 2323 [(set_attr "type" "imov")
7e6dc358
JJ
2324 (set_attr "modrm" "0,*")
2325 (set_attr "length_address" "8,0")
2326 (set_attr "length_immediate" "0,*")
0ec259ed
JH
2327 (set_attr "memory" "store")
2328 (set_attr "mode" "QI")])
2329
2330(define_insn "*movabsqi_2_rex64"
2331 [(set (match_operand:QI 0 "register_operand" "=a,r")
2332 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 2333 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 2334 "@
5e2ce672
JH
2335 movabs{b}\t{%P1, %0|%0, %P1}
2336 mov{b}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
2337 [(set_attr "type" "imov")
2338 (set_attr "modrm" "0,*")
2339 (set_attr "length_address" "8,0")
2340 (set_attr "length_immediate" "0")
2341 (set_attr "memory" "load")
2342 (set_attr "mode" "QI")])
2343
422edd6f
JB
2344(define_insn "*movdi_extzv_1"
2345 [(set (match_operand:DI 0 "register_operand" "=R")
2346 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2347 (const_int 8)
2348 (const_int 8)))]
2349 "TARGET_64BIT"
2350 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2351 [(set_attr "type" "imovx")
a952487c 2352 (set_attr "mode" "SI")])
422edd6f 2353
e075ae69 2354(define_insn "*movsi_extzv_1"
d2836273
JH
2355 [(set (match_operand:SI 0 "register_operand" "=R")
2356 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
2357 (const_int 8)
2358 (const_int 8)))]
2359 ""
0f40f9f7 2360 "movz{bl|x}\t{%h1, %0|%0, %h1}"
6ef67412
JH
2361 [(set_attr "type" "imovx")
2362 (set_attr "mode" "SI")])
886c62d1 2363
d2836273
JH
2364(define_insn "*movqi_extzv_2"
2365 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2366 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
e075ae69
RH
2367 (const_int 8)
2368 (const_int 8)) 0))]
d2836273 2369 "!TARGET_64BIT"
f31fce3f 2370{
e075ae69 2371 switch (get_attr_type (insn))
f31fce3f 2372 {
e075ae69 2373 case TYPE_IMOVX:
0f40f9f7 2374 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
e075ae69 2375 default:
0f40f9f7 2376 return "mov{b}\t{%h1, %0|%0, %h1}";
e075ae69 2377 }
0f40f9f7 2378}
e075ae69
RH
2379 [(set (attr "type")
2380 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2381 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2382 (ne (symbol_ref "TARGET_MOVX")
2383 (const_int 0))))
2384 (const_string "imovx")
6ef67412
JH
2385 (const_string "imov")))
2386 (set (attr "mode")
2387 (if_then_else (eq_attr "type" "imovx")
2388 (const_string "SI")
2389 (const_string "QI")))])
e075ae69 2390
d2836273
JH
2391(define_insn "*movqi_extzv_2_rex64"
2392 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2393 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2394 (const_int 8)
2395 (const_int 8)) 0))]
2396 "TARGET_64BIT"
d2836273
JH
2397{
2398 switch (get_attr_type (insn))
2399 {
2400 case TYPE_IMOVX:
0f40f9f7 2401 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
d2836273 2402 default:
0f40f9f7 2403 return "mov{b}\t{%h1, %0|%0, %h1}";
d2836273 2404 }
0f40f9f7 2405}
d2836273
JH
2406 [(set (attr "type")
2407 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2408 (ne (symbol_ref "TARGET_MOVX")
2409 (const_int 0)))
2410 (const_string "imovx")
2411 (const_string "imov")))
2412 (set (attr "mode")
2413 (if_then_else (eq_attr "type" "imovx")
2414 (const_string "SI")
2415 (const_string "QI")))])
2416
7a2e09f4 2417(define_insn "movsi_insv_1"
d2836273 2418 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
e075ae69
RH
2419 (const_int 8)
2420 (const_int 8))
f47c8646 2421 (match_operand:SI 1 "general_operand" "Qmn"))]
d2836273 2422 "!TARGET_64BIT"
0f40f9f7 2423 "mov{b}\t{%b1, %h0|%h0, %b1}"
d2836273
JH
2424 [(set_attr "type" "imov")
2425 (set_attr "mode" "QI")])
2426
8c996513
JH
2427(define_insn "*movsi_insv_1_rex64"
2428 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2429 (const_int 8)
2430 (const_int 8))
2431 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2432 "TARGET_64BIT"
2433 "mov{b}\t{%b1, %h0|%h0, %b1}"
2434 [(set_attr "type" "imov")
2435 (set_attr "mode" "QI")])
2436
044b3892
L
2437(define_insn "movdi_insv_1_rex64"
2438 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
d2836273
JH
2439 (const_int 8)
2440 (const_int 8))
044b3892 2441 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
d2836273 2442 "TARGET_64BIT"
0f40f9f7 2443 "mov{b}\t{%b1, %h0|%h0, %b1}"
6ef67412
JH
2444 [(set_attr "type" "imov")
2445 (set_attr "mode" "QI")])
e075ae69
RH
2446
2447(define_insn "*movqi_insv_2"
d2836273 2448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
e075ae69
RH
2449 (const_int 8)
2450 (const_int 8))
99f296a0
KH
2451 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2452 (const_int 8)))]
e075ae69 2453 ""
0f40f9f7 2454 "mov{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
2455 [(set_attr "type" "imov")
2456 (set_attr "mode" "QI")])
f31fce3f 2457
e075ae69 2458(define_expand "movdi"
4cbfbb1b 2459 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69
RH
2460 (match_operand:DI 1 "general_operand" ""))]
2461 ""
2462 "ix86_expand_move (DImode, operands); DONE;")
f31fce3f 2463
e075ae69
RH
2464(define_insn "*pushdi"
2465 [(set (match_operand:DI 0 "push_operand" "=<")
2c5a510c 2466 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1e07edd3 2467 "!TARGET_64BIT"
e075ae69 2468 "#")
f31fce3f 2469
6c4ccfd8 2470(define_insn "*pushdi2_rex64"
0ec259ed
JH
2471 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2472 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2473 "TARGET_64BIT"
2474 "@
0f40f9f7 2475 push{q}\t%1
0ec259ed
JH
2476 #"
2477 [(set_attr "type" "push,multi")
2478 (set_attr "mode" "DI")])
2479
2480;; Convert impossible pushes of immediate to existing instructions.
f5143c46 2481;; First try to get scratch register and go through it. In case this
0ec259ed
JH
2482;; fails, push sign extended lower part first and then overwrite
2483;; upper part by 32bit move.
2484(define_peephole2
2485 [(match_scratch:DI 2 "r")
2486 (set (match_operand:DI 0 "push_operand" "")
2487 (match_operand:DI 1 "immediate_operand" ""))]
2488 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2489 && !x86_64_immediate_operand (operands[1], DImode)"
2490 [(set (match_dup 2) (match_dup 1))
2491 (set (match_dup 0) (match_dup 2))]
2492 "")
2493
2494;; We need to define this as both peepholer and splitter for case
2495;; peephole2 pass is not run.
731edaed 2496;; "&& 1" is needed to keep it from matching the previous pattern.
0ec259ed
JH
2497(define_peephole2
2498 [(set (match_operand:DI 0 "push_operand" "")
2499 (match_operand:DI 1 "immediate_operand" ""))]
2500 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
731edaed 2501 && !x86_64_immediate_operand (operands[1], DImode) && 1"
0ec259ed
JH
2502 [(set (match_dup 0) (match_dup 1))
2503 (set (match_dup 2) (match_dup 3))]
c2b814b9 2504 "split_di (&operands[1], 1, &operands[2], &operands[3]);
0ec259ed
JH
2505 operands[1] = gen_lowpart (DImode, operands[2]);
2506 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2507 GEN_INT (4)));
2508 ")
2509
2510(define_split
2511 [(set (match_operand:DI 0 "push_operand" "")
2512 (match_operand:DI 1 "immediate_operand" ""))]
99523994 2513 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
6fb5fa3c 2514 ? epilogue_completed : reload_completed)
0ec259ed
JH
2515 && !symbolic_operand (operands[1], DImode)
2516 && !x86_64_immediate_operand (operands[1], DImode)"
2517 [(set (match_dup 0) (match_dup 1))
2518 (set (match_dup 2) (match_dup 3))]
c2b814b9 2519 "split_di (&operands[1], 1, &operands[2], &operands[3]);
0ec259ed
JH
2520 operands[1] = gen_lowpart (DImode, operands[2]);
2521 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2522 GEN_INT (4)));
2523 ")
2524
2525(define_insn "*pushdi2_prologue_rex64"
2526 [(set (match_operand:DI 0 "push_operand" "=<")
2527 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
f2042df3 2528 (clobber (mem:BLK (scratch)))]
0ec259ed 2529 "TARGET_64BIT"
0f40f9f7 2530 "push{q}\t%1"
0ec259ed
JH
2531 [(set_attr "type" "push")
2532 (set_attr "mode" "DI")])
2533
2534(define_insn "*popdi1_epilogue_rex64"
2535 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
2536 (mem:DI (reg:DI SP_REG)))
2537 (set (reg:DI SP_REG)
2538 (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 2539 (clobber (mem:BLK (scratch)))]
0ec259ed 2540 "TARGET_64BIT"
0f40f9f7 2541 "pop{q}\t%0"
0ec259ed
JH
2542 [(set_attr "type" "pop")
2543 (set_attr "mode" "DI")])
2544
2545(define_insn "popdi1"
2546 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
2547 (mem:DI (reg:DI SP_REG)))
2548 (set (reg:DI SP_REG)
2549 (plus:DI (reg:DI SP_REG) (const_int 8)))]
0ec259ed 2550 "TARGET_64BIT"
0f40f9f7 2551 "pop{q}\t%0"
0ec259ed
JH
2552 [(set_attr "type" "pop")
2553 (set_attr "mode" "DI")])
2554
2555(define_insn "*movdi_xor_rex64"
2556 [(set (match_operand:DI 0 "register_operand" "=r")
0edb82cb 2557 (match_operand:DI 1 "const0_operand" ""))
8bc527af 2558 (clobber (reg:CC FLAGS_REG))]
18bd082d 2559 "TARGET_64BIT
1b0c37d7 2560 && reload_completed"
a23132e1 2561 "xor{l}\t%k0, %k0";
0ec259ed
JH
2562 [(set_attr "type" "alu1")
2563 (set_attr "mode" "SI")
2564 (set_attr "length_immediate" "0")])
2565
2566(define_insn "*movdi_or_rex64"
2567 [(set (match_operand:DI 0 "register_operand" "=r")
2568 (match_operand:DI 1 "const_int_operand" "i"))
8bc527af 2569 (clobber (reg:CC FLAGS_REG))]
18bd082d 2570 "TARGET_64BIT
1b0c37d7 2571 && reload_completed
87d9741e 2572 && operands[1] == constm1_rtx"
0ec259ed
JH
2573{
2574 operands[1] = constm1_rtx;
0f40f9f7
ZW
2575 return "or{q}\t{%1, %0|%0, %1}";
2576}
0ec259ed
JH
2577 [(set_attr "type" "alu1")
2578 (set_attr "mode" "DI")
2579 (set_attr "length_immediate" "1")])
2580
e075ae69 2581(define_insn "*movdi_2"
d30c9461 2582 [(set (match_operand:DI 0 "nonimmediate_operand"
e2520c41 2583 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
d30c9461 2584 (match_operand:DI 1 "general_operand"
e2520c41 2585 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
f75959a6 2586 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
915119a5
BS
2587 "@
2588 #
2589 #
f75959a6 2590 pxor\t%0, %0
0f40f9f7
ZW
2591 movq\t{%1, %0|%0, %1}
2592 movq\t{%1, %0|%0, %1}
95879c72
L
2593 %vpxor\t%0, %d0
2594 %vmovq\t{%1, %0|%0, %1}
2595 %vmovdqa\t{%1, %0|%0, %1}
2596 %vmovq\t{%1, %0|%0, %1}
f75959a6 2597 xorps\t%0, %0
d30c9461
RH
2598 movlps\t{%1, %0|%0, %1}
2599 movaps\t{%1, %0|%0, %1}
2600 movlps\t{%1, %0|%0, %1}"
51df7179 2601 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
95879c72
L
2602 (set (attr "prefix")
2603 (if_then_else (eq_attr "alternative" "5,6,7,8")
2604 (const_string "vex")
2605 (const_string "orig")))
f75959a6 2606 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
dc0f0eb8 2607
e075ae69
RH
2608(define_split
2609 [(set (match_operand:DI 0 "push_operand" "")
2610 (match_operand:DI 1 "general_operand" ""))]
6c12e488
JH
2611 "!TARGET_64BIT && reload_completed
2612 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2450a057 2613 [(const_int 0)]
26e5b205 2614 "ix86_split_long_move (operands); DONE;")
f31fce3f 2615
e075ae69 2616;; %%% This multiword shite has got to go.
e075ae69 2617(define_split
c76aab11 2618 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69 2619 (match_operand:DI 1 "general_operand" ""))]
6c12e488
JH
2620 "!TARGET_64BIT && reload_completed
2621 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2622 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
26e5b205
JH
2623 [(const_int 0)]
2624 "ix86_split_long_move (operands); DONE;")
0ec259ed
JH
2625
2626(define_insn "*movdi_1_rex64"
6c4ccfd8 2627 [(set (match_operand:DI 0 "nonimmediate_operand"
4afb7791 2628 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
6c4ccfd8 2629 (match_operand:DI 1 "general_operand"
4afb7791 2630 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
f75959a6 2631 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0ec259ed
JH
2632{
2633 switch (get_attr_type (insn))
2634 {
9e9fb0ce 2635 case TYPE_SSECVT:
ed69105c 2636 if (SSE_REG_P (operands[0]))
9e9fb0ce
JB
2637 return "movq2dq\t{%1, %0|%0, %1}";
2638 else
2639 return "movdq2q\t{%1, %0|%0, %1}";
ed69105c 2640
5f90a099 2641 case TYPE_SSEMOV:
95879c72
L
2642 if (TARGET_AVX)
2643 {
2644 if (get_attr_mode (insn) == MODE_TI)
2645 return "vmovdqa\t{%1, %0|%0, %1}";
2646 else
2647 return "vmovq\t{%1, %0|%0, %1}";
2648 }
2649
8f62128d 2650 if (get_attr_mode (insn) == MODE_TI)
ed69105c 2651 return "movdqa\t{%1, %0|%0, %1}";
5efb1046 2652 /* FALLTHRU */
ed69105c 2653
5ccbcd8c 2654 case TYPE_MMXMOV:
ed69105c
RH
2655 /* Moves from and into integer register is done using movd
2656 opcode with REX prefix. */
8f62128d 2657 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
ed69105c 2658 return "movd\t{%1, %0|%0, %1}";
0f40f9f7 2659 return "movq\t{%1, %0|%0, %1}";
ed69105c 2660
f75959a6 2661 case TYPE_SSELOG1:
95879c72
L
2662 return "%vpxor\t%0, %d0";
2663
87673f84 2664 case TYPE_MMX:
f75959a6 2665 return "pxor\t%0, %0";
ed69105c 2666
0ec259ed 2667 case TYPE_MULTI:
0f40f9f7 2668 return "#";
ed69105c 2669
0ec259ed 2670 case TYPE_LEA:
0f40f9f7 2671 return "lea{q}\t{%a1, %0|%0, %a1}";
ed69105c 2672
0ec259ed 2673 default:
7637e42c 2674 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
0ec259ed 2675 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 2676 return "mov{l}\t{%k1, %k0|%k0, %k1}";
0ec259ed 2677 else if (which_alternative == 2)
0f40f9f7 2678 return "movabs{q}\t{%1, %0|%0, %1}";
0ec259ed 2679 else
0f40f9f7 2680 return "mov{q}\t{%1, %0|%0, %1}";
0ec259ed 2681 }
0f40f9f7 2682}
0ec259ed 2683 [(set (attr "type")
f75959a6 2684 (cond [(eq_attr "alternative" "5")
87673f84 2685 (const_string "mmx")
ed69105c 2686 (eq_attr "alternative" "6,7,8,9,10")
3d34cd91 2687 (const_string "mmxmov")
ed69105c 2688 (eq_attr "alternative" "11")
f75959a6 2689 (const_string "sselog1")
ed69105c 2690 (eq_attr "alternative" "12,13,14,15,16")
3d34cd91 2691 (const_string "ssemov")
ed69105c 2692 (eq_attr "alternative" "17,18")
9e9fb0ce 2693 (const_string "ssecvt")
0ec259ed
JH
2694 (eq_attr "alternative" "4")
2695 (const_string "multi")
47efdea4 2696 (match_operand:DI 1 "pic_32bit_operand" "")
0ec259ed
JH
2697 (const_string "lea")
2698 ]
2699 (const_string "imov")))
a952487c
JJ
2700 (set (attr "modrm")
2701 (if_then_else
2702 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2703 (const_string "0")
2704 (const_string "*")))
2705 (set (attr "length_immediate")
2706 (if_then_else
2707 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2708 (const_string "8")
2709 (const_string "*")))
725fd454
JJ
2710 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2711 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
95879c72
L
2712 (set (attr "prefix")
2713 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2714 (const_string "maybe_vex")
2715 (const_string "orig")))
ed69105c 2716 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
0ec259ed 2717
d1f87653 2718;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
2719;; We fake an second form of instruction to force reload to load address
2720;; into register when rax is not available
2721(define_insn "*movabsdi_1_rex64"
7e6dc358
JJ
2722 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2723 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2724 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 2725 "@
0f40f9f7 2726 movabs{q}\t{%1, %P0|%P0, %1}
7e6dc358 2727 mov{q}\t{%1, %a0|%a0, %1}"
0ec259ed 2728 [(set_attr "type" "imov")
7e6dc358
JJ
2729 (set_attr "modrm" "0,*")
2730 (set_attr "length_address" "8,0")
2731 (set_attr "length_immediate" "0,*")
0ec259ed
JH
2732 (set_attr "memory" "store")
2733 (set_attr "mode" "DI")])
2734
2735(define_insn "*movabsdi_2_rex64"
2736 [(set (match_operand:DI 0 "register_operand" "=a,r")
2737 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 2738 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 2739 "@
0f40f9f7
ZW
2740 movabs{q}\t{%P1, %0|%0, %P1}
2741 mov{q}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
2742 [(set_attr "type" "imov")
2743 (set_attr "modrm" "0,*")
2744 (set_attr "length_address" "8,0")
2745 (set_attr "length_immediate" "0")
2746 (set_attr "memory" "load")
2747 (set_attr "mode" "DI")])
2748
2749;; Convert impossible stores of immediate to existing instructions.
f5143c46 2750;; First try to get scratch register and go through it. In case this
0ec259ed
JH
2751;; fails, move by 32bit parts.
2752(define_peephole2
2753 [(match_scratch:DI 2 "r")
2754 (set (match_operand:DI 0 "memory_operand" "")
2755 (match_operand:DI 1 "immediate_operand" ""))]
2756 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2757 && !x86_64_immediate_operand (operands[1], DImode)"
2758 [(set (match_dup 2) (match_dup 1))
2759 (set (match_dup 0) (match_dup 2))]
2760 "")
2761
2762;; We need to define this as both peepholer and splitter for case
2763;; peephole2 pass is not run.
731edaed 2764;; "&& 1" is needed to keep it from matching the previous pattern.
0ec259ed
JH
2765(define_peephole2
2766 [(set (match_operand:DI 0 "memory_operand" "")
2767 (match_operand:DI 1 "immediate_operand" ""))]
2768 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
731edaed 2769 && !x86_64_immediate_operand (operands[1], DImode) && 1"
0ec259ed
JH
2770 [(set (match_dup 2) (match_dup 3))
2771 (set (match_dup 4) (match_dup 5))]
c2b814b9 2772 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
0ec259ed
JH
2773
2774(define_split
2775 [(set (match_operand:DI 0 "memory_operand" "")
2776 (match_operand:DI 1 "immediate_operand" ""))]
99523994 2777 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
6fb5fa3c 2778 ? epilogue_completed : reload_completed)
0ec259ed
JH
2779 && !symbolic_operand (operands[1], DImode)
2780 && !x86_64_immediate_operand (operands[1], DImode)"
2781 [(set (match_dup 2) (match_dup 3))
2782 (set (match_dup 4) (match_dup 5))]
c2b814b9 2783 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
0ec259ed
JH
2784
2785(define_insn "*swapdi_rex64"
2786 [(set (match_operand:DI 0 "register_operand" "+r")
2787 (match_operand:DI 1 "register_operand" "+r"))
2788 (set (match_dup 1)
2789 (match_dup 0))]
2790 "TARGET_64BIT"
0f40f9f7 2791 "xchg{q}\t%1, %0"
0ec259ed 2792 [(set_attr "type" "imov")
0ec259ed 2793 (set_attr "mode" "DI")
7cc6af0c 2794 (set_attr "pent_pair" "np")
21efb4d4 2795 (set_attr "athlon_decode" "vector")
4f3f76e6 2796 (set_attr "amdfam10_decode" "double")])
0ec259ed 2797
95879c72
L
2798(define_expand "movoi"
2799 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2800 (match_operand:OI 1 "general_operand" ""))]
2801 "TARGET_AVX"
2802 "ix86_expand_move (OImode, operands); DONE;")
2803
2804(define_insn "*movoi_internal"
2805 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2806 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2807 "TARGET_AVX
2808 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2809{
2810 switch (which_alternative)
2811 {
2812 case 0:
2813 return "vxorps\t%0, %0, %0";
2814 case 1:
2815 case 2:
2816 if (misaligned_operand (operands[0], OImode)
2817 || misaligned_operand (operands[1], OImode))
2818 return "vmovdqu\t{%1, %0|%0, %1}";
2819 else
2820 return "vmovdqa\t{%1, %0|%0, %1}";
2821 default:
2822 gcc_unreachable ();
2823 }
2824}
2825 [(set_attr "type" "sselog1,ssemov,ssemov")
2826 (set_attr "prefix" "vex")
2827 (set_attr "mode" "OI")])
2828
ef719a44
RH
2829(define_expand "movti"
2830 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2831 (match_operand:TI 1 "nonimmediate_operand" ""))]
2832 "TARGET_SSE || TARGET_64BIT"
2833{
2834 if (TARGET_64BIT)
2835 ix86_expand_move (TImode, operands);
72bd078f
UB
2836 else if (push_operand (operands[0], TImode))
2837 ix86_expand_push (TImode, operands[1]);
ef719a44
RH
2838 else
2839 ix86_expand_vector_move (TImode, operands);
2840 DONE;
2841})
2842
2843(define_insn "*movti_internal"
2844 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2845 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2846 "TARGET_SSE && !TARGET_64BIT
7656aee4 2847 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
ef719a44
RH
2848{
2849 switch (which_alternative)
2850 {
2851 case 0:
2852 if (get_attr_mode (insn) == MODE_V4SF)
95879c72 2853 return "%vxorps\t%0, %d0";
ef719a44 2854 else
95879c72 2855 return "%vpxor\t%0, %d0";
ef719a44
RH
2856 case 1:
2857 case 2:
66e1ecfe
L
2858 /* TDmode values are passed as TImode on the stack. Moving them
2859 to stack may result in unaligned memory access. */
2860 if (misaligned_operand (operands[0], TImode)
2861 || misaligned_operand (operands[1], TImode))
1ffcdc02 2862 {
66e1ecfe 2863 if (get_attr_mode (insn) == MODE_V4SF)
95879c72 2864 return "%vmovups\t{%1, %0|%0, %1}";
66e1ecfe 2865 else
95879c72 2866 return "%vmovdqu\t{%1, %0|%0, %1}";
66e1ecfe 2867 }
ef719a44 2868 else
1ffcdc02 2869 {
66e1ecfe 2870 if (get_attr_mode (insn) == MODE_V4SF)
95879c72 2871 return "%vmovaps\t{%1, %0|%0, %1}";
66e1ecfe 2872 else
95879c72 2873 return "%vmovdqa\t{%1, %0|%0, %1}";
66e1ecfe 2874 }
ef719a44 2875 default:
7637e42c 2876 gcc_unreachable ();
ef719a44
RH
2877 }
2878}
4501d314 2879 [(set_attr "type" "sselog1,ssemov,ssemov")
95879c72 2880 (set_attr "prefix" "maybe_vex")
ef719a44 2881 (set (attr "mode")
4501d314 2882 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3debdc1e 2883 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
ef719a44 2884 (const_string "V4SF")
4501d314
JB
2885 (and (eq_attr "alternative" "2")
2886 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2887 (const_int 0)))
2888 (const_string "V4SF")]
2889 (const_string "TI")))])
ef719a44
RH
2890
2891(define_insn "*movti_rex64"
33af070f 2892 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
ef719a44
RH
2893 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2894 "TARGET_64BIT
7656aee4 2895 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
ef719a44
RH
2896{
2897 switch (which_alternative)
2898 {
2899 case 0:
2900 case 1:
2901 return "#";
2902 case 2:
2903 if (get_attr_mode (insn) == MODE_V4SF)
95879c72 2904 return "%vxorps\t%0, %d0";
ef719a44 2905 else
95879c72 2906 return "%vpxor\t%0, %d0";
ef719a44
RH
2907 case 3:
2908 case 4:
66e1ecfe
L
2909 /* TDmode values are passed as TImode on the stack. Moving them
2910 to stack may result in unaligned memory access. */
2911 if (misaligned_operand (operands[0], TImode)
2912 || misaligned_operand (operands[1], TImode))
1ffcdc02 2913 {
66e1ecfe 2914 if (get_attr_mode (insn) == MODE_V4SF)
95879c72 2915 return "%vmovups\t{%1, %0|%0, %1}";
66e1ecfe 2916 else
95879c72 2917 return "%vmovdqu\t{%1, %0|%0, %1}";
66e1ecfe 2918 }
ef719a44 2919 else
1ffcdc02 2920 {
66e1ecfe 2921 if (get_attr_mode (insn) == MODE_V4SF)
95879c72 2922 return "%vmovaps\t{%1, %0|%0, %1}";
66e1ecfe 2923 else
95879c72 2924 return "%vmovdqa\t{%1, %0|%0, %1}";
66e1ecfe 2925 }
ef719a44 2926 default:
7637e42c 2927 gcc_unreachable ();
ef719a44
RH
2928 }
2929}
4501d314 2930 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
95879c72 2931 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
ef719a44
RH
2932 (set (attr "mode")
2933 (cond [(eq_attr "alternative" "2,3")
2934 (if_then_else
3debdc1e 2935 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
ef719a44
RH
2936 (const_int 0))
2937 (const_string "V4SF")
2938 (const_string "TI"))
2939 (eq_attr "alternative" "4")
2940 (if_then_else
2941 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2942 (const_int 0))
3debdc1e 2943 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
ef719a44
RH
2944 (const_int 0)))
2945 (const_string "V4SF")
2946 (const_string "TI"))]
2947 (const_string "DI")))])
2948
2949(define_split
2950 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2951 (match_operand:TI 1 "general_operand" ""))]
2952 "reload_completed && !SSE_REG_P (operands[0])
2953 && !SSE_REG_P (operands[1])"
2954 [(const_int 0)]
2955 "ix86_split_long_move (operands); DONE;")
2956
ceca734e
RH
2957;; This expands to what emit_move_complex would generate if we didn't
2958;; have a movti pattern. Having this avoids problems with reload on
2959;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2960;; to have around all the time.
2961(define_expand "movcdi"
2962 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2963 (match_operand:CDI 1 "general_operand" ""))]
2964 ""
2965{
2966 if (push_operand (operands[0], CDImode))
2967 emit_move_complex_push (CDImode, operands[0], operands[1]);
2968 else
2969 emit_move_complex_parts (operands[0], operands[1]);
2970 DONE;
2971})
2972
0be5d99f 2973(define_expand "movsf"
4cbfbb1b 2974 [(set (match_operand:SF 0 "nonimmediate_operand" "")
0be5d99f
MM
2975 (match_operand:SF 1 "general_operand" ""))]
2976 ""
e075ae69
RH
2977 "ix86_expand_move (SFmode, operands); DONE;")
2978
2979(define_insn "*pushsf"
446988df 2980 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
b5c82fa1 2981 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
0ec259ed 2982 "!TARGET_64BIT"
0be5d99f 2983{
7637e42c
NS
2984 /* Anything else should be already split before reg-stack. */
2985 gcc_assert (which_alternative == 1);
2986 return "push{l}\t%1";
0f40f9f7 2987}
446988df 2988 [(set_attr "type" "multi,push,multi")
af12f8ea 2989 (set_attr "unit" "i387,*,*")
446988df 2990 (set_attr "mode" "SF,SI,SF")])
0be5d99f 2991
0ec259ed 2992(define_insn "*pushsf_rex64"
a7efdc84 2993 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
b5c82fa1 2994 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
0ec259ed 2995 "TARGET_64BIT"
0ec259ed 2996{
7637e42c
NS
2997 /* Anything else should be already split before reg-stack. */
2998 gcc_assert (which_alternative == 1);
2999 return "push{q}\t%q1";
0f40f9f7 3000}
0ec259ed 3001 [(set_attr "type" "multi,push,multi")
af12f8ea 3002 (set_attr "unit" "i387,*,*")
0ec259ed
JH
3003 (set_attr "mode" "SF,DI,SF")])
3004
d7a29404
JH
3005(define_split
3006 [(set (match_operand:SF 0 "push_operand" "")
3007 (match_operand:SF 1 "memory_operand" ""))]
3008 "reload_completed
7656aee4 3009 && MEM_P (operands[1])
2a450639 3010 && (operands[2] = find_constant_src (insn))"
d7a29404 3011 [(set (match_dup 0)
2a450639 3012 (match_dup 2))])
d7a29404
JH
3013
3014
e075ae69
RH
3015;; %%% Kill this when call knows how to work this out.
3016(define_split
3017 [(set (match_operand:SF 0 "push_operand" "")
c3c637e3
GS
3018 (match_operand:SF 1 "any_fp_register_operand" ""))]
3019 "!TARGET_64BIT"
8bc527af
SB
3020 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
3021 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
e075ae69 3022
0ec259ed
JH
3023(define_split
3024 [(set (match_operand:SF 0 "push_operand" "")
c3c637e3
GS
3025 (match_operand:SF 1 "any_fp_register_operand" ""))]
3026 "TARGET_64BIT"
8bc527af
SB
3027 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3028 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
0ec259ed 3029
e075ae69 3030(define_insn "*movsf_1"
6c4ccfd8 3031 [(set (match_operand:SF 0 "nonimmediate_operand"
4afb7791 3032 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
6c4ccfd8 3033 (match_operand:SF 1 "general_operand"
4afb7791 3034 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
f75959a6 3035 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
d7a29404 3036 && (reload_in_progress || reload_completed
3987b9db 3037 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3debdc1e 3038 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
8002331e 3039 && standard_80387_constant_p (operands[1]))
d7a29404 3040 || GET_CODE (operands[1]) != CONST_DOUBLE
6300f037 3041 || memory_operand (operands[0], SFmode))"
886c62d1 3042{
e075ae69 3043 switch (which_alternative)
886c62d1 3044 {
e075ae69 3045 case 0:
e075ae69 3046 case 1:
d869c351 3047 return output_387_reg_move (insn, operands);
886c62d1 3048
e075ae69 3049 case 2:
881b2a96 3050 return standard_80387_constant_opcode (operands[1]);
886c62d1 3051
e075ae69
RH
3052 case 3:
3053 case 4:
0f40f9f7 3054 return "mov{l}\t{%1, %0|%0, %1}";
446988df 3055 case 5:
4977bab6 3056 if (get_attr_mode (insn) == MODE_TI)
95879c72 3057 return "%vpxor\t%0, %d0";
692efa8e 3058 else
95879c72 3059 return "%vxorps\t%0, %d0";
446988df 3060 case 6:
4977bab6 3061 if (get_attr_mode (insn) == MODE_V4SF)
95879c72
L
3062 return "%vmovaps\t{%1, %0|%0, %1}";
3063 else
3064 return "%vmovss\t{%1, %d0|%d0, %1}";
3065 case 7:
3066 if (TARGET_AVX)
3067 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3068 : "vmovss\t{%1, %0|%0, %1}";
2b04e52b 3069 else
0f40f9f7 3070 return "movss\t{%1, %0|%0, %1}";
95879c72
L
3071 case 8:
3072 return "%vmovss\t{%1, %0|%0, %1}";
886c62d1 3073
95879c72 3074 case 9: case 10: case 14: case 15:
ac300a45 3075 return "movd\t{%1, %0|%0, %1}";
95879c72
L
3076 case 12: case 13:
3077 return "%vmovd\t{%1, %0|%0, %1}";
ac300a45 3078
e5a20888
JJ
3079 case 11:
3080 return "movq\t{%1, %0|%0, %1}";
3081
e075ae69 3082 default:
7637e42c 3083 gcc_unreachable ();
e075ae69 3084 }
0f40f9f7 3085}
ed69105c 3086 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
95879c72
L
3087 (set (attr "prefix")
3088 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3089 (const_string "maybe_vex")
3090 (const_string "orig")))
4977bab6
ZW
3091 (set (attr "mode")
3092 (cond [(eq_attr "alternative" "3,4,9,10")
3093 (const_string "SI")
3094 (eq_attr "alternative" "5")
3095 (if_then_else
3096 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3097 (const_int 0))
3098 (ne (symbol_ref "TARGET_SSE2")
3099 (const_int 0)))
3debdc1e 3100 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
4977bab6
ZW
3101 (const_int 0)))
3102 (const_string "TI")
3103 (const_string "V4SF"))
3104 /* For architectures resolving dependencies on
3105 whole SSE registers use APS move to break dependency
6300f037 3106 chains, otherwise use short move to avoid extra work.
4977bab6
ZW
3107
3108 Do the same for architectures resolving dependencies on
3109 the parts. While in DF mode it is better to always handle
3110 just register parts, the SF mode is different due to lack
3111 of instructions to load just part of the register. It is
3112 better to maintain the whole registers in single format
3113 to avoid problems on using packed logical operations. */
3114 (eq_attr "alternative" "6")
3115 (if_then_else
3116 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3117 (const_int 0))
41afe4ef 3118 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
4977bab6
ZW
3119 (const_int 0)))
3120 (const_string "V4SF")
3121 (const_string "SF"))
3122 (eq_attr "alternative" "11")
3123 (const_string "DI")]
3124 (const_string "SF")))])
d7a29404 3125
a4414093 3126(define_insn "*swapsf"
6c4ccfd8
RH
3127 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3128 (match_operand:SF 1 "fp_register_operand" "+f"))
0be5d99f
MM
3129 (set (match_dup 1)
3130 (match_dup 0))]
6c4ccfd8 3131 "reload_completed || TARGET_80387"
0be5d99f
MM
3132{
3133 if (STACK_TOP_P (operands[0]))
0f40f9f7 3134 return "fxch\t%1";
0be5d99f 3135 else
0f40f9f7
ZW
3136 return "fxch\t%0";
3137}
6ef67412
JH
3138 [(set_attr "type" "fxch")
3139 (set_attr "mode" "SF")])
0be5d99f 3140
e075ae69 3141(define_expand "movdf"
4cbfbb1b 3142 [(set (match_operand:DF 0 "nonimmediate_operand" "")
e075ae69
RH
3143 (match_operand:DF 1 "general_operand" ""))]
3144 ""
3145 "ix86_expand_move (DFmode, operands); DONE;")
55953cea 3146
8fcaaa80 3147;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
d1f87653 3148;; Size of pushdf using integer instructions is 2+2*memory operand size
8fcaaa80
JH
3149;; On the average, pushdf using integers can be still shorter. Allow this
3150;; pattern for optimize_size too.
3151
0b5107cf 3152(define_insn "*pushdf_nointeger"
446988df 3153 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
e2520c41 3154 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
0ec259ed 3155 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
0b5107cf 3156{
839a4992 3157 /* This insn should be already split before reg-stack. */
7637e42c 3158 gcc_unreachable ();
0f40f9f7 3159}
6ef67412 3160 [(set_attr "type" "multi")
af12f8ea 3161 (set_attr "unit" "i387,*,*,*")
446988df 3162 (set_attr "mode" "DF,SI,SI,DF")])
0b5107cf
JH
3163
3164(define_insn "*pushdf_integer"
446988df 3165 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
e2520c41 3166 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
0ec259ed 3167 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
f31fce3f 3168{
839a4992 3169 /* This insn should be already split before reg-stack. */
7637e42c 3170 gcc_unreachable ();
0f40f9f7 3171}
6ef67412 3172 [(set_attr "type" "multi")
af12f8ea 3173 (set_attr "unit" "i387,*,*")
446988df 3174 (set_attr "mode" "DF,SI,DF")])
f31fce3f 3175
e075ae69 3176;; %%% Kill this when call knows how to work this out.
f72b27a5
JH
3177(define_split
3178 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3 3179 (match_operand:DF 1 "any_fp_register_operand" ""))]
90b48492
KT
3180 "reload_completed"
3181 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3182 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
0ec259ed
JH
3183 "")
3184
e075ae69
RH
3185(define_split
3186 [(set (match_operand:DF 0 "push_operand" "")
0be5d99f 3187 (match_operand:DF 1 "general_operand" ""))]
e075ae69 3188 "reload_completed"
2450a057 3189 [(const_int 0)]
26e5b205 3190 "ix86_split_long_move (operands); DONE;")
0be5d99f 3191
8fcaaa80
JH
3192;; Moving is usually shorter when only FP registers are used. This separate
3193;; movdf pattern avoids the use of integer registers for FP operations
3194;; when optimizing for size.
3195
3196(define_insn "*movdf_nointeger"
6c4ccfd8 3197 [(set (match_operand:DF 0 "nonimmediate_operand"
e2520c41 3198 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
6c4ccfd8 3199 (match_operand:DF 1 "general_operand"
20a415f8 3200 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
7656aee4 3201 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3debdc1e
JH
3202 && ((optimize_function_for_size_p (cfun)
3203 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
d7a29404 3204 && (reload_in_progress || reload_completed
3987b9db 3205 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3debdc1e
JH
3206 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3207 && optimize_function_for_size_p (cfun)
20a415f8 3208 && !memory_operand (operands[0], DFmode)
8002331e 3209 && standard_80387_constant_p (operands[1]))
d7a29404 3210 || GET_CODE (operands[1]) != CONST_DOUBLE
3debdc1e 3211 || ((optimize_function_for_size_p (cfun)
20a415f8
JH
3212 || !TARGET_MEMORY_MISMATCH_STALL
3213 || reload_in_progress || reload_completed)
3214 && memory_operand (operands[0], DFmode)))"
8fcaaa80
JH
3215{
3216 switch (which_alternative)
3217 {
3218 case 0:
8fcaaa80 3219 case 1:
d869c351 3220 return output_387_reg_move (insn, operands);
8fcaaa80
JH
3221
3222 case 2:
881b2a96 3223 return standard_80387_constant_opcode (operands[1]);
8fcaaa80
JH
3224
3225 case 3:
3226 case 4:
0f40f9f7 3227 return "#";
446988df 3228 case 5:
4977bab6
ZW
3229 switch (get_attr_mode (insn))
3230 {
3231 case MODE_V4SF:
95879c72 3232 return "%vxorps\t%0, %d0";
4977bab6 3233 case MODE_V2DF:
95879c72 3234 return "%vxorpd\t%0, %d0";
4977bab6 3235 case MODE_TI:
95879c72 3236 return "%vpxor\t%0, %d0";
4977bab6 3237 default:
7637e42c 3238 gcc_unreachable ();
4977bab6 3239 }
446988df 3240 case 6:
6c4ccfd8
RH
3241 case 7:
3242 case 8:
4977bab6
ZW
3243 switch (get_attr_mode (insn))
3244 {
3245 case MODE_V4SF:
95879c72 3246 return "%vmovaps\t{%1, %0|%0, %1}";
4977bab6 3247 case MODE_V2DF:
95879c72 3248 return "%vmovapd\t{%1, %0|%0, %1}";
6c4ccfd8 3249 case MODE_TI:
95879c72 3250 return "%vmovdqa\t{%1, %0|%0, %1}";
6c4ccfd8 3251 case MODE_DI:
95879c72 3252 return "%vmovq\t{%1, %0|%0, %1}";
4977bab6 3253 case MODE_DF:
95879c72
L
3254 if (TARGET_AVX)
3255 {
3256 if (REG_P (operands[0]) && REG_P (operands[1]))
3257 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3258 else
3259 return "vmovsd\t{%1, %0|%0, %1}";
3260 }
3261 else
3262 return "movsd\t{%1, %0|%0, %1}";
6c4ccfd8 3263 case MODE_V1DF:
95879c72
L
3264 if (TARGET_AVX)
3265 {
3266 if (REG_P (operands[0]))
3267 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3268 else
3269 return "vmovlpd\t{%1, %0|%0, %1}";
3270 }
3271 else
3272 return "movlpd\t{%1, %0|%0, %1}";
d30c9461 3273 case MODE_V2SF:
95879c72
L
3274 if (TARGET_AVX)
3275 {
3276 if (REG_P (operands[0]))
3277 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3278 else
3279 return "vmovlps\t{%1, %0|%0, %1}";
3280 }
3281 else
3282 return "movlps\t{%1, %0|%0, %1}";
4977bab6 3283 default:
7637e42c 3284 gcc_unreachable ();
4977bab6 3285 }
8fcaaa80
JH
3286
3287 default:
7637e42c 3288 gcc_unreachable ();
8fcaaa80 3289 }
0f40f9f7 3290}
4501d314 3291 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
95879c72
L
3292 (set (attr "prefix")
3293 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3294 (const_string "orig")
3295 (const_string "maybe_vex")))
725fd454
JJ
3296 (set (attr "prefix_data16")
3297 (if_then_else (eq_attr "mode" "V1DF")
3298 (const_string "1")
3299 (const_string "*")))
4977bab6 3300 (set (attr "mode")
d30c9461
RH
3301 (cond [(eq_attr "alternative" "0,1,2")
3302 (const_string "DF")
3303 (eq_attr "alternative" "3,4")
4977bab6 3304 (const_string "SI")
6c4ccfd8
RH
3305
3306 /* For SSE1, we have many fewer alternatives. */
3307 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3308 (cond [(eq_attr "alternative" "5,6")
d30c9461 3309 (const_string "V4SF")
6c4ccfd8 3310 ]
d30c9461 3311 (const_string "V2SF"))
6c4ccfd8 3312
4977bab6
ZW
3313 /* xorps is one byte shorter. */
3314 (eq_attr "alternative" "5")
3debdc1e 3315 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
4977bab6
ZW
3316 (const_int 0))
3317 (const_string "V4SF")
3318 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3319 (const_int 0))
6c4ccfd8
RH
3320 (const_string "TI")
3321 ]
4977bab6 3322 (const_string "V2DF"))
6c4ccfd8 3323
4977bab6
ZW
3324 /* For architectures resolving dependencies on
3325 whole SSE registers use APD move to break dependency
3326 chains, otherwise use short move to avoid extra work.
3327
3328 movaps encodes one byte shorter. */
3329 (eq_attr "alternative" "6")
3330 (cond
3debdc1e 3331 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
6c4ccfd8
RH
3332 (const_int 0))
3333 (const_string "V4SF")
3334 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3335 (const_int 0))
3336 (const_string "V2DF")
3337 ]
4977bab6 3338 (const_string "DF"))
d1f87653 3339 /* For architectures resolving dependencies on register
4977bab6
ZW
3340 parts we may avoid extra work to zero out upper part
3341 of register. */
3342 (eq_attr "alternative" "7")
3343 (if_then_else
41afe4ef 3344 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
4977bab6 3345 (const_int 0))
6c4ccfd8
RH
3346 (const_string "V1DF")
3347 (const_string "DF"))
3348 ]
3349 (const_string "DF")))])
8fcaaa80 3350
ed69105c
RH
3351(define_insn "*movdf_integer_rex64"
3352 [(set (match_operand:DF 0 "nonimmediate_operand"
e2520c41 3353 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
ed69105c 3354 (match_operand:DF 1 "general_operand"
e2520c41 3355 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
ed69105c
RH
3356 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3357 && (reload_in_progress || reload_completed
3358 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3debdc1e
JH
3359 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3360 && optimize_function_for_size_p (cfun)
ed69105c
RH
3361 && standard_80387_constant_p (operands[1]))
3362 || GET_CODE (operands[1]) != CONST_DOUBLE
3363 || memory_operand (operands[0], DFmode))"
3364{
3365 switch (which_alternative)
3366 {
3367 case 0:
ed69105c 3368 case 1:
d869c351 3369 return output_387_reg_move (insn, operands);
ed69105c
RH
3370
3371 case 2:
3372 return standard_80387_constant_opcode (operands[1]);
3373
3374 case 3:
3375 case 4:
3376 return "#";
3377
3378 case 5:
3379 switch (get_attr_mode (insn))
3380 {
3381 case MODE_V4SF:
95879c72 3382 return "%vxorps\t%0, %d0";
ed69105c 3383 case MODE_V2DF:
95879c72 3384 return "%vxorpd\t%0, %d0";
ed69105c 3385 case MODE_TI:
95879c72 3386 return "%vpxor\t%0, %d0";
ed69105c
RH
3387 default:
3388 gcc_unreachable ();
3389 }
3390 case 6:
3391 case 7:
3392 case 8:
3393 switch (get_attr_mode (insn))
3394 {
3395 case MODE_V4SF:
95879c72 3396 return "%vmovaps\t{%1, %0|%0, %1}";
ed69105c 3397 case MODE_V2DF:
95879c72 3398 return "%vmovapd\t{%1, %0|%0, %1}";
ed69105c 3399 case MODE_TI:
95879c72 3400 return "%vmovdqa\t{%1, %0|%0, %1}";
ed69105c 3401 case MODE_DI:
95879c72 3402 return "%vmovq\t{%1, %0|%0, %1}";
ed69105c 3403 case MODE_DF:
95879c72
L
3404 if (TARGET_AVX)
3405 {
3406 if (REG_P (operands[0]) && REG_P (operands[1]))
3407 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3408 else
3409 return "vmovsd\t{%1, %0|%0, %1}";
3410 }
3411 else
3412 return "movsd\t{%1, %0|%0, %1}";
ed69105c 3413 case MODE_V1DF:
95879c72 3414 return "%vmovlpd\t{%1, %d0|%d0, %1}";
ed69105c 3415 case MODE_V2SF:
95879c72 3416 return "%vmovlps\t{%1, %d0|%d0, %1}";
ed69105c
RH
3417 default:
3418 gcc_unreachable ();
3419 }
3420
3421 case 9:
3422 case 10:
95879c72 3423 return "%vmovd\t{%1, %0|%0, %1}";
ed69105c
RH
3424
3425 default:
3426 gcc_unreachable();
3427 }
3428}
3429 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
95879c72
L
3430 (set (attr "prefix")
3431 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3432 (const_string "orig")
3433 (const_string "maybe_vex")))
725fd454
JJ
3434 (set (attr "prefix_data16")
3435 (if_then_else (eq_attr "mode" "V1DF")
3436 (const_string "1")
3437 (const_string "*")))
ed69105c
RH
3438 (set (attr "mode")
3439 (cond [(eq_attr "alternative" "0,1,2")
3440 (const_string "DF")
3441 (eq_attr "alternative" "3,4,9,10")
3442 (const_string "DI")
3443
3444 /* For SSE1, we have many fewer alternatives. */
3445 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3446 (cond [(eq_attr "alternative" "5,6")
3447 (const_string "V4SF")
3448 ]
3449 (const_string "V2SF"))
3450
3451 /* xorps is one byte shorter. */
3452 (eq_attr "alternative" "5")
3debdc1e 3453 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
ed69105c
RH
3454 (const_int 0))
3455 (const_string "V4SF")
3456 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3457 (const_int 0))
3458 (const_string "TI")
3459 ]
3460 (const_string "V2DF"))
3461
3462 /* For architectures resolving dependencies on
3463 whole SSE registers use APD move to break dependency
3464 chains, otherwise use short move to avoid extra work.
3465
3466 movaps encodes one byte shorter. */
3467 (eq_attr "alternative" "6")
3468 (cond
3debdc1e 3469 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
ed69105c
RH
3470 (const_int 0))
3471 (const_string "V4SF")
3472 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3473 (const_int 0))
3474 (const_string "V2DF")
3475 ]
3476 (const_string "DF"))
3477 /* For architectures resolving dependencies on register
3478 parts we may avoid extra work to zero out upper part
3479 of register. */
3480 (eq_attr "alternative" "7")
3481 (if_then_else
3482 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3483 (const_int 0))
3484 (const_string "V1DF")
3485 (const_string "DF"))
3486 ]
3487 (const_string "DF")))])
3488
8fcaaa80 3489(define_insn "*movdf_integer"
6c4ccfd8 3490 [(set (match_operand:DF 0 "nonimmediate_operand"
e2520c41 3491 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
6c4ccfd8 3492 (match_operand:DF 1 "general_operand"
e2520c41 3493 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
7656aee4 3494 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3debdc1e
JH
3495 && optimize_function_for_speed_p (cfun)
3496 && TARGET_INTEGER_DFMODE_MOVES
d7a29404 3497 && (reload_in_progress || reload_completed
3987b9db 3498 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3debdc1e
JH
3499 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3500 && optimize_function_for_size_p (cfun)
8002331e 3501 && standard_80387_constant_p (operands[1]))
d7a29404 3502 || GET_CODE (operands[1]) != CONST_DOUBLE
6300f037 3503 || memory_operand (operands[0], DFmode))"
886c62d1 3504{
e075ae69 3505 switch (which_alternative)
886c62d1 3506 {
e075ae69 3507 case 0:
e075ae69 3508 case 1:
d869c351 3509 return output_387_reg_move (insn, operands);
886c62d1 3510
e075ae69 3511 case 2:
881b2a96 3512 return standard_80387_constant_opcode (operands[1]);
886c62d1 3513
e075ae69
RH
3514 case 3:
3515 case 4:
0f40f9f7 3516 return "#";
886c62d1 3517
446988df 3518 case 5:
4977bab6
ZW
3519 switch (get_attr_mode (insn))
3520 {
3521 case MODE_V4SF:
3522 return "xorps\t%0, %0";
3523 case MODE_V2DF:
3524 return "xorpd\t%0, %0";
3525 case MODE_TI:
3526 return "pxor\t%0, %0";
3527 default:
7637e42c 3528 gcc_unreachable ();
4977bab6 3529 }
446988df 3530 case 6:
6c4ccfd8
RH
3531 case 7:
3532 case 8:
4977bab6
ZW
3533 switch (get_attr_mode (insn))
3534 {
3535 case MODE_V4SF:
3536 return "movaps\t{%1, %0|%0, %1}";
3537 case MODE_V2DF:
3538 return "movapd\t{%1, %0|%0, %1}";
6c4ccfd8
RH
3539 case MODE_TI:
3540 return "movdqa\t{%1, %0|%0, %1}";
3541 case MODE_DI:
3542 return "movq\t{%1, %0|%0, %1}";
4977bab6
ZW
3543 case MODE_DF:
3544 return "movsd\t{%1, %0|%0, %1}";
6c4ccfd8
RH
3545 case MODE_V1DF:
3546 return "movlpd\t{%1, %0|%0, %1}";
d30c9461
RH
3547 case MODE_V2SF:
3548 return "movlps\t{%1, %0|%0, %1}";
4977bab6 3549 default:
7637e42c 3550 gcc_unreachable ();
4977bab6 3551 }
446988df 3552
e075ae69 3553 default:
7637e42c 3554 gcc_unreachable();
e075ae69 3555 }
0f40f9f7 3556}
4501d314 3557 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
725fd454
JJ
3558 (set (attr "prefix_data16")
3559 (if_then_else (eq_attr "mode" "V1DF")
3560 (const_string "1")
3561 (const_string "*")))
4977bab6 3562 (set (attr "mode")
d30c9461
RH
3563 (cond [(eq_attr "alternative" "0,1,2")
3564 (const_string "DF")
3565 (eq_attr "alternative" "3,4")
4977bab6 3566 (const_string "SI")
6c4ccfd8
RH
3567
3568 /* For SSE1, we have many fewer alternatives. */
3569 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3570 (cond [(eq_attr "alternative" "5,6")
d30c9461 3571 (const_string "V4SF")
6c4ccfd8 3572 ]
d30c9461 3573 (const_string "V2SF"))
6c4ccfd8 3574
4977bab6
ZW
3575 /* xorps is one byte shorter. */
3576 (eq_attr "alternative" "5")
3debdc1e 3577 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
4977bab6
ZW
3578 (const_int 0))
3579 (const_string "V4SF")
3580 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3581 (const_int 0))
6c4ccfd8
RH
3582 (const_string "TI")
3583 ]
4977bab6 3584 (const_string "V2DF"))
6c4ccfd8 3585
4977bab6
ZW
3586 /* For architectures resolving dependencies on
3587 whole SSE registers use APD move to break dependency
6c4ccfd8 3588 chains, otherwise use short move to avoid extra work.
4977bab6
ZW
3589
3590 movaps encodes one byte shorter. */
3591 (eq_attr "alternative" "6")
3592 (cond
3debdc1e 3593 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
6c4ccfd8
RH
3594 (const_int 0))
3595 (const_string "V4SF")
3596 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3597 (const_int 0))
3598 (const_string "V2DF")
3599 ]
4977bab6 3600 (const_string "DF"))
d1f87653 3601 /* For architectures resolving dependencies on register
4977bab6
ZW
3602 parts we may avoid extra work to zero out upper part
3603 of register. */
3604 (eq_attr "alternative" "7")
3605 (if_then_else
41afe4ef 3606 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
4977bab6 3607 (const_int 0))
6c4ccfd8
RH
3608 (const_string "V1DF")
3609 (const_string "DF"))
3610 ]
3611 (const_string "DF")))])
2ae0f82c 3612
e075ae69
RH
3613(define_split
3614 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3615 (match_operand:DF 1 "general_operand" ""))]
3616 "reload_completed
7656aee4 3617 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
6300f037 3618 && ! (ANY_FP_REG_P (operands[0]) ||
e075ae69 3619 (GET_CODE (operands[0]) == SUBREG
446988df 3620 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
6300f037 3621 && ! (ANY_FP_REG_P (operands[1]) ||
e075ae69 3622 (GET_CODE (operands[1]) == SUBREG
446988df 3623 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
26e5b205
JH
3624 [(const_int 0)]
3625 "ix86_split_long_move (operands); DONE;")
886c62d1 3626
a4414093 3627(define_insn "*swapdf"
6c4ccfd8
RH
3628 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3629 (match_operand:DF 1 "fp_register_operand" "+f"))
0be5d99f
MM
3630 (set (match_dup 1)
3631 (match_dup 0))]
6c4ccfd8 3632 "reload_completed || TARGET_80387"
0be5d99f
MM
3633{
3634 if (STACK_TOP_P (operands[0]))
0f40f9f7 3635 return "fxch\t%1";
0be5d99f 3636 else
0f40f9f7
ZW
3637 return "fxch\t%0";
3638}
6ef67412
JH
3639 [(set_attr "type" "fxch")
3640 (set_attr "mode" "DF")])
e075ae69
RH
3641
3642(define_expand "movxf"
4cbfbb1b 3643 [(set (match_operand:XF 0 "nonimmediate_operand" "")
e075ae69 3644 (match_operand:XF 1 "general_operand" ""))]
2b589241 3645 ""
f8a1ebc6 3646 "ix86_expand_move (XFmode, operands); DONE;")
2b589241 3647
8fcaaa80 3648;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
d1f87653 3649;; Size of pushdf using integer instructions is 3+3*memory operand size
8fcaaa80
JH
3650;; Pushing using integer instructions is longer except for constants
3651;; and direct memory references.
3652;; (assuming that any given constant is pushed only once, but this ought to be
3653;; handled elsewhere).
3654
3655(define_insn "*pushxf_nointeger"
1e07edd3 3656 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2c5a510c 3657 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3debdc1e 3658 "optimize_function_for_size_p (cfun)"
2b589241 3659{
839a4992 3660 /* This insn should be already split before reg-stack. */
7637e42c 3661 gcc_unreachable ();
0f40f9f7 3662}
2b589241 3663 [(set_attr "type" "multi")
af12f8ea 3664 (set_attr "unit" "i387,*,*")
2b589241
JH
3665 (set_attr "mode" "XF,SI,SI")])
3666
8fcaaa80 3667(define_insn "*pushxf_integer"
2450a057 3668 [(set (match_operand:XF 0 "push_operand" "=<,<")
b5c82fa1 3669 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3debdc1e 3670 "optimize_function_for_speed_p (cfun)"
2b589241 3671{
839a4992 3672 /* This insn should be already split before reg-stack. */
7637e42c 3673 gcc_unreachable ();
0f40f9f7 3674}
2b589241 3675 [(set_attr "type" "multi")
af12f8ea 3676 (set_attr "unit" "i387,*")
2b589241
JH
3677 (set_attr "mode" "XF,SI")])
3678
2450a057 3679(define_split
2b589241
JH
3680 [(set (match_operand 0 "push_operand" "")
3681 (match_operand 1 "general_operand" ""))]
2450a057 3682 "reload_completed
2b589241 3683 && (GET_MODE (operands[0]) == XFmode
2b589241 3684 || GET_MODE (operands[0]) == DFmode)
c3c637e3 3685 && !ANY_FP_REG_P (operands[1])"
2450a057 3686 [(const_int 0)]
26e5b205 3687 "ix86_split_long_move (operands); DONE;")
2450a057 3688
f72b27a5
JH
3689(define_split
3690 [(set (match_operand:XF 0 "push_operand" "")
c3c637e3 3691 (match_operand:XF 1 "any_fp_register_operand" ""))]
90b48492
KT
3692 ""
3693 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3694 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
f8a1ebc6 3695 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
0ec259ed 3696
8fcaaa80
JH
3697;; Do not use integer registers when optimizing for size
3698(define_insn "*movxf_nointeger"
3699 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3700 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3debdc1e 3701 "optimize_function_for_size_p (cfun)
7656aee4 3702 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
d7a29404 3703 && (reload_in_progress || reload_completed
3debdc1e 3704 || standard_80387_constant_p (operands[1])
d7a29404 3705 || GET_CODE (operands[1]) != CONST_DOUBLE
6300f037 3706 || memory_operand (operands[0], XFmode))"
0be5d99f 3707{
8fcaaa80
JH
3708 switch (which_alternative)
3709 {
3710 case 0:
8fcaaa80 3711 case 1:
d869c351 3712 return output_387_reg_move (insn, operands);
8fcaaa80
JH
3713
3714 case 2:
881b2a96 3715 return standard_80387_constant_opcode (operands[1]);
8fcaaa80
JH
3716
3717 case 3: case 4:
0f40f9f7 3718 return "#";
7637e42c
NS
3719 default:
3720 gcc_unreachable ();
8fcaaa80 3721 }
0f40f9f7 3722}
6ef67412
JH
3723 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3724 (set_attr "mode" "XF,XF,XF,SI,SI")])
8fcaaa80
JH
3725
3726(define_insn "*movxf_integer"
b5c82fa1
PB
3727 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3728 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3debdc1e 3729 "optimize_function_for_speed_p (cfun)
7656aee4 3730 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
d7a29404
JH
3731 && (reload_in_progress || reload_completed
3732 || GET_CODE (operands[1]) != CONST_DOUBLE
6300f037 3733 || memory_operand (operands[0], XFmode))"
4fb21e90 3734{
e075ae69 3735 switch (which_alternative)
4fb21e90 3736 {
e075ae69 3737 case 0:
e075ae69 3738 case 1:
d869c351 3739 return output_387_reg_move (insn, operands);
2f17722a 3740
e075ae69 3741 case 2:
881b2a96 3742 return standard_80387_constant_opcode (operands[1]);
467403ca
RH
3743
3744 case 3: case 4:
0f40f9f7 3745 return "#";
7637e42c
NS
3746
3747 default:
3748 gcc_unreachable ();
4fb21e90 3749 }
0f40f9f7 3750}
6ef67412
JH
3751 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3752 (set_attr "mode" "XF,XF,XF,SI,SI")])
4fb21e90 3753
a91d32a4
UB
3754(define_expand "movtf"
3755 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3756 (match_operand:TF 1 "nonimmediate_operand" ""))]
5bb77598 3757 "TARGET_SSE2"
a91d32a4
UB
3758{
3759 ix86_expand_move (TFmode, operands);
3760 DONE;
3761})
3762
3763(define_insn "*movtf_internal"
3764 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3765 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
5bb77598 3766 "TARGET_SSE2
a91d32a4
UB
3767 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3768{
3769 switch (which_alternative)
3770 {
3771 case 0:
3772 case 1:
3773 if (get_attr_mode (insn) == MODE_V4SF)
95879c72 3774 return "%vmovaps\t{%1, %0|%0, %1}";
a91d32a4 3775 else
95879c72 3776 return "%vmovdqa\t{%1, %0|%0, %1}";
a91d32a4
UB
3777 case 2:
3778 if (get_attr_mode (insn) == MODE_V4SF)
95879c72 3779 return "%vxorps\t%0, %d0";
a91d32a4 3780 else
95879c72 3781 return "%vpxor\t%0, %d0";
a91d32a4
UB
3782 case 3:
3783 case 4:
3784 return "#";
3785 default:
3786 gcc_unreachable ();
3787 }
3788}
3789 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
95879c72 3790 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
a91d32a4
UB
3791 (set (attr "mode")
3792 (cond [(eq_attr "alternative" "0,2")
3793 (if_then_else
3debdc1e 3794 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
a91d32a4
UB
3795 (const_int 0))
3796 (const_string "V4SF")
3797 (const_string "TI"))
3798 (eq_attr "alternative" "1")
3799 (if_then_else
3800 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3801 (const_int 0))
3debdc1e 3802 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
a91d32a4
UB
3803 (const_int 0)))
3804 (const_string "V4SF")
3805 (const_string "TI"))]
3806 (const_string "DI")))])
3807
dcde22ac
UB
3808(define_insn "*pushtf_sse"
3809 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3810 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3811 "TARGET_SSE2"
3812{
3813 /* This insn should be already split before reg-stack. */
3814 gcc_unreachable ();
3815}
3816 [(set_attr "type" "multi")
3817 (set_attr "unit" "sse,*,*")
3818 (set_attr "mode" "TF,SI,SI")])
3819
3820(define_split
3821 [(set (match_operand:TF 0 "push_operand" "")
3822 (match_operand:TF 1 "general_operand" ""))]
3823 "TARGET_SSE2 && reload_completed
3824 && !SSE_REG_P (operands[1])"
3825 [(const_int 0)]
3826 "ix86_split_long_move (operands); DONE;")
3827
3828(define_split
3829 [(set (match_operand:TF 0 "push_operand" "")
3830 (match_operand:TF 1 "any_fp_register_operand" ""))]
3831 "TARGET_SSE2"
3832 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3833 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3834 "")
3835
467403ca 3836(define_split
2b589241
JH
3837 [(set (match_operand 0 "nonimmediate_operand" "")
3838 (match_operand 1 "general_operand" ""))]
2450a057 3839 "reload_completed
7656aee4 3840 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
f8a1ebc6 3841 && GET_MODE (operands[0]) == XFmode
6300f037 3842 && ! (ANY_FP_REG_P (operands[0]) ||
8fcaaa80 3843 (GET_CODE (operands[0]) == SUBREG
446988df 3844 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
6300f037 3845 && ! (ANY_FP_REG_P (operands[1]) ||
8fcaaa80 3846 (GET_CODE (operands[1]) == SUBREG
446988df 3847 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
26e5b205
JH
3848 [(const_int 0)]
3849 "ix86_split_long_move (operands); DONE;")
467403ca 3850
d7a29404 3851(define_split
2b589241
JH
3852 [(set (match_operand 0 "register_operand" "")
3853 (match_operand 1 "memory_operand" ""))]
d7a29404 3854 "reload_completed
7656aee4 3855 && MEM_P (operands[1])
edc5bbcd
UB
3856 && (GET_MODE (operands[0]) == TFmode
3857 || GET_MODE (operands[0]) == XFmode
7656aee4
UB
3858 || GET_MODE (operands[0]) == SFmode
3859 || GET_MODE (operands[0]) == DFmode)
2a450639
RS
3860 && (operands[2] = find_constant_src (insn))"
3861 [(set (match_dup 0) (match_dup 2))]
b87cfcfb 3862{
2a450639 3863 rtx c = operands[2];
b87cfcfb
RH
3864 rtx r = operands[0];
3865
3866 if (GET_CODE (r) == SUBREG)
3867 r = SUBREG_REG (r);
3868
3869 if (SSE_REG_P (r))
3870 {
3871 if (!standard_sse_constant_p (c))
3872 FAIL;
3873 }
3874 else if (FP_REG_P (r))
3875 {
3876 if (!standard_80387_constant_p (c))
3877 FAIL;
3878 }
3879 else if (MMX_REG_P (r))
3880 FAIL;
b87cfcfb 3881})
d7a29404 3882
ce7d4645
UB
3883(define_split
3884 [(set (match_operand 0 "register_operand" "")
3885 (float_extend (match_operand 1 "memory_operand" "")))]
3886 "reload_completed
7656aee4 3887 && MEM_P (operands[1])
a91d32a4
UB
3888 && (GET_MODE (operands[0]) == TFmode
3889 || GET_MODE (operands[0]) == XFmode
7656aee4
UB
3890 || GET_MODE (operands[0]) == SFmode
3891 || GET_MODE (operands[0]) == DFmode)
2a450639
RS
3892 && (operands[2] = find_constant_src (insn))"
3893 [(set (match_dup 0) (match_dup 2))]
ce7d4645 3894{
2a450639 3895 rtx c = operands[2];
ce7d4645
UB
3896 rtx r = operands[0];
3897
3898 if (GET_CODE (r) == SUBREG)
3899 r = SUBREG_REG (r);
3900
3901 if (SSE_REG_P (r))
3902 {
3903 if (!standard_sse_constant_p (c))
3904 FAIL;
3905 }
3906 else if (FP_REG_P (r))
3907 {
3908 if (!standard_80387_constant_p (c))
3909 FAIL;
3910 }
3911 else if (MMX_REG_P (r))
3912 FAIL;
ce7d4645
UB
3913})
3914
e075ae69
RH
3915(define_insn "swapxf"
3916 [(set (match_operand:XF 0 "register_operand" "+f")
3917 (match_operand:XF 1 "register_operand" "+f"))
0be5d99f
MM
3918 (set (match_dup 1)
3919 (match_dup 0))]
6c4ccfd8 3920 "TARGET_80387"
0be5d99f
MM
3921{
3922 if (STACK_TOP_P (operands[0]))
0f40f9f7 3923 return "fxch\t%1";
0be5d99f 3924 else
0f40f9f7
ZW
3925 return "fxch\t%0";
3926}
0b5107cf 3927 [(set_attr "type" "fxch")
6ef67412 3928 (set_attr "mode" "XF")])
ef719a44 3929
2e1f15bd
UB
3930;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3931(define_split
3932 [(set (match_operand:X87MODEF 0 "register_operand" "")
3933 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3934 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3935 && (standard_80387_constant_p (operands[1]) == 8
3936 || standard_80387_constant_p (operands[1]) == 9)"
3937 [(set (match_dup 0)(match_dup 1))
3938 (set (match_dup 0)
3939 (neg:X87MODEF (match_dup 0)))]
3940{
3941 REAL_VALUE_TYPE r;
3942
3943 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3944 if (real_isnegzero (&r))
3945 operands[1] = CONST0_RTX (<MODE>mode);
3946 else
3947 operands[1] = CONST1_RTX (<MODE>mode);
3948})
3949
ef719a44
RH
3950(define_split
3951 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3952 (match_operand:TF 1 "general_operand" ""))]
a91d32a4
UB
3953 "reload_completed
3954 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
ef719a44
RH
3955 [(const_int 0)]
3956 "ix86_split_long_move (operands); DONE;")
886c62d1 3957\f
e075ae69 3958;; Zero extension instructions
886c62d1 3959
8f7661f2
JH
3960(define_expand "zero_extendhisi2"
3961 [(set (match_operand:SI 0 "register_operand" "")
3962 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
d626200a 3963 ""
e075ae69 3964{
3debdc1e 3965 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
2ae0f82c 3966 {
8f7661f2
JH
3967 operands[1] = force_reg (HImode, operands[1]);
3968 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3969 DONE;
2ae0f82c 3970 }
0f40f9f7 3971})
886c62d1 3972
8f7661f2
JH
3973(define_insn "zero_extendhisi2_and"
3974 [(set (match_operand:SI 0 "register_operand" "=r")
3975 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
8bc527af 3976 (clobber (reg:CC FLAGS_REG))]
3debdc1e 3977 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
8f7661f2 3978 "#"
6ef67412
JH
3979 [(set_attr "type" "alu1")
3980 (set_attr "mode" "SI")])
2ae0f82c
SC
3981
3982(define_split
3983 [(set (match_operand:SI 0 "register_operand" "")
8f7661f2 3984 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
8bc527af 3985 (clobber (reg:CC FLAGS_REG))]
3debdc1e
JH
3986 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3987 && optimize_function_for_speed_p (cfun)"
8f7661f2 3988 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
8bc527af 3989 (clobber (reg:CC FLAGS_REG))])]
d626200a
JL
3990 "")
3991
8f7661f2
JH
3992(define_insn "*zero_extendhisi2_movzwl"
3993 [(set (match_operand:SI 0 "register_operand" "=r")
3994 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3debdc1e
JH
3995 "!TARGET_ZERO_EXTEND_WITH_AND
3996 || optimize_function_for_size_p (cfun)"
0f40f9f7 3997 "movz{wl|x}\t{%1, %0|%0, %1}"
6ef67412
JH
3998 [(set_attr "type" "imovx")
3999 (set_attr "mode" "SI")])
8f7661f2
JH
4000
4001(define_expand "zero_extendqihi2"
4002 [(parallel
4003 [(set (match_operand:HI 0 "register_operand" "")
4004 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 4005 (clobber (reg:CC FLAGS_REG))])]
e075ae69 4006 ""
8f7661f2
JH
4007 "")
4008
4009(define_insn "*zero_extendqihi2_and"
4010 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4011 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
8bc527af 4012 (clobber (reg:CC FLAGS_REG))]
3debdc1e 4013 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
8f7661f2 4014 "#"
6ef67412
JH
4015 [(set_attr "type" "alu1")
4016 (set_attr "mode" "HI")])
8f7661f2
JH
4017
4018(define_insn "*zero_extendqihi2_movzbw_and"
4019 [(set (match_operand:HI 0 "register_operand" "=r,r")
4020 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
8bc527af 4021 (clobber (reg:CC FLAGS_REG))]
3debdc1e 4022 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
8f7661f2 4023 "#"
6ef67412
JH
4024 [(set_attr "type" "imovx,alu1")
4025 (set_attr "mode" "HI")])
886c62d1 4026
0d9e7244
EC
4027; zero extend to SImode here to avoid partial register stalls
4028(define_insn "*zero_extendqihi2_movzbl"
8f7661f2
JH
4029 [(set (match_operand:HI 0 "register_operand" "=r")
4030 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
71aaa2ff 4031 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3debdc1e 4032 && reload_completed"
9ad5e54f 4033 "movz{bl|x}\t{%1, %k0|%k0, %1}"
6ef67412 4034 [(set_attr "type" "imovx")
0d9e7244 4035 (set_attr "mode" "SI")])
8f7661f2
JH
4036
4037;; For the movzbw case strip only the clobber
2ae0f82c
SC
4038(define_split
4039 [(set (match_operand:HI 0 "register_operand" "")
e075ae69 4040 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 4041 (clobber (reg:CC FLAGS_REG))]
6300f037 4042 "reload_completed
3debdc1e
JH
4043 && (!TARGET_ZERO_EXTEND_WITH_AND
4044 || optimize_function_for_size_p (cfun))
1a06f5fe 4045 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2
JH
4046 [(set (match_operand:HI 0 "register_operand" "")
4047 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2ae0f82c 4048
8f7661f2
JH
4049;; When source and destination does not overlap, clear destination
4050;; first and then do the movb
2ae0f82c
SC
4051(define_split
4052 [(set (match_operand:HI 0 "register_operand" "")
8f7661f2 4053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 4054 (clobber (reg:CC FLAGS_REG))]
e075ae69 4055 "reload_completed
1a06f5fe 4056 && ANY_QI_REG_P (operands[0])
3debdc1e
JH
4057 && (TARGET_ZERO_EXTEND_WITH_AND
4058 && optimize_function_for_speed_p (cfun))
8f7661f2
JH
4059 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4060 [(set (match_dup 0) (const_int 0))
4061 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4062 "operands[2] = gen_lowpart (QImode, operands[0]);")
2ae0f82c 4063
8f7661f2 4064;; Rest is handled by single and.
2ae0f82c
SC
4065(define_split
4066 [(set (match_operand:HI 0 "register_operand" "")
e075ae69 4067 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
8bc527af 4068 (clobber (reg:CC FLAGS_REG))]
e075ae69 4069 "reload_completed
8f7661f2
JH
4070 && true_regnum (operands[0]) == true_regnum (operands[1])"
4071 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
8bc527af 4072 (clobber (reg:CC FLAGS_REG))])]
d626200a
JL
4073 "")
4074
8f7661f2
JH
4075(define_expand "zero_extendqisi2"
4076 [(parallel
4077 [(set (match_operand:SI 0 "register_operand" "")
4078 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 4079 (clobber (reg:CC FLAGS_REG))])]
e075ae69 4080 ""
8f7661f2
JH
4081 "")
4082
4083(define_insn "*zero_extendqisi2_and"
4084 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4085 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
8bc527af 4086 (clobber (reg:CC FLAGS_REG))]
3debdc1e 4087 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
8f7661f2 4088 "#"
6ef67412
JH
4089 [(set_attr "type" "alu1")
4090 (set_attr "mode" "SI")])
8f7661f2
JH
4091
4092(define_insn "*zero_extendqisi2_movzbw_and"
4093 [(set (match_operand:SI 0 "register_operand" "=r,r")
4094 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
8bc527af 4095 (clobber (reg:CC FLAGS_REG))]
3debdc1e 4096 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
8f7661f2 4097 "#"
6ef67412
JH
4098 [(set_attr "type" "imovx,alu1")
4099 (set_attr "mode" "SI")])
2ae0f82c 4100
8f7661f2
JH
4101(define_insn "*zero_extendqisi2_movzbw"
4102 [(set (match_operand:SI 0 "register_operand" "=r")
4103 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3debdc1e
JH
4104 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4105 && reload_completed"
0f40f9f7 4106 "movz{bl|x}\t{%1, %0|%0, %1}"
6ef67412
JH
4107 [(set_attr "type" "imovx")
4108 (set_attr "mode" "SI")])
8f7661f2
JH
4109
4110;; For the movzbl case strip only the clobber
4111(define_split
4112 [(set (match_operand:SI 0 "register_operand" "")
4113 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 4114 (clobber (reg:CC FLAGS_REG))]
6300f037 4115 "reload_completed
3debdc1e 4116 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
1a06f5fe 4117 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2
JH
4118 [(set (match_dup 0)
4119 (zero_extend:SI (match_dup 1)))])
4120
4121;; When source and destination does not overlap, clear destination
4122;; first and then do the movb
2ae0f82c
SC
4123(define_split
4124 [(set (match_operand:SI 0 "register_operand" "")
e075ae69 4125 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 4126 (clobber (reg:CC FLAGS_REG))]
e075ae69 4127 "reload_completed
1a06f5fe 4128 && ANY_QI_REG_P (operands[0])
7656aee4 4129 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3debdc1e 4130 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
e075ae69 4131 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8f7661f2
JH
4132 [(set (match_dup 0) (const_int 0))
4133 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4134 "operands[2] = gen_lowpart (QImode, operands[0]);")
2ae0f82c 4135
8f7661f2 4136;; Rest is handled by single and.
2ae0f82c
SC
4137(define_split
4138 [(set (match_operand:SI 0 "register_operand" "")
e075ae69 4139 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
8bc527af 4140 (clobber (reg:CC FLAGS_REG))]
e075ae69 4141 "reload_completed
8f7661f2
JH
4142 && true_regnum (operands[0]) == true_regnum (operands[1])"
4143 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
8bc527af 4144 (clobber (reg:CC FLAGS_REG))])]
e075ae69 4145 "")
2ae0f82c 4146
e075ae69 4147;; %%% Kill me once multi-word ops are sane.
123bf9e3 4148(define_expand "zero_extendsidi2"
00188daa
UB
4149 [(set (match_operand:DI 0 "register_operand" "")
4150 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
123bf9e3 4151 ""
ed69105c
RH
4152{
4153 if (!TARGET_64BIT)
4154 {
4155 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4156 DONE;
4157 }
4158})
123bf9e3
JH
4159
4160(define_insn "zero_extendsidi2_32"
e2520c41 4161 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
50961141 4162 (zero_extend:DI
4afb7791 4163 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
8bc527af 4164 (clobber (reg:CC FLAGS_REG))]
f75959a6 4165 "!TARGET_64BIT"
ebe75517
JH
4166 "@
4167 #
4168 #
4169 #
4170 movd\t{%1, %0|%0, %1}
ed69105c 4171 movd\t{%1, %0|%0, %1}
95879c72
L
4172 %vmovd\t{%1, %0|%0, %1}
4173 %vmovd\t{%1, %0|%0, %1}"
4174 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4175 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4176 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
2ae0f82c 4177
123bf9e3 4178(define_insn "zero_extendsidi2_rex64"
e2520c41 4179 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
50961141 4180 (zero_extend:DI
4afb7791 4181 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
f75959a6 4182 "TARGET_64BIT"
ebe75517
JH
4183 "@
4184 mov\t{%k1, %k0|%k0, %k1}
4185 #
4186 movd\t{%1, %0|%0, %1}
ed69105c 4187 movd\t{%1, %0|%0, %1}
95879c72
L
4188 %vmovd\t{%1, %0|%0, %1}
4189 %vmovd\t{%1, %0|%0, %1}"
ed69105c 4190 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
95879c72 4191 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
a952487c 4192 (set_attr "prefix_0f" "0,*,*,*,*,*")
ed69105c 4193 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
123bf9e3
JH
4194
4195(define_split
4196 [(set (match_operand:DI 0 "memory_operand" "")
4197 (zero_extend:DI (match_dup 0)))]
1b0c37d7 4198 "TARGET_64BIT"
123bf9e3
JH
4199 [(set (match_dup 4) (const_int 0))]
4200 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4201
6300f037 4202(define_split
bb62e19a 4203 [(set (match_operand:DI 0 "register_operand" "")
e075ae69 4204 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 4205 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
4206 "!TARGET_64BIT && reload_completed
4207 && true_regnum (operands[0]) == true_regnum (operands[1])"
591702de 4208 [(set (match_dup 4) (const_int 0))]
bb62e19a
JH
4209 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4210
6300f037 4211(define_split
bb62e19a 4212 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69 4213 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
8bc527af 4214 (clobber (reg:CC FLAGS_REG))]
ebe75517
JH
4215 "!TARGET_64BIT && reload_completed
4216 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
bb62e19a 4217 [(set (match_dup 3) (match_dup 1))
591702de 4218 (set (match_dup 4) (const_int 0))]
bb62e19a 4219 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
123bf9e3
JH
4220
4221(define_insn "zero_extendhidi2"
422edd6f
JB
4222 [(set (match_operand:DI 0 "register_operand" "=r")
4223 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
123bf9e3 4224 "TARGET_64BIT"
422edd6f 4225 "movz{wl|x}\t{%1, %k0|%k0, %1}"
123bf9e3 4226 [(set_attr "type" "imovx")
a952487c 4227 (set_attr "mode" "SI")])
123bf9e3
JH
4228
4229(define_insn "zero_extendqidi2"
422edd6f
JB
4230 [(set (match_operand:DI 0 "register_operand" "=r")
4231 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
123bf9e3 4232 "TARGET_64BIT"
422edd6f 4233 "movz{bl|x}\t{%1, %k0|%k0, %1}"
123bf9e3 4234 [(set_attr "type" "imovx")
a952487c 4235 (set_attr "mode" "SI")])
886c62d1 4236\f
e075ae69 4237;; Sign extension instructions
886c62d1 4238
123bf9e3
JH
4239(define_expand "extendsidi2"
4240 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4241 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 4242 (clobber (reg:CC FLAGS_REG))
123bf9e3
JH
4243 (clobber (match_scratch:SI 2 ""))])]
4244 ""
123bf9e3
JH
4245{
4246 if (TARGET_64BIT)
4247 {
4248 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4249 DONE;
4250 }
0f40f9f7 4251})
123bf9e3
JH
4252
4253(define_insn "*extendsidi2_1"
e075ae69
RH
4254 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4255 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
8bc527af 4256 (clobber (reg:CC FLAGS_REG))
6b29b0e2 4257 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
123bf9e3 4258 "!TARGET_64BIT"
724d568a
JH
4259 "#")
4260
123bf9e3
JH
4261(define_insn "extendsidi2_rex64"
4262 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4263 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4264 "TARGET_64BIT"
4265 "@
4266 {cltq|cdqe}
725fd454 4267 movs{lq|x}\t{%1, %0|%0, %1}"
123bf9e3
JH
4268 [(set_attr "type" "imovx")
4269 (set_attr "mode" "DI")
4270 (set_attr "prefix_0f" "0")
4271 (set_attr "modrm" "0,1")])
4272
4273(define_insn "extendhidi2"
4274 [(set (match_operand:DI 0 "register_operand" "=r")
4275 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4276 "TARGET_64BIT"
725fd454 4277 "movs{wq|x}\t{%1, %0|%0, %1}"
123bf9e3
JH
4278 [(set_attr "type" "imovx")
4279 (set_attr "mode" "DI")])
4280
4281(define_insn "extendqidi2"
4282 [(set (match_operand:DI 0 "register_operand" "=r")
4283 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4284 "TARGET_64BIT"
725fd454 4285 "movs{bq|x}\t{%1, %0|%0, %1}"
123bf9e3
JH
4286 [(set_attr "type" "imovx")
4287 (set_attr "mode" "DI")])
4288
724d568a 4289;; Extend to memory case when source register does die.
6300f037 4290(define_split
724d568a
JH
4291 [(set (match_operand:DI 0 "memory_operand" "")
4292 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 4293 (clobber (reg:CC FLAGS_REG))
6b29b0e2 4294 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 4295 "(reload_completed
724d568a
JH
4296 && dead_or_set_p (insn, operands[1])
4297 && !reg_mentioned_p (operands[1], operands[0]))"
4298 [(set (match_dup 3) (match_dup 1))
e075ae69 4299 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
8bc527af 4300 (clobber (reg:CC FLAGS_REG))])
724d568a
JH
4301 (set (match_dup 4) (match_dup 1))]
4302 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4303
4304;; Extend to memory case when source register does not die.
6300f037 4305(define_split
724d568a
JH
4306 [(set (match_operand:DI 0 "memory_operand" "")
4307 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 4308 (clobber (reg:CC FLAGS_REG))
6b29b0e2 4309 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 4310 "reload_completed"
724d568a 4311 [(const_int 0)]
9c530261 4312{
724d568a
JH
4313 split_di (&operands[0], 1, &operands[3], &operands[4]);
4314
4315 emit_move_insn (operands[3], operands[1]);
4316
4317 /* Generate a cltd if possible and doing so it profitable. */
3debdc1e 4318 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
29b74761
UB
4319 && true_regnum (operands[1]) == AX_REG
4320 && true_regnum (operands[2]) == DX_REG)
71a247f0 4321 {
e075ae69 4322 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
724d568a
JH
4323 }
4324 else
4325 {
4326 emit_move_insn (operands[2], operands[1]);
e075ae69 4327 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
71a247f0 4328 }
724d568a
JH
4329 emit_move_insn (operands[4], operands[2]);
4330 DONE;
0f40f9f7 4331})
9c530261 4332
724d568a
JH
4333;; Extend to register case. Optimize case where source and destination
4334;; registers match and cases where we can use cltd.
6300f037 4335(define_split
724d568a
JH
4336 [(set (match_operand:DI 0 "register_operand" "")
4337 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 4338 (clobber (reg:CC FLAGS_REG))
6b29b0e2 4339 (clobber (match_scratch:SI 2 ""))]
724d568a
JH
4340 "reload_completed"
4341 [(const_int 0)]
724d568a
JH
4342{
4343 split_di (&operands[0], 1, &operands[3], &operands[4]);
4344
4345 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4346 emit_move_insn (operands[3], operands[1]);
9c530261 4347
724d568a 4348 /* Generate a cltd if possible and doing so it profitable. */
3debdc1e 4349 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
29b74761 4350 && true_regnum (operands[3]) == AX_REG)
724d568a 4351 {
e075ae69 4352 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
724d568a
JH
4353 DONE;
4354 }
4355
4356 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4357 emit_move_insn (operands[4], operands[1]);
4358
e075ae69 4359 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
724d568a 4360 DONE;
0f40f9f7 4361})
886c62d1 4362
886c62d1 4363(define_insn "extendhisi2"
e075ae69
RH
4364 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4365 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
886c62d1 4366 ""
886c62d1 4367{
6ef67412 4368 switch (get_attr_prefix_0f (insn))
e075ae69 4369 {
6ef67412 4370 case 0:
0f40f9f7 4371 return "{cwtl|cwde}";
e075ae69 4372 default:
725fd454 4373 return "movs{wl|x}\t{%1, %0|%0, %1}";
e075ae69 4374 }
0f40f9f7 4375}
e075ae69 4376 [(set_attr "type" "imovx")
6ef67412
JH
4377 (set_attr "mode" "SI")
4378 (set (attr "prefix_0f")
4379 ;; movsx is short decodable while cwtl is vector decoded.
4380 (if_then_else (and (eq_attr "cpu" "!k6")
4381 (eq_attr "alternative" "0"))
4382 (const_string "0")
4383 (const_string "1")))
4384 (set (attr "modrm")
4385 (if_then_else (eq_attr "prefix_0f" "0")
4386 (const_string "0")
4387 (const_string "1")))])
886c62d1 4388
123bf9e3
JH
4389(define_insn "*extendhisi2_zext"
4390 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4391 (zero_extend:DI
4392 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4393 "TARGET_64BIT"
123bf9e3
JH
4394{
4395 switch (get_attr_prefix_0f (insn))
4396 {
4397 case 0:
0f40f9f7 4398 return "{cwtl|cwde}";
123bf9e3 4399 default:
725fd454 4400 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
123bf9e3 4401 }
0f40f9f7 4402}
123bf9e3
JH
4403 [(set_attr "type" "imovx")
4404 (set_attr "mode" "SI")
4405 (set (attr "prefix_0f")
4406 ;; movsx is short decodable while cwtl is vector decoded.
4407 (if_then_else (and (eq_attr "cpu" "!k6")
4408 (eq_attr "alternative" "0"))
4409 (const_string "0")
4410 (const_string "1")))
4411 (set (attr "modrm")
4412 (if_then_else (eq_attr "prefix_0f" "0")
4413 (const_string "0")
4414 (const_string "1")))])
4415
886c62d1 4416(define_insn "extendqihi2"
e075ae69
RH
4417 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4418 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
886c62d1 4419 ""
886c62d1 4420{
6ef67412 4421 switch (get_attr_prefix_0f (insn))
e075ae69 4422 {
6ef67412 4423 case 0:
0f40f9f7 4424 return "{cbtw|cbw}";
e075ae69 4425 default:
725fd454 4426 return "movs{bw|x}\t{%1, %0|%0, %1}";
e075ae69 4427 }
0f40f9f7 4428}
e075ae69 4429 [(set_attr "type" "imovx")
6ef67412
JH
4430 (set_attr "mode" "HI")
4431 (set (attr "prefix_0f")
4432 ;; movsx is short decodable while cwtl is vector decoded.
4433 (if_then_else (and (eq_attr "cpu" "!k6")
4434 (eq_attr "alternative" "0"))
4435 (const_string "0")
4436 (const_string "1")))
4437 (set (attr "modrm")
4438 (if_then_else (eq_attr "prefix_0f" "0")
4439 (const_string "0")
4440 (const_string "1")))])
886c62d1
JVA
4441
4442(define_insn "extendqisi2"
2ae0f82c
SC
4443 [(set (match_operand:SI 0 "register_operand" "=r")
4444 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
886c62d1 4445 ""
725fd454 4446 "movs{bl|x}\t{%1, %0|%0, %1}"
6ef67412
JH
4447 [(set_attr "type" "imovx")
4448 (set_attr "mode" "SI")])
123bf9e3
JH
4449
4450(define_insn "*extendqisi2_zext"
4451 [(set (match_operand:DI 0 "register_operand" "=r")
4452 (zero_extend:DI
4453 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4454 "TARGET_64BIT"
725fd454 4455 "movs{bl|x}\t{%1, %k0|%k0, %1}"
123bf9e3
JH
4456 [(set_attr "type" "imovx")
4457 (set_attr "mode" "SI")])
886c62d1
JVA
4458\f
4459;; Conversions between float and double.
4460
e075ae69
RH
4461;; These are all no-ops in the model used for the 80387. So just
4462;; emit moves.
6a4a5d95 4463
6300f037 4464;; %%% Kill these when call knows how to work out a DFmode push earlier.
6343a50e 4465(define_insn "*dummy_extendsfdf2"
e075ae69 4466 [(set (match_operand:DF 0 "push_operand" "=<")
e2520c41 4467 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
e075ae69
RH
4468 "0"
4469 "#")
6a4a5d95
JW
4470
4471(define_split
e075ae69 4472 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3 4473 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
90b48492
KT
4474 ""
4475 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4476 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
123bf9e3 4477
6343a50e 4478(define_insn "*dummy_extendsfxf2"
e075ae69
RH
4479 [(set (match_operand:XF 0 "push_operand" "=<")
4480 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4481 "0"
4482 "#")
e4ad1003
JW
4483
4484(define_split
e075ae69 4485 [(set (match_operand:XF 0 "push_operand" "")
c3c637e3 4486 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
f8a1ebc6 4487 ""
90b48492
KT
4488 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4489 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
f8a1ebc6 4490 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
e4ad1003
JW
4491
4492(define_split
e075ae69 4493 [(set (match_operand:XF 0 "push_operand" "")
c3c637e3 4494 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
f8a1ebc6 4495 ""
90b48492
KT
4496 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4497 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
f8a1ebc6 4498 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
123bf9e3 4499
f97d9ec3
JH
4500(define_expand "extendsfdf2"
4501 [(set (match_operand:DF 0 "nonimmediate_operand" "")
51286de6 4502 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
2312581e 4503 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
f97d9ec3 4504{
51286de6
RH
4505 /* ??? Needed for compress_float_constant since all fp constants
4506 are LEGITIMATE_CONSTANT_P. */
4507 if (GET_CODE (operands[1]) == CONST_DOUBLE)
e046a30a
PB
4508 {
4509 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4510 && standard_80387_constant_p (operands[1]) > 0)
4511 {
4512 operands[1] = simplify_const_unary_operation
4513 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4514 emit_move_insn_1 (operands[0], operands[1]);
4515 DONE;
4516 }
4517 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4518 }
0f40f9f7 4519})
f97d9ec3 4520
4845dbb5
JH
4521/* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4522 cvtss2sd:
4523 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4524 cvtps2pd xmm2,xmm1
4525 We do the conversion post reload to avoid producing of 128bit spills
4526 that might lead to ICE on 32bit target. The sequence unlikely combine
4527 anyway. */
4528(define_split
4529 [(set (match_operand:DF 0 "register_operand" "")
4530 (float_extend:DF
4531 (match_operand:SF 1 "nonimmediate_operand" "")))]
54723b46 4532 "TARGET_USE_VECTOR_FP_CONVERTS
3debdc1e 4533 && optimize_insn_for_speed_p ()
4845dbb5
JH
4534 && reload_completed && SSE_REG_P (operands[0])"
4535 [(set (match_dup 2)
4536 (float_extend:V2DF
4537 (vec_select:V2SF
4538 (match_dup 3)
4539 (parallel [(const_int 0) (const_int 1)]))))]
4540{
4541 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4542 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4543 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4544 Try to avoid move when unpacking can be done in source. */
4545 if (REG_P (operands[1]))
4546 {
4547 /* If it is unsafe to overwrite upper half of source, we need
4548 to move to destination and unpack there. */
4549 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4550 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4551 && true_regnum (operands[0]) != true_regnum (operands[1]))
4552 {
4553 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4554 emit_move_insn (tmp, operands[1]);
4555 }
4556 else
4557 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4558 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4559 }
4560 else
4f3f76e6 4561 emit_insn (gen_vec_setv4sf_0 (operands[3],
4845dbb5
JH
4562 CONST0_RTX (V4SFmode), operands[1]));
4563})
4564
2312581e 4565(define_insn "*extendsfdf2_mixed"
50961141
RH
4566 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4567 (float_extend:DF
4568 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
509a77dc 4569 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4fb21e90 4570{
e075ae69 4571 switch (which_alternative)
4fb21e90 4572 {
e075ae69 4573 case 0:
e075ae69 4574 case 1:
d869c351 4575 return output_387_reg_move (insn, operands);
5ea9cb6e 4576
42a0aa6f 4577 case 2:
95879c72 4578 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4fb21e90 4579
e075ae69 4580 default:
7637e42c 4581 gcc_unreachable ();
e075ae69 4582 }
0f40f9f7 4583}
3d34cd91 4584 [(set_attr "type" "fmov,fmov,ssecvt")
95879c72 4585 (set_attr "prefix" "orig,orig,maybe_vex")
a811cc63 4586 (set_attr "mode" "SF,XF,DF")])
42a0aa6f 4587
2312581e 4588(define_insn "*extendsfdf2_sse"
50961141
RH
4589 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4590 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
509a77dc 4591 "TARGET_SSE2 && TARGET_SSE_MATH"
95879c72 4592 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3d34cd91 4593 [(set_attr "type" "ssecvt")
95879c72 4594 (set_attr "prefix" "maybe_vex")
42a0aa6f 4595 (set_attr "mode" "DF")])
e075ae69 4596
2312581e
UB
4597(define_insn "*extendsfdf2_i387"
4598 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4599 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
509a77dc 4600 "TARGET_80387"
d869c351 4601 "* return output_387_reg_move (insn, operands);"
2312581e
UB
4602 [(set_attr "type" "fmov")
4603 (set_attr "mode" "SF,XF")])
4604
a344e3cb 4605(define_expand "extend<mode>xf2"
f97d9ec3 4606 [(set (match_operand:XF 0 "nonimmediate_operand" "")
00188daa 4607 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
f8a1ebc6 4608 "TARGET_80387"
f97d9ec3 4609{
51286de6
RH
4610 /* ??? Needed for compress_float_constant since all fp constants
4611 are LEGITIMATE_CONSTANT_P. */
4612 if (GET_CODE (operands[1]) == CONST_DOUBLE)
e046a30a
PB
4613 {
4614 if (standard_80387_constant_p (operands[1]) > 0)
4615 {
4616 operands[1] = simplify_const_unary_operation
a344e3cb 4617 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
e046a30a
PB
4618 emit_move_insn_1 (operands[0], operands[1]);
4619 DONE;
4620 }
a344e3cb 4621 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
e046a30a 4622 }
0f40f9f7 4623})
f97d9ec3 4624
a344e3cb 4625(define_insn "*extend<mode>xf2_i387"
e075ae69 4626 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
a344e3cb 4627 (float_extend:XF
00188daa 4628 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
509a77dc 4629 "TARGET_80387"
d869c351 4630 "* return output_387_reg_move (insn, operands);"
2b589241 4631 [(set_attr "type" "fmov")
a344e3cb 4632 (set_attr "mode" "<MODE>,XF")])
2b589241 4633
e075ae69
RH
4634;; %%% This seems bad bad news.
4635;; This cannot output into an f-reg because there is no way to be sure
4636;; of truncating in that case. Otherwise this is just like a simple move
4637;; insn. So we pretend we can output to a reg in order to get better
4638;; register preferencing, but we really use a stack slot.
886c62d1 4639
5b1f1e63 4640;; Conversion from DFmode to SFmode.
bc725565 4641
5b1f1e63
RH
4642(define_expand "truncdfsf2"
4643 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4644 (float_truncate:SF
4645 (match_operand:DF 1 "nonimmediate_operand" "")))]
4646 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
82a6a758 4647{
5b1f1e63
RH
4648 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4649 ;
4650 else if (flag_unsafe_math_optimizations)
4651 ;
4652 else
4653 {
bbbbb16a
ILT
4654 enum ix86_stack_slot slot = (virtuals_instantiated
4655 ? SLOT_TEMP
4656 : SLOT_VIRTUAL);
be0c4603 4657 rtx temp = assign_386_stack_local (SFmode, slot);
5b1f1e63
RH
4658 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4659 DONE;
4660 }
4661})
4662
4845dbb5
JH
4663/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4664 cvtsd2ss:
4665 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4666 cvtpd2ps xmm2,xmm1
4667 We do the conversion post reload to avoid producing of 128bit spills
4668 that might lead to ICE on 32bit target. The sequence unlikely combine
4669 anyway. */
4670(define_split
4671 [(set (match_operand:SF 0 "register_operand" "")
4672 (float_truncate:SF
4673 (match_operand:DF 1 "nonimmediate_operand" "")))]
54723b46 4674 "TARGET_USE_VECTOR_FP_CONVERTS
3debdc1e 4675 && optimize_insn_for_speed_p ()
4845dbb5
JH
4676 && reload_completed && SSE_REG_P (operands[0])"
4677 [(set (match_dup 2)
4678 (vec_concat:V4SF
4679 (float_truncate:V2SF
4680 (match_dup 4))
4681 (match_dup 3)))]
4682{
4683 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4684 operands[3] = CONST0_RTX (V2SFmode);
4685 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4686 /* Use movsd for loading from memory, unpcklpd for registers.
4687 Try to avoid move when unpacking can be done in source, or SSE3
4688 movddup is available. */
4689 if (REG_P (operands[1]))
4690 {
4691 if (!TARGET_SSE3
4692 && true_regnum (operands[0]) != true_regnum (operands[1])
4693 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4694 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4695 {
4696 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4697 emit_move_insn (tmp, operands[1]);
4698 operands[1] = tmp;
4699 }
4700 else if (!TARGET_SSE3)
4701 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4702 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4703 }
4704 else
4705 emit_insn (gen_sse2_loadlpd (operands[4],
4706 CONST0_RTX (V2DFmode), operands[1]));
4707})
4708
5b1f1e63
RH
4709(define_expand "truncdfsf2_with_temp"
4710 [(parallel [(set (match_operand:SF 0 "" "")
4711 (float_truncate:SF (match_operand:DF 1 "" "")))
4712 (clobber (match_operand:SF 2 "" ""))])]
4713 "")
4714
4715(define_insn "*truncdfsf_fast_mixed"
73e8165a 4716 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
5b1f1e63 4717 (float_truncate:SF
73e8165a 4718 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
5b1f1e63 4719 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
e075ae69
RH
4720{
4721 switch (which_alternative)
4722 {
4723 case 0:
5b1f1e63 4724 return output_387_reg_move (insn, operands);
73e8165a 4725 case 1:
95879c72 4726 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
46ed7963 4727 default:
7637e42c 4728 gcc_unreachable ();
e075ae69 4729 }
0f40f9f7 4730}
73e8165a 4731 [(set_attr "type" "fmov,ssecvt")
95879c72 4732 (set_attr "prefix" "orig,maybe_vex")
5b1f1e63
RH
4733 (set_attr "mode" "SF")])
4734
4735;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4736;; because nothing we do here is unsafe.
4737(define_insn "*truncdfsf_fast_sse"
50961141 4738 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
5b1f1e63 4739 (float_truncate:SF
50961141 4740 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
5b1f1e63 4741 "TARGET_SSE2 && TARGET_SSE_MATH"
95879c72 4742 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
5b1f1e63 4743 [(set_attr "type" "ssecvt")
95879c72 4744 (set_attr "prefix" "maybe_vex")
5b1f1e63
RH
4745 (set_attr "mode" "SF")])
4746
4747(define_insn "*truncdfsf_fast_i387"
4748 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4749 (float_truncate:SF
4750 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4751 "TARGET_80387 && flag_unsafe_math_optimizations"
4752 "* return output_387_reg_move (insn, operands);"
4753 [(set_attr "type" "fmov")
4754 (set_attr "mode" "SF")])
42a0aa6f 4755
5b1f1e63 4756(define_insn "*truncdfsf_mixed"
9ade279b 4757 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
42a0aa6f 4758 (float_truncate:SF
9ade279b
UB
4759 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4760 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
5b1f1e63 4761 "TARGET_MIX_SSE_I387"
4977bab6
ZW
4762{
4763 switch (which_alternative)
4764 {
4765 case 0:
a344e3cb 4766 return output_387_reg_move (insn, operands);
5b1f1e63 4767 case 1:
95879c72 4768 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
9ade279b 4769
46ed7963 4770 default:
9ade279b 4771 return "#";
42a0aa6f 4772 }
0f40f9f7 4773}
9ade279b
UB
4774 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4775 (set_attr "unit" "*,*,i387,i387,i387")
4776 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
5b1f1e63 4777 (set_attr "mode" "SF")])
53b5ce19 4778
5b1f1e63 4779(define_insn "*truncdfsf_i387"
9ade279b 4780 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
42a0aa6f 4781 (float_truncate:SF
9ade279b
UB
4782 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4783 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
5b1f1e63 4784 "TARGET_80387"
42a0aa6f
JH
4785{
4786 switch (which_alternative)
4787 {
4788 case 0:
a344e3cb
UB
4789 return output_387_reg_move (insn, operands);
4790
0f40f9f7 4791 default:
9ade279b 4792 return "#";
42a0aa6f 4793 }
0f40f9f7 4794}
9ade279b
UB
4795 [(set_attr "type" "fmov,multi,multi,multi")
4796 (set_attr "unit" "*,i387,i387,i387")
26f74aa3 4797 (set_attr "mode" "SF")])
acaa3bf7
RS
4798
4799(define_insn "*truncdfsf2_i387_1"
4800 [(set (match_operand:SF 0 "memory_operand" "=m")
4801 (float_truncate:SF
4802 (match_operand:DF 1 "register_operand" "f")))]
4803 "TARGET_80387
4804 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4805 && !TARGET_MIX_SSE_I387"
a344e3cb 4806 "* return output_387_reg_move (insn, operands);"
acaa3bf7
RS
4807 [(set_attr "type" "fmov")
4808 (set_attr "mode" "SF")])
42a0aa6f 4809
42a0aa6f 4810(define_split
4977bab6 4811 [(set (match_operand:SF 0 "register_operand" "")
42a0aa6f 4812 (float_truncate:SF
5b1f1e63 4813 (match_operand:DF 1 "fp_register_operand" "")))
42a0aa6f 4814 (clobber (match_operand 2 "" ""))]
5b1f1e63
RH
4815 "reload_completed"
4816 [(set (match_dup 2) (match_dup 1))
4817 (set (match_dup 0) (match_dup 2))]
4977bab6 4818{
5b1f1e63 4819 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4977bab6 4820})
42a0aa6f 4821
a344e3cb 4822;; Conversion from XFmode to {SF,DF}mode
53b5ce19 4823
a344e3cb 4824(define_expand "truncxf<mode>2"
00188daa
UB
4825 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4826 (float_truncate:MODEF
a344e3cb 4827 (match_operand:XF 1 "register_operand" "")))
e075ae69 4828 (clobber (match_dup 2))])]
f8a1ebc6 4829 "TARGET_80387"
5b1f1e63 4830{
0c5faf29
RS
4831 if (flag_unsafe_math_optimizations)
4832 {
a344e3cb
UB
4833 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4834 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
0c5faf29
RS
4835 if (reg != operands[0])
4836 emit_move_insn (operands[0], reg);
4837 DONE;
4838 }
4839 else
be0c4603 4840 {
bbbbb16a
ILT
4841 enum ix86_stack_slot slot = (virtuals_instantiated
4842 ? SLOT_TEMP
4843 : SLOT_VIRTUAL);
be0c4603
UB
4844 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4845 }
5b1f1e63
RH
4846})
4847
4848(define_insn "*truncxfsf2_mixed"
9ade279b 4849 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
5b1f1e63 4850 (float_truncate:SF
9ade279b
UB
4851 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4852 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
e26feb2c 4853 "TARGET_80387"
5b1f1e63 4854{
7637e42c 4855 gcc_assert (!which_alternative);
a344e3cb 4856 return output_387_reg_move (insn, operands);
0f40f9f7 4857}
9ade279b
UB
4858 [(set_attr "type" "fmov,multi,multi,multi")
4859 (set_attr "unit" "*,i387,i387,i387")
6ef67412 4860 (set_attr "mode" "SF")])
bc725565 4861
5b1f1e63 4862(define_insn "*truncxfdf2_mixed"
9ade279b 4863 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
5b1f1e63 4864 (float_truncate:DF
9ade279b
UB
4865 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4866 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
e26feb2c 4867 "TARGET_80387"
5b1f1e63 4868{
7637e42c 4869 gcc_assert (!which_alternative);
a344e3cb 4870 return output_387_reg_move (insn, operands);
5b1f1e63 4871}
9ade279b
UB
4872 [(set_attr "type" "fmov,multi,multi,multi")
4873 (set_attr "unit" "*,i387,i387,i387")
5b1f1e63 4874 (set_attr "mode" "DF")])
0c5faf29 4875
a344e3cb 4876(define_insn "truncxf<mode>2_i387_noop"
00188daa
UB
4877 [(set (match_operand:MODEF 0 "register_operand" "=f")
4878 (float_truncate:MODEF
a344e3cb 4879 (match_operand:XF 1 "register_operand" "f")))]
0c5faf29 4880 "TARGET_80387 && flag_unsafe_math_optimizations"
01302104 4881 "* return output_387_reg_move (insn, operands);"
82a6a758 4882 [(set_attr "type" "fmov")
a344e3cb 4883 (set_attr "mode" "<MODE>")])
bc725565 4884
a344e3cb 4885(define_insn "*truncxf<mode>2_i387"
00188daa
UB
4886 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4887 (float_truncate:MODEF
e075ae69 4888 (match_operand:XF 1 "register_operand" "f")))]
f8a1ebc6 4889 "TARGET_80387"
a344e3cb 4890 "* return output_387_reg_move (insn, operands);"
6ef67412 4891 [(set_attr "type" "fmov")
a344e3cb 4892 (set_attr "mode" "<MODE>")])
bc725565
JW
4893
4894(define_split
00188daa
UB
4895 [(set (match_operand:MODEF 0 "register_operand" "")
4896 (float_truncate:MODEF
a344e3cb 4897 (match_operand:XF 1 "register_operand" "")))
00188daa 4898 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
5b1f1e63 4899 "TARGET_80387 && reload_completed"
00188daa 4900 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
5b1f1e63 4901 (set (match_dup 0) (match_dup 2))]
4fb21e90
JVA
4902 "")
4903
bc725565 4904(define_split
00188daa
UB
4905 [(set (match_operand:MODEF 0 "memory_operand" "")
4906 (float_truncate:MODEF
a344e3cb 4907 (match_operand:XF 1 "register_operand" "")))
00188daa 4908 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
5b1f1e63 4909 "TARGET_80387"
00188daa 4910 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4fb21e90 4911 "")
e075ae69 4912\f
e075ae69
RH
4913;; Signed conversion to DImode.
4914
2b589241 4915(define_expand "fix_truncxfdi2"
ec13ba83
CT
4916 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4917 (fix:DI (match_operand:XF 1 "register_operand" "")))
8bc527af 4918 (clobber (reg:CC FLAGS_REG))])]
bc725565 4919 "TARGET_80387"
46ed7963 4920{
9199f050 4921 if (TARGET_FISTTP)
46ed7963 4922 {
9199f050 4923 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
46ed7963
JH
4924 DONE;
4925 }
0f40f9f7 4926})
53b5ce19 4927
9199f050 4928(define_expand "fix_trunc<mode>di2"
ec13ba83 4929 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
00188daa 4930 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
9199f050
UB
4931 (clobber (reg:CC FLAGS_REG))])]
4932 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
46ed7963 4933{
9199f050
UB
4934 if (TARGET_FISTTP
4935 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4936 {
4937 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4938 DONE;
4939 }
4940 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
46ed7963
JH
4941 {
4942 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
9199f050 4943 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
46ed7963
JH
4944 if (out != operands[0])
4945 emit_move_insn (operands[0], out);
4946 DONE;
4947 }
0f40f9f7 4948})
e075ae69 4949
e075ae69 4950;; Signed conversion to SImode.
53b5ce19 4951
e075ae69 4952(define_expand "fix_truncxfsi2"
ec13ba83 4953 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9199f050 4954 (fix:SI (match_operand:XF 1 "register_operand" "")))
8bc527af 4955 (clobber (reg:CC FLAGS_REG))])]
2b589241 4956 "TARGET_80387"
42a0aa6f 4957{
9199f050 4958 if (TARGET_FISTTP)
42a0aa6f 4959 {
9199f050 4960 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
42a0aa6f
JH
4961 DONE;
4962 }
0f40f9f7 4963})
886c62d1 4964
9199f050 4965(define_expand "fix_trunc<mode>si2"
ec13ba83 4966 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
00188daa 4967 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
9199f050 4968 (clobber (reg:CC FLAGS_REG))])]
84c2b4da 4969 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
42a0aa6f 4970{
9199f050
UB
4971 if (TARGET_FISTTP
4972 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4973 {
4974 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4975 DONE;
4976 }
4977 if (SSE_FLOAT_MODE_P (<MODE>mode))
42a0aa6f 4978 {
ca9a9b12 4979 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
9199f050 4980 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
b1675dbd
JH
4981 if (out != operands[0])
4982 emit_move_insn (operands[0], out);
42a0aa6f
JH
4983 DONE;
4984 }
0f40f9f7 4985})
e075ae69 4986
9199f050
UB
4987;; Signed conversion to HImode.
4988
4989(define_expand "fix_trunc<mode>hi2"
4990 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4991 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4992 (clobber (reg:CC FLAGS_REG))])]
4993 "TARGET_80387
4994 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
22fb740d 4995{
9199f050
UB
4996 if (TARGET_FISTTP)
4997 {
4998 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4999 DONE;
5000 }
5001})
22fb740d 5002
ebff937c
SH
5003;; Unsigned conversion to SImode.
5004
5005(define_expand "fixuns_trunc<mode>si2"
174c12c7
RH
5006 [(parallel
5007 [(set (match_operand:SI 0 "register_operand" "")
5008 (unsigned_fix:SI
00188daa 5009 (match_operand:MODEF 1 "nonimmediate_operand" "")))
174c12c7
RH
5010 (use (match_dup 2))
5011 (clobber (match_scratch:<ssevecmode> 3 ""))
5012 (clobber (match_scratch:<ssevecmode> 4 ""))])]
18bd082d 5013 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
174c12c7
RH
5014{
5015 enum machine_mode mode = <MODE>mode;
5016 enum machine_mode vecmode = <ssevecmode>mode;
5017 REAL_VALUE_TYPE TWO31r;
5018 rtx two31;
5019
18bd082d
JH
5020 if (optimize_insn_for_size_p ())
5021 FAIL;
5022
174c12c7
RH
5023 real_ldexp (&TWO31r, &dconst1, 31);
5024 two31 = const_double_from_real_value (TWO31r, mode);
5025 two31 = ix86_build_const_vector (mode, true, two31);
5026 operands[2] = force_reg (vecmode, two31);
5027})
5028
5029(define_insn_and_split "*fixuns_trunc<mode>_1"
5030 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5031 (unsigned_fix:SI
00188daa 5032 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
174c12c7
RH
5033 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5034 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5035 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
3debdc1e
JH
5036 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5037 && optimize_function_for_speed_p (cfun)"
174c12c7
RH
5038 "#"
5039 "&& reload_completed"
5040 [(const_int 0)]
ebff937c 5041{
174c12c7 5042 ix86_split_convert_uns_si_sse (operands);
ebff937c
SH
5043 DONE;
5044})
5045
5046;; Unsigned conversion to HImode.
5047;; Without these patterns, we'll try the unsigned SI conversion which
5048;; is complex for SSE, rather than the signed SI conversion, which isn't.
5049
d8e3118a 5050(define_expand "fixuns_trunc<mode>hi2"
ebff937c 5051 [(set (match_dup 2)
00188daa 5052 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
ebff937c
SH
5053 (set (match_operand:HI 0 "nonimmediate_operand" "")
5054 (subreg:HI (match_dup 2) 0))]
d8e3118a 5055 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
ebff937c
SH
5056 "operands[2] = gen_reg_rtx (SImode);")
5057
9199f050 5058;; When SSE is available, it is always faster to use it!
d8e3118a 5059(define_insn "fix_trunc<mode>di_sse"
9199f050 5060 [(set (match_operand:DI 0 "register_operand" "=r,r")
00188daa 5061 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
d8e3118a
UB
5062 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
5063 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
95879c72 5064 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
9199f050 5065 [(set_attr "type" "sseicvt")
95879c72 5066 (set_attr "prefix" "maybe_vex")
725fd454 5067 (set_attr "prefix_rex" "1")
d8e3118a 5068 (set_attr "mode" "<MODE>")
21efb4d4
HJ
5069 (set_attr "athlon_decode" "double,vector")
5070 (set_attr "amdfam10_decode" "double,double")])
22fb740d 5071
d8e3118a 5072(define_insn "fix_trunc<mode>si_sse"
f56e86bd 5073 [(set (match_operand:SI 0 "register_operand" "=r,r")
00188daa 5074 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
d8e3118a
UB
5075 "SSE_FLOAT_MODE_P (<MODE>mode)
5076 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
95879c72 5077 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
f56e86bd 5078 [(set_attr "type" "sseicvt")
95879c72 5079 (set_attr "prefix" "maybe_vex")
d8e3118a 5080 (set_attr "mode" "<MODE>")
21efb4d4
HJ
5081 (set_attr "athlon_decode" "double,vector")
5082 (set_attr "amdfam10_decode" "double,double")])
42a0aa6f 5083
962ef7fe
UB
5084;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5085(define_peephole2
00188daa
UB
5086 [(set (match_operand:MODEF 0 "register_operand" "")
5087 (match_operand:MODEF 1 "memory_operand" ""))
962ef7fe
UB
5088 (set (match_operand:SSEMODEI24 2 "register_operand" "")
5089 (fix:SSEMODEI24 (match_dup 0)))]
ddff69b9 5090 "TARGET_SHORTEN_X87_SSE
962ef7fe
UB
5091 && peep2_reg_dead_p (2, operands[0])"
5092 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5093 "")
5094
9199f050 5095;; Avoid vector decoded forms of the instruction.
8dfa3bb0 5096(define_peephole2
e2520c41 5097 [(match_scratch:DF 2 "Y2")
9199f050
UB
5098 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5099 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
3debdc1e 5100 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
8dfa3bb0 5101 [(set (match_dup 2) (match_dup 1))
9199f050 5102 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
8dfa3bb0
JH
5103 "")
5104
9199f050
UB
5105(define_peephole2
5106 [(match_scratch:SF 2 "x")
5107 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5108 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
3debdc1e 5109 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
9199f050
UB
5110 [(set (match_dup 2) (match_dup 1))
5111 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
bc725565 5112 "")
4fb21e90 5113
9199f050 5114(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
00188daa
UB
5115 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5116 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
27ac40e2
UB
5117 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5118 && TARGET_FISTTP
9199f050
UB
5119 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5120 && (TARGET_64BIT || <MODE>mode != DImode))
5121 && TARGET_SSE_MATH)
5122 && !(reload_completed || reload_in_progress)"
5123 "#"
5124 "&& 1"
5125 [(const_int 0)]
5126{
5127 if (memory_operand (operands[0], VOIDmode))
5128 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5129 else
5130 {
ff680eb1 5131 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
9199f050
UB
5132 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5133 operands[1],
5134 operands[2]));
5135 }
5136 DONE;
5137}
5138 [(set_attr "type" "fisttp")
5139 (set_attr "mode" "<MODE>")])
22fb740d 5140
9199f050
UB
5141(define_insn "fix_trunc<mode>_i387_fisttp"
5142 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5143 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5144 (clobber (match_scratch:XF 2 "=&1f"))]
27ac40e2
UB
5145 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5146 && TARGET_FISTTP
9199f050
UB
5147 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5148 && (TARGET_64BIT || <MODE>mode != DImode))
5149 && TARGET_SSE_MATH)"
5150 "* return output_fix_trunc (insn, operands, 1);"
5151 [(set_attr "type" "fisttp")
5152 (set_attr "mode" "<MODE>")])
46d21d2c 5153
9199f050
UB
5154(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5155 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5156 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
73e8165a 5157 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
9199f050 5158 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
27ac40e2
UB
5159 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5160 && TARGET_FISTTP
9199f050
UB
5161 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5162 && (TARGET_64BIT || <MODE>mode != DImode))
5163 && TARGET_SSE_MATH)"
5164 "#"
5165 [(set_attr "type" "fisttp")
5166 (set_attr "mode" "<MODE>")])
2b589241 5167
9199f050
UB
5168(define_split
5169 [(set (match_operand:X87MODEI 0 "register_operand" "")
5170 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5171 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5172 (clobber (match_scratch 3 ""))]
5173 "reload_completed"
5174 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5175 (clobber (match_dup 3))])
5176 (set (match_dup 0) (match_dup 2))]
22fb740d 5177 "")
46d21d2c 5178
9199f050
UB
5179(define_split
5180 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5181 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5182 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5183 (clobber (match_scratch 3 ""))]
5184 "reload_completed"
5185 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5186 (clobber (match_dup 3))])]
22fb740d
JH
5187 "")
5188
5189;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
9199f050
UB
5190;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5191;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5192;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5193;; function in i386.c.
5194(define_insn_and_split "*fix_trunc<mode>_i387_1"
00188daa
UB
5195 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5196 (fix:X87MODEI (match_operand 1 "register_operand" "")))
8bc527af 5197 (clobber (reg:CC FLAGS_REG))]
27ac40e2
UB
5198 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5199 && !TARGET_FISTTP
9199f050
UB
5200 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5201 && (TARGET_64BIT || <MODE>mode != DImode))
5202 && !(reload_completed || reload_in_progress)"
22fb740d 5203 "#"
d7518354 5204 "&& 1"
22fb740d
JH
5205 [(const_int 0)]
5206{
ff680eb1
UB
5207 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5208
5209 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5210 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
22fb740d 5211 if (memory_operand (operands[0], VOIDmode))
9199f050
UB
5212 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5213 operands[2], operands[3]));
22fb740d
JH
5214 else
5215 {
ff680eb1 5216 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
9199f050
UB
5217 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5218 operands[2], operands[3],
5219 operands[4]));
22fb740d
JH
5220 }
5221 DONE;
5222}
26f74aa3 5223 [(set_attr "type" "fistp")
edeacc14 5224 (set_attr "i387_cw" "trunc")
9199f050
UB
5225 (set_attr "mode" "<MODE>")])
5226
5227(define_insn "fix_truncdi_i387"
5228 [(set (match_operand:DI 0 "memory_operand" "=m")
5229 (fix:DI (match_operand 1 "register_operand" "f")))
5230 (use (match_operand:HI 2 "memory_operand" "m"))
5231 (use (match_operand:HI 3 "memory_operand" "m"))
5232 (clobber (match_scratch:XF 4 "=&1f"))]
27ac40e2
UB
5233 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5234 && !TARGET_FISTTP
9199f050
UB
5235 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5236 "* return output_fix_trunc (insn, operands, 0);"
5237 [(set_attr "type" "fistp")
5238 (set_attr "i387_cw" "trunc")
5239 (set_attr "mode" "DI")])
46d21d2c 5240
9199f050
UB
5241(define_insn "fix_truncdi_i387_with_temp"
5242 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5243 (fix:DI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
5244 (use (match_operand:HI 2 "memory_operand" "m,m"))
5245 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 5246 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
9199f050 5247 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
27ac40e2
UB
5248 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5249 && !TARGET_FISTTP
9199f050 5250 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
22fb740d 5251 "#"
26f74aa3 5252 [(set_attr "type" "fistp")
edeacc14 5253 (set_attr "i387_cw" "trunc")
9199f050 5254 (set_attr "mode" "DI")])
22fb740d 5255
6300f037 5256(define_split
9199f050
UB
5257 [(set (match_operand:DI 0 "register_operand" "")
5258 (fix:DI (match_operand 1 "register_operand" "")))
5259 (use (match_operand:HI 2 "memory_operand" ""))
5260 (use (match_operand:HI 3 "memory_operand" ""))
5261 (clobber (match_operand:DI 4 "memory_operand" ""))
5262 (clobber (match_scratch 5 ""))]
5263 "reload_completed"
5264 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5265 (use (match_dup 2))
5266 (use (match_dup 3))
5267 (clobber (match_dup 5))])
5268 (set (match_dup 0) (match_dup 4))]
5269 "")
5270
6300f037 5271(define_split
9199f050
UB
5272 [(set (match_operand:DI 0 "memory_operand" "")
5273 (fix:DI (match_operand 1 "register_operand" "")))
5274 (use (match_operand:HI 2 "memory_operand" ""))
5275 (use (match_operand:HI 3 "memory_operand" ""))
5276 (clobber (match_operand:DI 4 "memory_operand" ""))
5277 (clobber (match_scratch 5 ""))]
5278 "reload_completed"
5279 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5280 (use (match_dup 2))
5281 (use (match_dup 3))
5282 (clobber (match_dup 5))])]
5283 "")
5284
5285(define_insn "fix_trunc<mode>_i387"
5286 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5287 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
22fb740d
JH
5288 (use (match_operand:HI 2 "memory_operand" "m"))
5289 (use (match_operand:HI 3 "memory_operand" "m"))]
27ac40e2
UB
5290 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5291 && !TARGET_FISTTP
22fb740d 5292 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
9199f050 5293 "* return output_fix_trunc (insn, operands, 0);"
26f74aa3 5294 [(set_attr "type" "fistp")
edeacc14 5295 (set_attr "i387_cw" "trunc")
9199f050
UB
5296 (set_attr "mode" "<MODE>")])
5297
5298(define_insn "fix_trunc<mode>_i387_with_temp"
5299 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5300 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5301 (use (match_operand:HI 2 "memory_operand" "m,m"))
5302 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 5303 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
27ac40e2
UB
5304 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5305 && !TARGET_FISTTP
9199f050
UB
5306 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5307 "#"
5308 [(set_attr "type" "fistp")
5309 (set_attr "i387_cw" "trunc")
5310 (set_attr "mode" "<MODE>")])
22fb740d 5311
6300f037 5312(define_split
9199f050
UB
5313 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5314 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
22fb740d
JH
5315 (use (match_operand:HI 2 "memory_operand" ""))
5316 (use (match_operand:HI 3 "memory_operand" ""))
9199f050 5317 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
22fb740d 5318 "reload_completed"
9199f050 5319 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
22fb740d 5320 (use (match_dup 2))
9199f050
UB
5321 (use (match_dup 3))])
5322 (set (match_dup 0) (match_dup 4))]
22fb740d 5323 "")
46d21d2c 5324
6300f037 5325(define_split
9199f050
UB
5326 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5327 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
7a2e09f4
JH
5328 (use (match_operand:HI 2 "memory_operand" ""))
5329 (use (match_operand:HI 3 "memory_operand" ""))
9199f050 5330 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
46d21d2c 5331 "reload_completed"
9199f050 5332 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
7a2e09f4 5333 (use (match_dup 2))
9199f050 5334 (use (match_dup 3))])]
46d21d2c
JW
5335 "")
5336
e075ae69 5337(define_insn "x86_fnstcw_1"
c76aab11 5338 [(set (match_operand:HI 0 "memory_operand" "=m")
03c259ad 5339 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
e1f998ad 5340 "TARGET_80387"
0f40f9f7 5341 "fnstcw\t%0"
725fd454 5342 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
6ef67412 5343 (set_attr "mode" "HI")
56bab446 5344 (set_attr "unit" "i387")])
bc725565 5345
e075ae69 5346(define_insn "x86_fldcw_1"
03c259ad 5347 [(set (reg:HI FPCR_REG)
8ee41eaf 5348 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
bc725565 5349 "TARGET_80387"
0f40f9f7 5350 "fldcw\t%0"
725fd454 5351 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
6ef67412 5352 (set_attr "mode" "HI")
3d34cd91 5353 (set_attr "unit" "i387")
21efb4d4 5354 (set_attr "athlon_decode" "vector")
4f3f76e6 5355 (set_attr "amdfam10_decode" "vector")])
e075ae69
RH
5356\f
5357;; Conversion between fixed point and floating point.
886c62d1 5358
e075ae69
RH
5359;; Even though we only accept memory inputs, the backend _really_
5360;; wants to be able to do this between registers.
5361
0218c012 5362(define_expand "floathi<mode>2"
380edc9f
UB
5363 [(set (match_operand:X87MODEF 0 "register_operand" "")
5364 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5365 "TARGET_80387
5366 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5367 || TARGET_MIX_SSE_I387)"
5368 "")
35c28a13 5369
380edc9f
UB
5370;; Pre-reload splitter to add memory clobber to the pattern.
5371(define_insn_and_split "*floathi<mode>2_1"
5372 [(set (match_operand:X87MODEF 0 "register_operand" "")
5373 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5374 "TARGET_80387
5375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5376 || TARGET_MIX_SSE_I387)
5377 && !(reload_completed || reload_in_progress)"
5378 "#"
5379 "&& 1"
5380 [(parallel [(set (match_dup 0)
5381 (float:X87MODEF (match_dup 1)))
5382 (clobber (match_dup 2))])]
5383 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5384
5385(define_insn "*floathi<mode>2_i387_with_temp"
5386 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5387 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5388 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
0218c012
UB
5389 "TARGET_80387
5390 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5391 || TARGET_MIX_SSE_I387)"
380edc9f 5392 "#"
155d8a47 5393 [(set_attr "type" "fmov,multi")
0218c012 5394 (set_attr "mode" "<MODE>")
af12f8ea 5395 (set_attr "unit" "*,i387")
155d8a47
JW
5396 (set_attr "fp_int_src" "true")])
5397
380edc9f
UB
5398(define_insn "*floathi<mode>2_i387"
5399 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5400 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5401 "TARGET_80387
5402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5403 || TARGET_MIX_SSE_I387)"
a3a5e3d1 5404 "fild%Z1\t%1"
380edc9f
UB
5405 [(set_attr "type" "fmov")
5406 (set_attr "mode" "<MODE>")
630ecd8d
JH
5407 (set_attr "fp_int_src" "true")])
5408
4f3f76e6 5409(define_split
380edc9f
UB
5410 [(set (match_operand:X87MODEF 0 "register_operand" "")
5411 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5412 (clobber (match_operand:HI 2 "memory_operand" ""))]
5413 "TARGET_80387
5414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5415 || TARGET_MIX_SSE_I387)
5416 && reload_completed"
5417 [(set (match_dup 2) (match_dup 1))
5418 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5419 "")
4845dbb5 5420
4f3f76e6 5421(define_split
380edc9f
UB
5422 [(set (match_operand:X87MODEF 0 "register_operand" "")
5423 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5424 (clobber (match_operand:HI 2 "memory_operand" ""))]
5425 "TARGET_80387
5426 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5427 || TARGET_MIX_SSE_I387)
5428 && reload_completed"
5429 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5430 "")
4845dbb5 5431
380edc9f
UB
5432(define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5433 [(set (match_operand:X87MODEF 0 "register_operand" "")
5434 (float:X87MODEF
5435 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5436 "TARGET_80387
5437 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5438 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
8ce94e44
JM
5439 "
5440{
5441 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5442 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5443 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5444 {
5445 rtx reg = gen_reg_rtx (XFmode);
5446 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5447/* Avoid references to nonexistent function in dead code in XFmode case. */
5448#define gen_truncxfxf2 gen_truncxfdf2
5449 emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5450#undef gen_truncxfxf2
5451 DONE;
5452 }
5453}")
bc725565 5454
380edc9f
UB
5455;; Pre-reload splitter to add memory clobber to the pattern.
5456(define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5457 [(set (match_operand:X87MODEF 0 "register_operand" "")
5458 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5459 "((TARGET_80387
8ce94e44 5460 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
380edc9f
UB
5461 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5462 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5463 || TARGET_MIX_SSE_I387))
5464 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5465 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5466 && ((<SSEMODEI24:MODE>mode == SImode
3debdc1e
JH
5467 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5468 && optimize_function_for_speed_p (cfun)
380edc9f 5469 && flag_trapping_math)
3debdc1e
JH
5470 || !(TARGET_INTER_UNIT_CONVERSIONS
5471 || optimize_function_for_size_p (cfun)))))
380edc9f
UB
5472 && !(reload_completed || reload_in_progress)"
5473 "#"
5474 "&& 1"
5475 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5476 (clobber (match_dup 2))])]
7b198002
UB
5477{
5478 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5479
5480 /* Avoid store forwarding (partial memory) stall penalty
5481 by passing DImode value through XMM registers. */
1ffcdc02
L
5482 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5483 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
3debdc1e 5484 && optimize_function_for_speed_p (cfun))
7b198002
UB
5485 {
5486 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5487 operands[1],
5488 operands[2]));
5489 DONE;
5490 }
5491})
630ecd8d 5492
380edc9f
UB
5493(define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5494 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5495 (float:MODEF
5496 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
73e8165a 5497 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4845dbb5 5498 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3debdc1e 5499 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
380edc9f 5500 "#"
4845dbb5 5501 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
380edc9f 5502 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4845dbb5
JH
5503 (set_attr "unit" "*,i387,*,*,*")
5504 (set_attr "athlon_decode" "*,*,double,direct,double")
5505 (set_attr "amdfam10_decode" "*,*,vector,double,double")
380edc9f 5506 (set_attr "fp_int_src" "true")])
4845dbb5 5507
380edc9f
UB
5508(define_insn "*floatsi<mode>2_vector_mixed"
5509 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5510 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
630ecd8d 5511 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3debdc1e 5512 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
630ecd8d 5513 "@
a3a5e3d1 5514 fild%Z1\t%1
380edc9f 5515 #"
630ecd8d 5516 [(set_attr "type" "fmov,sseicvt")
380edc9f
UB
5517 (set_attr "mode" "<MODE>,<ssevecmode>")
5518 (set_attr "unit" "i387,*")
630ecd8d
JH
5519 (set_attr "athlon_decode" "*,direct")
5520 (set_attr "amdfam10_decode" "*,double")
5521 (set_attr "fp_int_src" "true")])
5522
380edc9f
UB
5523(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5524 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5525 (float:MODEF
5526 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
73e8165a 5527 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
380edc9f
UB
5528 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5529 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5530 "#"
5531 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5532 (set_attr "mode" "<MODEF:MODE>")
5533 (set_attr "unit" "*,i387,*,*")
5534 (set_attr "athlon_decode" "*,*,double,direct")
5535 (set_attr "amdfam10_decode" "*,*,vector,double")
0218c012
UB
5536 (set_attr "fp_int_src" "true")])
5537
4f3f76e6 5538(define_split
380edc9f
UB
5539 [(set (match_operand:MODEF 0 "register_operand" "")
5540 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5541 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5542 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5543 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5544 && TARGET_INTER_UNIT_CONVERSIONS
5545 && reload_completed
5546 && (SSE_REG_P (operands[0])
5547 || (GET_CODE (operands[0]) == SUBREG
5548 && SSE_REG_P (operands[0])))"
5549 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5550 "")
0218c012 5551
380edc9f
UB
5552(define_split
5553 [(set (match_operand:MODEF 0 "register_operand" "")
5554 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5555 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5556 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5557 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
3debdc1e 5558 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
380edc9f
UB
5559 && reload_completed
5560 && (SSE_REG_P (operands[0])
5561 || (GET_CODE (operands[0]) == SUBREG
5562 && SSE_REG_P (operands[0])))"
5563 [(set (match_dup 2) (match_dup 1))
5564 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5565 "")
630ecd8d 5566
380edc9f
UB
5567(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5568 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
00188daa 5569 (float:MODEF
0d5fd2b8 5570 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
380edc9f
UB
5571 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5572 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
3debdc1e 5573 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
e075ae69 5574 "@
a3a5e3d1 5575 fild%Z1\t%1
95879c72
L
5576 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5577 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
380edc9f 5578 [(set_attr "type" "fmov,sseicvt,sseicvt")
95879c72 5579 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
380edc9f 5580 (set_attr "mode" "<MODEF:MODE>")
a952487c
JJ
5581 (set (attr "prefix_rex")
5582 (if_then_else
5583 (and (eq_attr "prefix" "maybe_vex")
5584 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5585 (const_string "1")
5586 (const_string "*")))
380edc9f
UB
5587 (set_attr "unit" "i387,*,*")
5588 (set_attr "athlon_decode" "*,double,direct")
5589 (set_attr "amdfam10_decode" "*,vector,double")
46ed7963
JH
5590 (set_attr "fp_int_src" "true")])
5591
380edc9f
UB
5592(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5593 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5594 (float:MODEF
5595 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5596 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5597 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
3debdc1e 5598 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
630ecd8d 5599 "@
a3a5e3d1 5600 fild%Z1\t%1
95879c72 5601 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
630ecd8d 5602 [(set_attr "type" "fmov,sseicvt")
95879c72 5603 (set_attr "prefix" "orig,maybe_vex")
380edc9f 5604 (set_attr "mode" "<MODEF:MODE>")
a952487c
JJ
5605 (set (attr "prefix_rex")
5606 (if_then_else
5607 (and (eq_attr "prefix" "maybe_vex")
5608 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5609 (const_string "1")
5610 (const_string "*")))
380edc9f 5611 (set_attr "athlon_decode" "*,direct")
630ecd8d
JH
5612 (set_attr "amdfam10_decode" "*,double")
5613 (set_attr "fp_int_src" "true")])
5614
380edc9f
UB
5615(define_insn "*floatsi<mode>2_vector_sse_with_temp"
5616 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5617 (float:MODEF
5618 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
73e8165a 5619 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
380edc9f 5620 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5621 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
380edc9f 5622 "#"
f56e86bd 5623 [(set_attr "type" "sseicvt")
380edc9f
UB
5624 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5625 (set_attr "athlon_decode" "double,direct,double")
5626 (set_attr "amdfam10_decode" "vector,double,double")
e075ae69 5627 (set_attr "fp_int_src" "true")])
bc725565 5628
380edc9f
UB
5629(define_insn "*floatsi<mode>2_vector_sse"
5630 [(set (match_operand:MODEF 0 "register_operand" "=x")
5631 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5632 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5633 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
380edc9f 5634 "#"
630ecd8d 5635 [(set_attr "type" "sseicvt")
380edc9f
UB
5636 (set_attr "mode" "<MODE>")
5637 (set_attr "athlon_decode" "direct")
630ecd8d
JH
5638 (set_attr "amdfam10_decode" "double")
5639 (set_attr "fp_int_src" "true")])
5640
380edc9f
UB
5641(define_split
5642 [(set (match_operand:MODEF 0 "register_operand" "")
5643 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5644 (clobber (match_operand:SI 2 "memory_operand" ""))]
5645 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5646 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
380edc9f
UB
5647 && reload_completed
5648 && (SSE_REG_P (operands[0])
5649 || (GET_CODE (operands[0]) == SUBREG
5650 && SSE_REG_P (operands[0])))"
5651 [(const_int 0)]
ebff937c 5652{
380edc9f
UB
5653 rtx op1 = operands[1];
5654
5655 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5656 <MODE>mode, 0);
5657 if (GET_CODE (op1) == SUBREG)
5658 op1 = SUBREG_REG (op1);
5659
5660 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
ebff937c 5661 {
380edc9f
UB
5662 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5663 emit_insn (gen_sse2_loadld (operands[4],
5664 CONST0_RTX (V4SImode), operands[1]));
ebff937c 5665 }
380edc9f
UB
5666 /* We can ignore possible trapping value in the
5667 high part of SSE register for non-trapping math. */
5668 else if (SSE_REG_P (op1) && !flag_trapping_math)
5669 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5670 else
630ecd8d 5671 {
380edc9f
UB
5672 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5673 emit_move_insn (operands[2], operands[1]);
5674 emit_insn (gen_sse2_loadld (operands[4],
5675 CONST0_RTX (V4SImode), operands[2]));
630ecd8d 5676 }
380edc9f
UB
5677 emit_insn
5678 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5679 DONE;
ebff937c 5680})
da8947b0 5681
380edc9f
UB
5682(define_split
5683 [(set (match_operand:MODEF 0 "register_operand" "")
5684 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5685 (clobber (match_operand:SI 2 "memory_operand" ""))]
5686 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5687 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
380edc9f
UB
5688 && reload_completed
5689 && (SSE_REG_P (operands[0])
5690 || (GET_CODE (operands[0]) == SUBREG
5691 && SSE_REG_P (operands[0])))"
5692 [(const_int 0)]
5693{
5694 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5695 <MODE>mode, 0);
5696 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5697
5698 emit_insn (gen_sse2_loadld (operands[4],
5699 CONST0_RTX (V4SImode), operands[1]));
5700 emit_insn
5701 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5702 DONE;
5703})
46ed7963 5704
380edc9f
UB
5705(define_split
5706 [(set (match_operand:MODEF 0 "register_operand" "")
5707 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5708 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5709 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
380edc9f
UB
5710 && reload_completed
5711 && (SSE_REG_P (operands[0])
5712 || (GET_CODE (operands[0]) == SUBREG
5713 && SSE_REG_P (operands[0])))"
5714 [(const_int 0)]
5715{
5716 rtx op1 = operands[1];
5717
5718 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5719 <MODE>mode, 0);
5720 if (GET_CODE (op1) == SUBREG)
5721 op1 = SUBREG_REG (op1);
5722
5723 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5724 {
5725 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5726 emit_insn (gen_sse2_loadld (operands[4],
5727 CONST0_RTX (V4SImode), operands[1]));
5728 }
5729 /* We can ignore possible trapping value in the
5730 high part of SSE register for non-trapping math. */
5731 else if (SSE_REG_P (op1) && !flag_trapping_math)
5732 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5733 else
5734 gcc_unreachable ();
ddd5eeb1
L
5735 emit_insn
5736 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5737 DONE;
380edc9f
UB
5738})
5739
5740(define_split
5741 [(set (match_operand:MODEF 0 "register_operand" "")
5742 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5743 "TARGET_SSE2 && TARGET_SSE_MATH
3debdc1e 5744 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
380edc9f
UB
5745 && reload_completed
5746 && (SSE_REG_P (operands[0])
5747 || (GET_CODE (operands[0]) == SUBREG
5748 && SSE_REG_P (operands[0])))"
5749 [(const_int 0)]
5750{
5751 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5752 <MODE>mode, 0);
5753 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5754
5755 emit_insn (gen_sse2_loadld (operands[4],
5756 CONST0_RTX (V4SImode), operands[1]));
5757 emit_insn
5758 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5759 DONE;
5760})
5761
5762(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5763 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5764 (float:MODEF
5765 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
73e8165a 5766 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
380edc9f
UB
5767 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5768 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5769 "#"
5770 [(set_attr "type" "sseicvt")
5771 (set_attr "mode" "<MODEF:MODE>")
5772 (set_attr "athlon_decode" "double,direct")
5773 (set_attr "amdfam10_decode" "vector,double")
630ecd8d
JH
5774 (set_attr "fp_int_src" "true")])
5775
380edc9f
UB
5776(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5777 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5778 (float:MODEF
5779 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5780 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5781 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
3debdc1e 5782 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
95879c72 5783 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
f56e86bd 5784 [(set_attr "type" "sseicvt")
95879c72 5785 (set_attr "prefix" "maybe_vex")
380edc9f 5786 (set_attr "mode" "<MODEF:MODE>")
a952487c
JJ
5787 (set (attr "prefix_rex")
5788 (if_then_else
5789 (and (eq_attr "prefix" "maybe_vex")
5790 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5791 (const_string "1")
5792 (const_string "*")))
f56e86bd 5793 (set_attr "athlon_decode" "double,direct")
21efb4d4 5794 (set_attr "amdfam10_decode" "vector,double")
e075ae69 5795 (set_attr "fp_int_src" "true")])
bc725565 5796
380edc9f
UB
5797(define_split
5798 [(set (match_operand:MODEF 0 "register_operand" "")
5799 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5800 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5801 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5802 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
3debdc1e 5803 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
380edc9f
UB
5804 && reload_completed
5805 && (SSE_REG_P (operands[0])
5806 || (GET_CODE (operands[0]) == SUBREG
5807 && SSE_REG_P (operands[0])))"
5808 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5809 "")
5810
5811(define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5812 [(set (match_operand:MODEF 0 "register_operand" "=x")
5813 (float:MODEF
5814 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5815 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5816 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
3debdc1e 5817 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
95879c72 5818 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
630ecd8d 5819 [(set_attr "type" "sseicvt")
95879c72 5820 (set_attr "prefix" "maybe_vex")
380edc9f 5821 (set_attr "mode" "<MODEF:MODE>")
a952487c
JJ
5822 (set (attr "prefix_rex")
5823 (if_then_else
5824 (and (eq_attr "prefix" "maybe_vex")
5825 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5826 (const_string "1")
5827 (const_string "*")))
630ecd8d
JH
5828 (set_attr "athlon_decode" "direct")
5829 (set_attr "amdfam10_decode" "double")
5830 (set_attr "fp_int_src" "true")])
5831
380edc9f
UB
5832(define_split
5833 [(set (match_operand:MODEF 0 "register_operand" "")
5834 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5835 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5836 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5837 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
3debdc1e 5838 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
380edc9f
UB
5839 && reload_completed
5840 && (SSE_REG_P (operands[0])
5841 || (GET_CODE (operands[0]) == SUBREG
5842 && SSE_REG_P (operands[0])))"
5843 [(set (match_dup 2) (match_dup 1))
5844 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5845 "")
5846
5847(define_split
5848 [(set (match_operand:MODEF 0 "register_operand" "")
5849 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5850 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5851 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5852 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5853 && reload_completed
5854 && (SSE_REG_P (operands[0])
5855 || (GET_CODE (operands[0]) == SUBREG
5856 && SSE_REG_P (operands[0])))"
5857 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5858 "")
5859
5860(define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5861 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5862 (float:X87MODEF
5863 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
73e8165a 5864 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
8ce94e44
JM
5865 "TARGET_80387
5866 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
2b589241 5867 "@
a3a5e3d1 5868 fild%Z1\t%1
2b589241
JH
5869 #"
5870 [(set_attr "type" "fmov,multi")
380edc9f 5871 (set_attr "mode" "<X87MODEF:MODE>")
af12f8ea 5872 (set_attr "unit" "*,i387")
2b589241
JH
5873 (set_attr "fp_int_src" "true")])
5874
380edc9f
UB
5875(define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5876 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5877 (float:X87MODEF
5878 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
8ce94e44
JM
5879 "TARGET_80387
5880 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
a3a5e3d1 5881 "fild%Z1\t%1"
380edc9f
UB
5882 [(set_attr "type" "fmov")
5883 (set_attr "mode" "<X87MODEF:MODE>")
2b589241
JH
5884 (set_attr "fp_int_src" "true")])
5885
155d8a47 5886(define_split
380edc9f
UB
5887 [(set (match_operand:X87MODEF 0 "register_operand" "")
5888 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5889 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5890 "TARGET_80387
8ce94e44 5891 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
380edc9f
UB
5892 && reload_completed
5893 && FP_REG_P (operands[0])"
5894 [(set (match_dup 2) (match_dup 1))
5895 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5896 "")
5897
5898(define_split
5899 [(set (match_operand:X87MODEF 0 "register_operand" "")
5900 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5901 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5902 "TARGET_80387
8ce94e44 5903 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
380edc9f
UB
5904 && reload_completed
5905 && FP_REG_P (operands[0])"
5906 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5907 "")
8d705469 5908
7b198002
UB
5909;; Avoid store forwarding (partial memory) stall penalty
5910;; by passing DImode value through XMM registers. */
5911
5912(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5913 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5914 (float:X87MODEF
5915 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
73e8165a
UB
5916 (clobber (match_scratch:V4SI 3 "=X,x"))
5917 (clobber (match_scratch:V4SI 4 "=X,x"))
5918 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
8ce94e44
JM
5919 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5920 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
3debdc1e 5921 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
7b198002
UB
5922 "#"
5923 [(set_attr "type" "multi")
5924 (set_attr "mode" "<X87MODEF:MODE>")
5925 (set_attr "unit" "i387")
5926 (set_attr "fp_int_src" "true")])
5927
5928(define_split
5929 [(set (match_operand:X87MODEF 0 "register_operand" "")
5930 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
e356fac8
UB
5931 (clobber (match_scratch:V4SI 3 ""))
5932 (clobber (match_scratch:V4SI 4 ""))
7b198002 5933 (clobber (match_operand:DI 2 "memory_operand" ""))]
8ce94e44
JM
5934 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5935 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
3debdc1e 5936 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
7b198002
UB
5937 && reload_completed
5938 && FP_REG_P (operands[0])"
5939 [(set (match_dup 2) (match_dup 3))
5940 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5941{
5942 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5943 Assemble the 64-bit DImode value in an xmm register. */
5944 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5945 gen_rtx_SUBREG (SImode, operands[1], 0)));
5946 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5947 gen_rtx_SUBREG (SImode, operands[1], 4)));
5948 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5949
5950 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5951})
5952
5953(define_split
5954 [(set (match_operand:X87MODEF 0 "register_operand" "")
5955 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
e356fac8
UB
5956 (clobber (match_scratch:V4SI 3 ""))
5957 (clobber (match_scratch:V4SI 4 ""))
5958 (clobber (match_operand:DI 2 "memory_operand" ""))]
8ce94e44
JM
5959 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5960 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
3debdc1e 5961 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
7b198002
UB
5962 && reload_completed
5963 && FP_REG_P (operands[0])"
5964 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5965 "")
5966
7fb1431b
UB
5967;; Avoid store forwarding (partial memory) stall penalty by extending
5968;; SImode value to DImode through XMM register instead of pushing two
5969;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5970;; targets benefit from this optimization. Also note that fild
5971;; loads from memory only.
5972
5973(define_insn "*floatunssi<mode>2_1"
5974 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5975 (unsigned_float:X87MODEF
5976 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5977 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5978 (clobber (match_scratch:SI 3 "=X,x"))]
5979 "!TARGET_64BIT
8f612190 5980 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
8ce94e44 5981 && TARGET_SSE"
7fb1431b
UB
5982 "#"
5983 [(set_attr "type" "multi")
5984 (set_attr "mode" "<MODE>")])
5985
5986(define_split
5987 [(set (match_operand:X87MODEF 0 "register_operand" "")
5988 (unsigned_float:X87MODEF
5989 (match_operand:SI 1 "register_operand" "")))
5990 (clobber (match_operand:DI 2 "memory_operand" ""))
5991 (clobber (match_scratch:SI 3 ""))]
5992 "!TARGET_64BIT
8f612190 5993 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
8ce94e44 5994 && TARGET_SSE
7fb1431b
UB
5995 && reload_completed"
5996 [(set (match_dup 2) (match_dup 1))
5997 (set (match_dup 0)
5998 (float:X87MODEF (match_dup 2)))]
5999 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
6000
6001(define_split
6002 [(set (match_operand:X87MODEF 0 "register_operand" "")
6003 (unsigned_float:X87MODEF
6004 (match_operand:SI 1 "memory_operand" "")))
6005 (clobber (match_operand:DI 2 "memory_operand" ""))
6006 (clobber (match_scratch:SI 3 ""))]
6007 "!TARGET_64BIT
8f612190 6008 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
8ce94e44 6009 && TARGET_SSE
7fb1431b
UB
6010 && reload_completed"
6011 [(set (match_dup 2) (match_dup 3))
6012 (set (match_dup 0)
6013 (float:X87MODEF (match_dup 2)))]
6014{
6015 emit_move_insn (operands[3], operands[1]);
6016 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
6017})
6018
def7425b 6019(define_expand "floatunssi<mode>2"
7fb1431b
UB
6020 [(parallel
6021 [(set (match_operand:X87MODEF 0 "register_operand" "")
6022 (unsigned_float:X87MODEF
6023 (match_operand:SI 1 "nonimmediate_operand" "")))
6024 (clobber (match_dup 2))
6025 (clobber (match_scratch:SI 3 ""))])]
6026 "!TARGET_64BIT
8f612190 6027 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
8ce94e44 6028 && TARGET_SSE)
7fb1431b 6029 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
ebff937c 6030{
7fb1431b
UB
6031 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6032 {
6033 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6034 DONE;
6035 }
6036 else
6037 {
bbbbb16a
ILT
6038 enum ix86_stack_slot slot = (virtuals_instantiated
6039 ? SLOT_TEMP
6040 : SLOT_VIRTUAL);
7fb1431b
UB
6041 operands[2] = assign_386_stack_local (DImode, slot);
6042 }
ebff937c
SH
6043})
6044
8d705469
JH
6045(define_expand "floatunsdisf2"
6046 [(use (match_operand:SF 0 "register_operand" ""))
ebff937c 6047 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
da8947b0 6048 "TARGET_64BIT && TARGET_SSE_MATH"
8d705469
JH
6049 "x86_emit_floatuns (operands); DONE;")
6050
6051(define_expand "floatunsdidf2"
6052 [(use (match_operand:DF 0 "register_operand" ""))
ebff937c 6053 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
def7425b
UB
6054 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6055 && TARGET_SSE2 && TARGET_SSE_MATH"
ebff937c
SH
6056{
6057 if (TARGET_64BIT)
6058 x86_emit_floatuns (operands);
6059 else
6060 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6061 DONE;
6062})
997404de 6063\f
e075ae69 6064;; Add instructions
53b5ce19 6065
28356f52
JB
6066;; %%% splits for addditi3
6067
6068(define_expand "addti3"
6069 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6070 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7ae14d31 6071 (match_operand:TI 2 "x86_64_general_operand" "")))]
28356f52
JB
6072 "TARGET_64BIT"
6073 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
6074
6075(define_insn "*addti3_1"
6076 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6077 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
68b8830a 6078 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
28356f52
JB
6079 (clobber (reg:CC FLAGS_REG))]
6080 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
6081 "#")
6082
6083(define_split
6084 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6085 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
68b8830a 6086 (match_operand:TI 2 "x86_64_general_operand" "")))
28356f52
JB
6087 (clobber (reg:CC FLAGS_REG))]
6088 "TARGET_64BIT && reload_completed"
6089 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6090 UNSPEC_ADD_CARRY))
6091 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
6092 (parallel [(set (match_dup 3)
6093 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6094 (match_dup 4))
6095 (match_dup 5)))
6096 (clobber (reg:CC FLAGS_REG))])]
c2b814b9 6097 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
28356f52 6098
e075ae69
RH
6099;; %%% splits for addsidi3
6100; [(set (match_operand:DI 0 "nonimmediate_operand" "")
6101; (plus:DI (match_operand:DI 1 "general_operand" "")
6102; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
e1f998ad 6103
9b70259d
JH
6104(define_expand "adddi3"
6105 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6106 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7ae14d31 6107 (match_operand:DI 2 "x86_64_general_operand" "")))]
9b70259d
JH
6108 ""
6109 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
6110
6111(define_insn "*adddi3_1"
e075ae69
RH
6112 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6113 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6114 (match_operand:DI 2 "general_operand" "roiF,riF")))
8bc527af 6115 (clobber (reg:CC FLAGS_REG))]
c15c18c5 6116 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
bc725565
JW
6117 "#")
6118
6119(define_split
e075ae69 6120 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4cbfbb1b 6121 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
e075ae69 6122 (match_operand:DI 2 "general_operand" "")))
8bc527af 6123 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 6124 "!TARGET_64BIT && reload_completed"
8bc527af 6125 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
8ee41eaf 6126 UNSPEC_ADD_CARRY))
e075ae69
RH
6127 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
6128 (parallel [(set (match_dup 3)
8bc527af 6129 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9dcbdc7e
JH
6130 (match_dup 4))
6131 (match_dup 5)))
8bc527af 6132 (clobber (reg:CC FLAGS_REG))])]
c2b814b9 6133 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
e075ae69 6134
7b52eede 6135(define_insn "adddi3_carry_rex64"
9b70259d 6136 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
e6e81735 6137 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
9b70259d
JH
6138 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
6139 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8bc527af 6140 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 6141 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
0f40f9f7 6142 "adc{q}\t{%2, %0|%0, %2}"
9b70259d 6143 [(set_attr "type" "alu")
b6837b94 6144 (set_attr "use_carry" "1")
9b70259d 6145 (set_attr "pent_pair" "pu")
56bab446 6146 (set_attr "mode" "DI")])
9b70259d
JH
6147
6148(define_insn "*adddi3_cc_rex64"
8bc527af 6149 [(set (reg:CC FLAGS_REG)
8ee41eaf
RH
6150 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
6151 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
6152 UNSPEC_ADD_CARRY))
9b70259d
JH
6153 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6154 (plus:DI (match_dup 1) (match_dup 2)))]
6155 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
0f40f9f7 6156 "add{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6157 [(set_attr "type" "alu")
6158 (set_attr "mode" "DI")])
6159
d1c3b587 6160(define_insn "*<plusminus_insn><mode>3_cc_overflow"
d39d658d
RIL
6161 [(set (reg:CCC FLAGS_REG)
6162 (compare:CCC
6163 (plusminus:SWI
6164 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6165 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6166 (match_dup 1)))
6167 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6168 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6169 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
d1c3b587 6170 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
d39d658d
RIL
6171 [(set_attr "type" "alu")
6172 (set_attr "mode" "<MODE>")])
6173
6174(define_insn "*add<mode>3_cconly_overflow"
6175 [(set (reg:CCC FLAGS_REG)
6176 (compare:CCC
6177 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
6178 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6179 (match_dup 1)))
6180 (clobber (match_scratch:SWI 0 "=<r>"))]
6181 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6182 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6183 [(set_attr "type" "alu")
6184 (set_attr "mode" "<MODE>")])
6185
6186(define_insn "*sub<mode>3_cconly_overflow"
6187 [(set (reg:CCC FLAGS_REG)
6188 (compare:CCC
6189 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6190 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6191 (match_dup 0)))]
6192 ""
6193 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6194 [(set_attr "type" "icmp")
6195 (set_attr "mode" "<MODE>")])
6196
d1c3b587 6197(define_insn "*<plusminus_insn>si3_zext_cc_overflow"
d39d658d
RIL
6198 [(set (reg:CCC FLAGS_REG)
6199 (compare:CCC
6200 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6201 (match_operand:SI 2 "general_operand" "g"))
6202 (match_dup 1)))
6203 (set (match_operand:DI 0 "register_operand" "=r")
6204 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6205 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
d1c3b587 6206 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
d39d658d
RIL
6207 [(set_attr "type" "alu")
6208 (set_attr "mode" "SI")])
6209
7b52eede 6210(define_insn "addqi3_carry"
d67e96cf 6211 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
e6e81735 6212 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7b52eede 6213 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
0edb82cb 6214 (match_operand:QI 2 "general_operand" "qn,qm")))
8bc527af 6215 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
6216 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6217 "adc{b}\t{%2, %0|%0, %2}"
6218 [(set_attr "type" "alu")
b6837b94 6219 (set_attr "use_carry" "1")
7b52eede 6220 (set_attr "pent_pair" "pu")
56bab446 6221 (set_attr "mode" "QI")])
7b52eede
JH
6222
6223(define_insn "addhi3_carry"
6224 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
e6e81735 6225 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7b52eede 6226 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
0edb82cb 6227 (match_operand:HI 2 "general_operand" "rn,rm")))
8bc527af 6228 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
6229 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6230 "adc{w}\t{%2, %0|%0, %2}"
6231 [(set_attr "type" "alu")
b6837b94 6232 (set_attr "use_carry" "1")
7b52eede 6233 (set_attr "pent_pair" "pu")
56bab446 6234 (set_attr "mode" "HI")])
7b52eede
JH
6235
6236(define_insn "addsi3_carry"
e075ae69 6237 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
e6e81735 6238 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9dcbdc7e
JH
6239 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
6240 (match_operand:SI 2 "general_operand" "ri,rm")))
8bc527af 6241 (clobber (reg:CC FLAGS_REG))]
d525dfdf 6242 "ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 6243 "adc{l}\t{%2, %0|%0, %2}"
e075ae69 6244 [(set_attr "type" "alu")
b6837b94 6245 (set_attr "use_carry" "1")
e075ae69 6246 (set_attr "pent_pair" "pu")
56bab446 6247 (set_attr "mode" "SI")])
4fb21e90 6248
9b70259d
JH
6249(define_insn "*addsi3_carry_zext"
6250 [(set (match_operand:DI 0 "register_operand" "=r")
6300f037 6251 (zero_extend:DI
e6e81735 6252 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9b70259d 6253 (match_operand:SI 1 "nonimmediate_operand" "%0"))
73f48658 6254 (match_operand:SI 2 "general_operand" "g"))))
8bc527af 6255 (clobber (reg:CC FLAGS_REG))]
9b70259d 6256 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 6257 "adc{l}\t{%2, %k0|%k0, %2}"
9b70259d 6258 [(set_attr "type" "alu")
b6837b94 6259 (set_attr "use_carry" "1")
9b70259d 6260 (set_attr "pent_pair" "pu")
56bab446 6261 (set_attr "mode" "SI")])
9b70259d 6262
7e08e190 6263(define_insn "*addsi3_cc"
8bc527af 6264 [(set (reg:CC FLAGS_REG)
8ee41eaf
RH
6265 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
6266 (match_operand:SI 2 "general_operand" "ri,rm")]
6267 UNSPEC_ADD_CARRY))
7e08e190
JH
6268 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6269 (plus:SI (match_dup 1) (match_dup 2)))]
265dab10 6270 "ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 6271 "add{l}\t{%2, %0|%0, %2}"
265dab10 6272 [(set_attr "type" "alu")
7e08e190
JH
6273 (set_attr "mode" "SI")])
6274
6275(define_insn "addqi3_cc"
8bc527af 6276 [(set (reg:CC FLAGS_REG)
8ee41eaf 6277 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
0edb82cb 6278 (match_operand:QI 2 "general_operand" "qn,qm")]
8ee41eaf 6279 UNSPEC_ADD_CARRY))
7e08e190
JH
6280 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6281 (plus:QI (match_dup 1) (match_dup 2)))]
6282 "ix86_binary_operator_ok (PLUS, QImode, operands)"
0f40f9f7 6283 "add{b}\t{%2, %0|%0, %2}"
7e08e190
JH
6284 [(set_attr "type" "alu")
6285 (set_attr "mode" "QI")])
265dab10 6286
e075ae69 6287(define_expand "addsi3"
7ae14d31
UB
6288 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6289 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6290 (match_operand:SI 2 "general_operand" "")))]
e075ae69
RH
6291 ""
6292 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
886c62d1 6293
ac62a60e 6294(define_insn "*lea_1"
e075ae69 6295 [(set (match_operand:SI 0 "register_operand" "=r")
74dc3e94 6296 (match_operand:SI 1 "no_seg_address_operand" "p"))]
ac62a60e 6297 "!TARGET_64BIT"
0f40f9f7 6298 "lea{l}\t{%a1, %0|%0, %a1}"
6ef67412
JH
6299 [(set_attr "type" "lea")
6300 (set_attr "mode" "SI")])
2ae0f82c 6301
ac62a60e
JH
6302(define_insn "*lea_1_rex64"
6303 [(set (match_operand:SI 0 "register_operand" "=r")
74dc3e94 6304 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
ac62a60e 6305 "TARGET_64BIT"
0f40f9f7 6306 "lea{l}\t{%a1, %0|%0, %a1}"
ac62a60e
JH
6307 [(set_attr "type" "lea")
6308 (set_attr "mode" "SI")])
6309
6310(define_insn "*lea_1_zext"
6311 [(set (match_operand:DI 0 "register_operand" "=r")
74dc3e94
RH
6312 (zero_extend:DI
6313 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
d4f33f6c 6314 "TARGET_64BIT"
0f40f9f7 6315 "lea{l}\t{%a1, %k0|%k0, %a1}"
ac62a60e
JH
6316 [(set_attr "type" "lea")
6317 (set_attr "mode" "SI")])
6318
6319(define_insn "*lea_2_rex64"
6320 [(set (match_operand:DI 0 "register_operand" "=r")
74dc3e94 6321 (match_operand:DI 1 "no_seg_address_operand" "p"))]
ac62a60e 6322 "TARGET_64BIT"
0f40f9f7 6323 "lea{q}\t{%a1, %0|%0, %a1}"
ac62a60e
JH
6324 [(set_attr "type" "lea")
6325 (set_attr "mode" "DI")])
6326
58787064
JH
6327;; The lea patterns for non-Pmodes needs to be matched by several
6328;; insns converted to real lea by splitters.
6329
6330(define_insn_and_split "*lea_general_1"
6331 [(set (match_operand 0 "register_operand" "=r")
9a9286af 6332 (plus (plus (match_operand 1 "index_register_operand" "l")
58787064
JH
6333 (match_operand 2 "register_operand" "r"))
6334 (match_operand 3 "immediate_operand" "i")))]
ac62a60e
JH
6335 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6336 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
3debdc1e 6337 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
58787064
JH
6338 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6339 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6340 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6341 || GET_MODE (operands[3]) == VOIDmode)"
6342 "#"
cb694d2c 6343 "&& reload_completed"
58787064 6344 [(const_int 0)]
58787064
JH
6345{
6346 rtx pat;
6347 operands[0] = gen_lowpart (SImode, operands[0]);
6348 operands[1] = gen_lowpart (Pmode, operands[1]);
6349 operands[2] = gen_lowpart (Pmode, operands[2]);
6350 operands[3] = gen_lowpart (Pmode, operands[3]);
6351 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6352 operands[3]);
6353 if (Pmode != SImode)
6354 pat = gen_rtx_SUBREG (SImode, pat, 0);
6355 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6356 DONE;
0f40f9f7 6357}
58787064
JH
6358 [(set_attr "type" "lea")
6359 (set_attr "mode" "SI")])
6360
ac62a60e
JH
6361(define_insn_and_split "*lea_general_1_zext"
6362 [(set (match_operand:DI 0 "register_operand" "=r")
6363 (zero_extend:DI
9a9286af 6364 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
ac62a60e
JH
6365 (match_operand:SI 2 "register_operand" "r"))
6366 (match_operand:SI 3 "immediate_operand" "i"))))]
6367 "TARGET_64BIT"
6368 "#"
6369 "&& reload_completed"
6370 [(set (match_dup 0)
6371 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6372 (match_dup 2))
6373 (match_dup 3)) 0)))]
ac62a60e
JH
6374{
6375 operands[1] = gen_lowpart (Pmode, operands[1]);
6376 operands[2] = gen_lowpart (Pmode, operands[2]);
6377 operands[3] = gen_lowpart (Pmode, operands[3]);
0f40f9f7 6378}
ac62a60e
JH
6379 [(set_attr "type" "lea")
6380 (set_attr "mode" "SI")])
6381
58787064
JH
6382(define_insn_and_split "*lea_general_2"
6383 [(set (match_operand 0 "register_operand" "=r")
9a9286af 6384 (plus (mult (match_operand 1 "index_register_operand" "l")
58787064
JH
6385 (match_operand 2 "const248_operand" "i"))
6386 (match_operand 3 "nonmemory_operand" "ri")))]
ac62a60e
JH
6387 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6388 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
3debdc1e 6389 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
58787064
JH
6390 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6391 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6392 || GET_MODE (operands[3]) == VOIDmode)"
6393 "#"
cb694d2c 6394 "&& reload_completed"
58787064 6395 [(const_int 0)]
58787064
JH
6396{
6397 rtx pat;
6398 operands[0] = gen_lowpart (SImode, operands[0]);
6399 operands[1] = gen_lowpart (Pmode, operands[1]);
6400 operands[3] = gen_lowpart (Pmode, operands[3]);
6401 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6402 operands[3]);
6403 if (Pmode != SImode)
6404 pat = gen_rtx_SUBREG (SImode, pat, 0);
6405 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6406 DONE;
0f40f9f7 6407}
58787064
JH
6408 [(set_attr "type" "lea")
6409 (set_attr "mode" "SI")])
6410
ac62a60e
JH
6411(define_insn_and_split "*lea_general_2_zext"
6412 [(set (match_operand:DI 0 "register_operand" "=r")
6413 (zero_extend:DI
9a9286af 6414 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
ac62a60e
JH
6415 (match_operand:SI 2 "const248_operand" "n"))
6416 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6417 "TARGET_64BIT"
6418 "#"
6419 "&& reload_completed"
6420 [(set (match_dup 0)
6421 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6422 (match_dup 2))
6423 (match_dup 3)) 0)))]
ac62a60e
JH
6424{
6425 operands[1] = gen_lowpart (Pmode, operands[1]);
6426 operands[3] = gen_lowpart (Pmode, operands[3]);
0f40f9f7 6427}
ac62a60e
JH
6428 [(set_attr "type" "lea")
6429 (set_attr "mode" "SI")])
6430
58787064
JH
6431(define_insn_and_split "*lea_general_3"
6432 [(set (match_operand 0 "register_operand" "=r")
9a9286af 6433 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
58787064
JH
6434 (match_operand 2 "const248_operand" "i"))
6435 (match_operand 3 "register_operand" "r"))
6436 (match_operand 4 "immediate_operand" "i")))]
ac62a60e
JH
6437 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6438 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
3debdc1e 6439 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
58787064
JH
6440 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6441 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6442 "#"
cb694d2c 6443 "&& reload_completed"
58787064 6444 [(const_int 0)]
58787064
JH
6445{
6446 rtx pat;
6447 operands[0] = gen_lowpart (SImode, operands[0]);
6448 operands[1] = gen_lowpart (Pmode, operands[1]);
6449 operands[3] = gen_lowpart (Pmode, operands[3]);
6450 operands[4] = gen_lowpart (Pmode, operands[4]);
6451 pat = gen_rtx_PLUS (Pmode,
6452 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6453 operands[2]),
6454 operands[3]),
6455 operands[4]);
6456 if (Pmode != SImode)
6457 pat = gen_rtx_SUBREG (SImode, pat, 0);
6458 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6459 DONE;
0f40f9f7 6460}
58787064
JH
6461 [(set_attr "type" "lea")
6462 (set_attr "mode" "SI")])
6463
ac62a60e
JH
6464(define_insn_and_split "*lea_general_3_zext"
6465 [(set (match_operand:DI 0 "register_operand" "=r")
6466 (zero_extend:DI
9a9286af
RH
6467 (plus:SI (plus:SI (mult:SI
6468 (match_operand:SI 1 "index_register_operand" "l")
6469 (match_operand:SI 2 "const248_operand" "n"))
ac62a60e
JH
6470 (match_operand:SI 3 "register_operand" "r"))
6471 (match_operand:SI 4 "immediate_operand" "i"))))]
6472 "TARGET_64BIT"
6473 "#"
6474 "&& reload_completed"
6475 [(set (match_dup 0)
6476 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6477 (match_dup 2))
6478 (match_dup 3))
6479 (match_dup 4)) 0)))]
ac62a60e
JH
6480{
6481 operands[1] = gen_lowpart (Pmode, operands[1]);
6482 operands[3] = gen_lowpart (Pmode, operands[3]);
6483 operands[4] = gen_lowpart (Pmode, operands[4]);
0f40f9f7 6484}
ac62a60e
JH
6485 [(set_attr "type" "lea")
6486 (set_attr "mode" "SI")])
6487
9b70259d 6488(define_insn "*adddi_1_rex64"
b6837b94
JY
6489 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
6490 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
6491 (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
8bc527af 6492 (clobber (reg:CC FLAGS_REG))]
9b70259d 6493 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
2ae0f82c 6494{
e075ae69 6495 switch (get_attr_type (insn))
2ae0f82c 6496 {
e075ae69
RH
6497 case TYPE_LEA:
6498 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 6499 return "lea{q}\t{%a2, %0|%0, %a2}";
2ae0f82c 6500
e075ae69 6501 case TYPE_INCDEC:
7637e42c 6502 gcc_assert (rtx_equal_p (operands[0], operands[1]));
e075ae69 6503 if (operands[2] == const1_rtx)
0f40f9f7 6504 return "inc{q}\t%0";
2ae0f82c 6505 else
7637e42c
NS
6506 {
6507 gcc_assert (operands[2] == constm1_rtx);
6508 return "dec{q}\t%0";
6509 }
2ae0f82c 6510
e075ae69 6511 default:
b6837b94
JY
6512 /* Use add as much as possible to replace lea for AGU optimization. */
6513 if (which_alternative == 2 && TARGET_OPT_AGU)
6514 return "add{q}\t{%1, %0|%0, %1}";
6515
7637e42c 6516 gcc_assert (rtx_equal_p (operands[0], operands[1]));
2ae0f82c 6517
e075ae69
RH
6518 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6519 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 6520 if (CONST_INT_P (operands[2])
ef6257cd 6521 /* Avoid overflows. */
0f40f9f7 6522 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
e075ae69
RH
6523 && (INTVAL (operands[2]) == 128
6524 || (INTVAL (operands[2]) < 0
6525 && INTVAL (operands[2]) != -128)))
6526 {
6527 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6528 return "sub{q}\t{%2, %0|%0, %2}";
e075ae69 6529 }
0f40f9f7 6530 return "add{q}\t{%2, %0|%0, %2}";
e075ae69 6531 }
0f40f9f7 6532}
e075ae69 6533 [(set (attr "type")
b6837b94
JY
6534 (cond [(and (eq_attr "alternative" "2")
6535 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
e075ae69 6536 (const_string "lea")
b6837b94
JY
6537 (eq_attr "alternative" "3")
6538 (const_string "lea")
e075ae69
RH
6539 ; Current assemblers are broken and do not allow @GOTOFF in
6540 ; ought but a memory context.
9b70259d 6541 (match_operand:DI 2 "pic_symbolic_operand" "")
e075ae69 6542 (const_string "lea")
9b70259d 6543 (match_operand:DI 2 "incdec_operand" "")
e075ae69
RH
6544 (const_string "incdec")
6545 ]
6ef67412 6546 (const_string "alu")))
a952487c
JJ
6547 (set (attr "length_immediate")
6548 (if_then_else
6549 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6550 (const_string "1")
6551 (const_string "*")))
9b70259d 6552 (set_attr "mode" "DI")])
e075ae69 6553
1c27d4b2
JH
6554;; Convert lea to the lea pattern to avoid flags dependency.
6555(define_split
9b70259d
JH
6556 [(set (match_operand:DI 0 "register_operand" "")
6557 (plus:DI (match_operand:DI 1 "register_operand" "")
6558 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
8bc527af 6559 (clobber (reg:CC FLAGS_REG))]
6ff078d4
JY
6560 "TARGET_64BIT && reload_completed
6561 && ix86_lea_for_add_ok (PLUS, insn, operands)"
9b70259d
JH
6562 [(set (match_dup 0)
6563 (plus:DI (match_dup 1)
6564 (match_dup 2)))]
6565 "")
1c27d4b2 6566
9b70259d 6567(define_insn "*adddi_2_rex64"
42fabf21 6568 [(set (reg FLAGS_REG)
16189740 6569 (compare
9b70259d
JH
6570 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6571 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6300f037 6572 (const_int 0)))
9b70259d
JH
6573 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6574 (plus:DI (match_dup 1) (match_dup 2)))]
6575 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6576 && ix86_binary_operator_ok (PLUS, DImode, operands)
e075ae69 6577 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 6578 ought but a memory context. */
e075ae69 6579 && ! pic_symbolic_operand (operands[2], VOIDmode)"
886c62d1 6580{
e075ae69 6581 switch (get_attr_type (insn))
96f218bb 6582 {
e075ae69 6583 case TYPE_INCDEC:
7637e42c 6584 gcc_assert (rtx_equal_p (operands[0], operands[1]));
e075ae69 6585 if (operands[2] == const1_rtx)
0f40f9f7 6586 return "inc{q}\t%0";
96f218bb 6587 else
7637e42c
NS
6588 {
6589 gcc_assert (operands[2] == constm1_rtx);
6590 return "dec{q}\t%0";
6591 }
96f218bb 6592
e075ae69 6593 default:
7637e42c 6594 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d 6595 /* ???? We ought to handle there the 32bit case too
5bdc5878 6596 - do we need new constraint? */
e075ae69
RH
6597 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6598 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 6599 if (CONST_INT_P (operands[2])
ef6257cd 6600 /* Avoid overflows. */
0f40f9f7 6601 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
e075ae69
RH
6602 && (INTVAL (operands[2]) == 128
6603 || (INTVAL (operands[2]) < 0
6604 && INTVAL (operands[2]) != -128)))
6605 {
6606 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6607 return "sub{q}\t{%2, %0|%0, %2}";
e075ae69 6608 }
0f40f9f7 6609 return "add{q}\t{%2, %0|%0, %2}";
9c530261 6610 }
0f40f9f7 6611}
e075ae69 6612 [(set (attr "type")
9b70259d 6613 (if_then_else (match_operand:DI 2 "incdec_operand" "")
e075ae69 6614 (const_string "incdec")
6ef67412 6615 (const_string "alu")))
a952487c
JJ
6616 (set (attr "length_immediate")
6617 (if_then_else
6618 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6619 (const_string "1")
6620 (const_string "*")))
9b70259d 6621 (set_attr "mode" "DI")])
e075ae69 6622
e74061a9 6623(define_insn "*adddi_3_rex64"
42fabf21 6624 [(set (reg FLAGS_REG)
9b70259d
JH
6625 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6626 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6627 (clobber (match_scratch:DI 0 "=r"))]
e74061a9
JH
6628 "TARGET_64BIT
6629 && ix86_match_ccmode (insn, CCZmode)
7656aee4 6630 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
d90ffc8d 6631 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 6632 ought but a memory context. */
d90ffc8d 6633 && ! pic_symbolic_operand (operands[2], VOIDmode)"
d90ffc8d
JH
6634{
6635 switch (get_attr_type (insn))
6636 {
6637 case TYPE_INCDEC:
7637e42c 6638 gcc_assert (rtx_equal_p (operands[0], operands[1]));
d90ffc8d 6639 if (operands[2] == const1_rtx)
0f40f9f7 6640 return "inc{q}\t%0";
d90ffc8d 6641 else
7637e42c
NS
6642 {
6643 gcc_assert (operands[2] == constm1_rtx);
6644 return "dec{q}\t%0";
6645 }
d90ffc8d
JH
6646
6647 default:
7637e42c 6648 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d 6649 /* ???? We ought to handle there the 32bit case too
5bdc5878 6650 - do we need new constraint? */
d90ffc8d
JH
6651 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6652 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 6653 if (CONST_INT_P (operands[2])
ef6257cd 6654 /* Avoid overflows. */
0f40f9f7 6655 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
d90ffc8d
JH
6656 && (INTVAL (operands[2]) == 128
6657 || (INTVAL (operands[2]) < 0
6658 && INTVAL (operands[2]) != -128)))
6659 {
6660 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6661 return "sub{q}\t{%2, %0|%0, %2}";
d90ffc8d 6662 }
0f40f9f7 6663 return "add{q}\t{%2, %0|%0, %2}";
d90ffc8d 6664 }
0f40f9f7 6665}
d90ffc8d 6666 [(set (attr "type")
9b70259d 6667 (if_then_else (match_operand:DI 2 "incdec_operand" "")
d90ffc8d
JH
6668 (const_string "incdec")
6669 (const_string "alu")))
a952487c
JJ
6670 (set (attr "length_immediate")
6671 (if_then_else
6672 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6673 (const_string "1")
6674 (const_string "*")))
9b70259d 6675 (set_attr "mode" "DI")])
d90ffc8d 6676
9b70259d 6677; For comparisons against 1, -1 and 128, we may generate better code
7e08e190
JH
6678; by converting cmp to add, inc or dec as done by peephole2. This pattern
6679; is matched then. We can't accept general immediate, because for
6680; case of overflows, the result is messed up.
9b70259d 6681; This pattern also don't hold of 0x8000000000000000, since the value overflows
7e08e190 6682; when negated.
d6a7951f 6683; Also carry flag is reversed compared to cmp, so this conversion is valid
7e08e190 6684; only for comparisons not depending on it.
e74061a9 6685(define_insn "*adddi_4_rex64"
42fabf21 6686 [(set (reg FLAGS_REG)
9b70259d
JH
6687 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6688 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6689 (clobber (match_scratch:DI 0 "=rm"))]
e74061a9
JH
6690 "TARGET_64BIT
6691 && ix86_match_ccmode (insn, CCGCmode)"
7e08e190
JH
6692{
6693 switch (get_attr_type (insn))
6694 {
6695 case TYPE_INCDEC:
6696 if (operands[2] == constm1_rtx)
0f40f9f7 6697 return "inc{q}\t%0";
7e08e190 6698 else
7637e42c
NS
6699 {
6700 gcc_assert (operands[2] == const1_rtx);
6701 return "dec{q}\t%0";
6702 }
e075ae69 6703
7e08e190 6704 default:
7637e42c 6705 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7e08e190
JH
6706 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6707 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6708 if ((INTVAL (operands[2]) == -128
6709 || (INTVAL (operands[2]) > 0
ef6257cd
JH
6710 && INTVAL (operands[2]) != 128))
6711 /* Avoid overflows. */
0f40f9f7
ZW
6712 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6713 return "sub{q}\t{%2, %0|%0, %2}";
7e08e190 6714 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6715 return "add{q}\t{%2, %0|%0, %2}";
7e08e190 6716 }
0f40f9f7 6717}
7e08e190 6718 [(set (attr "type")
9b70259d 6719 (if_then_else (match_operand:DI 2 "incdec_operand" "")
7e08e190
JH
6720 (const_string "incdec")
6721 (const_string "alu")))
93cac287
JJ
6722 (set (attr "length_immediate")
6723 (if_then_else
725fd454 6724 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
93cac287
JJ
6725 (const_string "1")
6726 (const_string "*")))
9b70259d 6727 (set_attr "mode" "DI")])
d90ffc8d 6728
e74061a9 6729(define_insn "*adddi_5_rex64"
42fabf21 6730 [(set (reg FLAGS_REG)
9076b9c1 6731 (compare
9b70259d
JH
6732 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6733 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6300f037 6734 (const_int 0)))
9b70259d 6735 (clobber (match_scratch:DI 0 "=r"))]
e74061a9
JH
6736 "TARGET_64BIT
6737 && ix86_match_ccmode (insn, CCGOCmode)
7656aee4 6738 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
9076b9c1 6739 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 6740 ought but a memory context. */
9076b9c1 6741 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9076b9c1
JH
6742{
6743 switch (get_attr_type (insn))
6744 {
6745 case TYPE_INCDEC:
7637e42c 6746 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9076b9c1 6747 if (operands[2] == const1_rtx)
0f40f9f7 6748 return "inc{q}\t%0";
9076b9c1 6749 else
7637e42c
NS
6750 {
6751 gcc_assert (operands[2] == constm1_rtx);
6752 return "dec{q}\t%0";
6753 }
9076b9c1
JH
6754
6755 default:
7637e42c 6756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9076b9c1
JH
6757 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6758 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 6759 if (CONST_INT_P (operands[2])
ef6257cd 6760 /* Avoid overflows. */
0f40f9f7 6761 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
9076b9c1
JH
6762 && (INTVAL (operands[2]) == 128
6763 || (INTVAL (operands[2]) < 0
6764 && INTVAL (operands[2]) != -128)))
6765 {
6766 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6767 return "sub{q}\t{%2, %0|%0, %2}";
9076b9c1 6768 }
0f40f9f7 6769 return "add{q}\t{%2, %0|%0, %2}";
9076b9c1 6770 }
0f40f9f7 6771}
9076b9c1 6772 [(set (attr "type")
9b70259d 6773 (if_then_else (match_operand:DI 2 "incdec_operand" "")
9076b9c1
JH
6774 (const_string "incdec")
6775 (const_string "alu")))
a952487c
JJ
6776 (set (attr "length_immediate")
6777 (if_then_else
6778 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6779 (const_string "1")
6780 (const_string "*")))
9b70259d 6781 (set_attr "mode" "DI")])
2ae0f82c 6782
e075ae69 6783
9b70259d 6784(define_insn "*addsi_1"
b6837b94
JY
6785 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
6786 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
6787 (match_operand:SI 2 "general_operand" "g,ri,0,li")))
8bc527af 6788 (clobber (reg:CC FLAGS_REG))]
9b70259d 6789 "ix86_binary_operator_ok (PLUS, SImode, operands)"
58787064
JH
6790{
6791 switch (get_attr_type (insn))
6792 {
6793 case TYPE_LEA:
9b70259d 6794 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 6795 return "lea{l}\t{%a2, %0|%0, %a2}";
9b70259d 6796
58787064 6797 case TYPE_INCDEC:
7637e42c 6798 gcc_assert (rtx_equal_p (operands[0], operands[1]));
58787064 6799 if (operands[2] == const1_rtx)
0f40f9f7 6800 return "inc{l}\t%0";
9b70259d 6801 else
7637e42c
NS
6802 {
6803 gcc_assert (operands[2] == constm1_rtx);
6804 return "dec{l}\t%0";
6805 }
58787064
JH
6806
6807 default:
b6837b94
JY
6808 /* Use add as much as possible to replace lea for AGU optimization. */
6809 if (which_alternative == 2 && TARGET_OPT_AGU)
6810 return "add{l}\t{%1, %0|%0, %1}";
6811
7637e42c 6812 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d 6813
58787064
JH
6814 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6815 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 6816 if (CONST_INT_P (operands[2])
58787064
JH
6817 && (INTVAL (operands[2]) == 128
6818 || (INTVAL (operands[2]) < 0
6819 && INTVAL (operands[2]) != -128)))
9b70259d
JH
6820 {
6821 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6822 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 6823 }
0f40f9f7 6824 return "add{l}\t{%2, %0|%0, %2}";
58787064 6825 }
0f40f9f7 6826}
58787064 6827 [(set (attr "type")
b6837b94
JY
6828 (cond [(and (eq_attr "alternative" "2")
6829 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6830 (const_string "lea")
6831 (eq_attr "alternative" "3")
9b70259d
JH
6832 (const_string "lea")
6833 ; Current assemblers are broken and do not allow @GOTOFF in
6834 ; ought but a memory context.
6835 (match_operand:SI 2 "pic_symbolic_operand" "")
6836 (const_string "lea")
6837 (match_operand:SI 2 "incdec_operand" "")
6838 (const_string "incdec")
6839 ]
6840 (const_string "alu")))
a952487c
JJ
6841 (set (attr "length_immediate")
6842 (if_then_else
6843 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6844 (const_string "1")
6845 (const_string "*")))
9b70259d 6846 (set_attr "mode" "SI")])
58787064 6847
9b70259d
JH
6848;; Convert lea to the lea pattern to avoid flags dependency.
6849(define_split
6850 [(set (match_operand 0 "register_operand" "")
6851 (plus (match_operand 1 "register_operand" "")
6852 (match_operand 2 "nonmemory_operand" "")))
8bc527af 6853 (clobber (reg:CC FLAGS_REG))]
6ff078d4 6854 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
9b70259d 6855 [(const_int 0)]
9b70259d
JH
6856{
6857 rtx pat;
6858 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6859 may confuse gen_lowpart. */
6860 if (GET_MODE (operands[0]) != Pmode)
6861 {
6862 operands[1] = gen_lowpart (Pmode, operands[1]);
6863 operands[2] = gen_lowpart (Pmode, operands[2]);
6864 }
6865 operands[0] = gen_lowpart (SImode, operands[0]);
6866 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6867 if (Pmode != SImode)
6868 pat = gen_rtx_SUBREG (SImode, pat, 0);
6869 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6870 DONE;
0f40f9f7 6871})
9b70259d
JH
6872
6873;; It may seem that nonimmediate operand is proper one for operand 1.
6874;; The addsi_1 pattern allows nonimmediate operand at that place and
6875;; we take care in ix86_binary_operator_ok to not allow two memory
6876;; operands so proper swapping will be done in reload. This allow
6877;; patterns constructed from addsi_1 to match.
6878(define_insn "addsi_1_zext"
6879 [(set (match_operand:DI 0 "register_operand" "=r,r")
6880 (zero_extend:DI
6881 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
0edb82cb 6882 (match_operand:SI 2 "general_operand" "g,li"))))
8bc527af 6883 (clobber (reg:CC FLAGS_REG))]
9b70259d 6884 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
886c62d1 6885{
e075ae69 6886 switch (get_attr_type (insn))
7c802a40 6887 {
9b70259d
JH
6888 case TYPE_LEA:
6889 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 6890 return "lea{l}\t{%a2, %k0|%k0, %a2}";
9b70259d 6891
e075ae69
RH
6892 case TYPE_INCDEC:
6893 if (operands[2] == const1_rtx)
0f40f9f7 6894 return "inc{l}\t%k0";
9b70259d 6895 else
7637e42c
NS
6896 {
6897 gcc_assert (operands[2] == constm1_rtx);
6898 return "dec{l}\t%k0";
6899 }
9b70259d
JH
6900
6901 default:
6902 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6903 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 6904 if (CONST_INT_P (operands[2])
9b70259d
JH
6905 && (INTVAL (operands[2]) == 128
6906 || (INTVAL (operands[2]) < 0
6907 && INTVAL (operands[2]) != -128)))
6908 {
6909 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6910 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 6911 }
0f40f9f7 6912 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 6913 }
0f40f9f7 6914}
9b70259d
JH
6915 [(set (attr "type")
6916 (cond [(eq_attr "alternative" "1")
6917 (const_string "lea")
6918 ; Current assemblers are broken and do not allow @GOTOFF in
6919 ; ought but a memory context.
6920 (match_operand:SI 2 "pic_symbolic_operand" "")
6921 (const_string "lea")
6922 (match_operand:SI 2 "incdec_operand" "")
6923 (const_string "incdec")
6924 ]
6925 (const_string "alu")))
a952487c
JJ
6926 (set (attr "length_immediate")
6927 (if_then_else
6928 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6929 (const_string "1")
6930 (const_string "*")))
9b70259d
JH
6931 (set_attr "mode" "SI")])
6932
6933;; Convert lea to the lea pattern to avoid flags dependency.
6934(define_split
6935 [(set (match_operand:DI 0 "register_operand" "")
6936 (zero_extend:DI
6937 (plus:SI (match_operand:SI 1 "register_operand" "")
6938 (match_operand:SI 2 "nonmemory_operand" ""))))
8bc527af 6939 (clobber (reg:CC FLAGS_REG))]
bc8a6d63 6940 "TARGET_64BIT && reload_completed
9b70259d
JH
6941 && true_regnum (operands[0]) != true_regnum (operands[1])"
6942 [(set (match_dup 0)
6943 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
9b70259d
JH
6944{
6945 operands[1] = gen_lowpart (Pmode, operands[1]);
6946 operands[2] = gen_lowpart (Pmode, operands[2]);
0f40f9f7 6947})
9b70259d
JH
6948
6949(define_insn "*addsi_2"
42fabf21 6950 [(set (reg FLAGS_REG)
9b70259d
JH
6951 (compare
6952 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
0edb82cb 6953 (match_operand:SI 2 "general_operand" "g,ri"))
6300f037 6954 (const_int 0)))
9b70259d
JH
6955 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6956 (plus:SI (match_dup 1) (match_dup 2)))]
6957 "ix86_match_ccmode (insn, CCGOCmode)
6958 && ix86_binary_operator_ok (PLUS, SImode, operands)
6959 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 6960 ought but a memory context. */
9b70259d 6961 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
6962{
6963 switch (get_attr_type (insn))
6964 {
6965 case TYPE_INCDEC:
7637e42c 6966 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d 6967 if (operands[2] == const1_rtx)
0f40f9f7 6968 return "inc{l}\t%0";
9b70259d 6969 else
7637e42c
NS
6970 {
6971 gcc_assert (operands[2] == constm1_rtx);
6972 return "dec{l}\t%0";
6973 }
9b70259d
JH
6974
6975 default:
7637e42c 6976 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d
JH
6977 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6978 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 6979 if (CONST_INT_P (operands[2])
9b70259d
JH
6980 && (INTVAL (operands[2]) == 128
6981 || (INTVAL (operands[2]) < 0
6982 && INTVAL (operands[2]) != -128)))
6983 {
6984 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6985 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 6986 }
0f40f9f7 6987 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 6988 }
0f40f9f7 6989}
9b70259d
JH
6990 [(set (attr "type")
6991 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6992 (const_string "incdec")
6993 (const_string "alu")))
a952487c
JJ
6994 (set (attr "length_immediate")
6995 (if_then_else
6996 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6997 (const_string "1")
6998 (const_string "*")))
9b70259d
JH
6999 (set_attr "mode" "SI")])
7000
7001;; See comment for addsi_1_zext why we do use nonimmediate_operand
7002(define_insn "*addsi_2_zext"
42fabf21 7003 [(set (reg FLAGS_REG)
9b70259d
JH
7004 (compare
7005 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
0edb82cb 7006 (match_operand:SI 2 "general_operand" "g"))
6300f037 7007 (const_int 0)))
9b70259d
JH
7008 (set (match_operand:DI 0 "register_operand" "=r")
7009 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7010 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7011 && ix86_binary_operator_ok (PLUS, SImode, operands)
7012 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 7013 ought but a memory context. */
9b70259d 7014 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
7015{
7016 switch (get_attr_type (insn))
7017 {
7018 case TYPE_INCDEC:
7019 if (operands[2] == const1_rtx)
0f40f9f7 7020 return "inc{l}\t%k0";
9b70259d 7021 else
7637e42c
NS
7022 {
7023 gcc_assert (operands[2] == constm1_rtx);
7024 return "dec{l}\t%k0";
7025 }
9b70259d
JH
7026
7027 default:
7028 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7029 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7030 if (CONST_INT_P (operands[2])
9b70259d
JH
7031 && (INTVAL (operands[2]) == 128
7032 || (INTVAL (operands[2]) < 0
7033 && INTVAL (operands[2]) != -128)))
7034 {
7035 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7036 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 7037 }
0f40f9f7 7038 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 7039 }
0f40f9f7 7040}
9b70259d
JH
7041 [(set (attr "type")
7042 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7043 (const_string "incdec")
7044 (const_string "alu")))
a952487c
JJ
7045 (set (attr "length_immediate")
7046 (if_then_else
7047 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7048 (const_string "1")
7049 (const_string "*")))
9b70259d
JH
7050 (set_attr "mode" "SI")])
7051
7052(define_insn "*addsi_3"
42fabf21 7053 [(set (reg FLAGS_REG)
0edb82cb 7054 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
9b70259d
JH
7055 (match_operand:SI 1 "nonimmediate_operand" "%0")))
7056 (clobber (match_scratch:SI 0 "=r"))]
7057 "ix86_match_ccmode (insn, CCZmode)
7656aee4 7058 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
9b70259d 7059 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 7060 ought but a memory context. */
9b70259d 7061 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
7062{
7063 switch (get_attr_type (insn))
7064 {
7065 case TYPE_INCDEC:
7637e42c 7066 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d 7067 if (operands[2] == const1_rtx)
0f40f9f7 7068 return "inc{l}\t%0";
9b70259d 7069 else
7637e42c
NS
7070 {
7071 gcc_assert (operands[2] == constm1_rtx);
7072 return "dec{l}\t%0";
7073 }
9b70259d
JH
7074
7075 default:
7637e42c 7076 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d
JH
7077 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7078 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7079 if (CONST_INT_P (operands[2])
9b70259d
JH
7080 && (INTVAL (operands[2]) == 128
7081 || (INTVAL (operands[2]) < 0
7082 && INTVAL (operands[2]) != -128)))
7083 {
7084 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7085 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 7086 }
0f40f9f7 7087 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 7088 }
0f40f9f7 7089}
9b70259d
JH
7090 [(set (attr "type")
7091 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7092 (const_string "incdec")
7093 (const_string "alu")))
a952487c
JJ
7094 (set (attr "length_immediate")
7095 (if_then_else
7096 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7097 (const_string "1")
7098 (const_string "*")))
9b70259d
JH
7099 (set_attr "mode" "SI")])
7100
7101;; See comment for addsi_1_zext why we do use nonimmediate_operand
7102(define_insn "*addsi_3_zext"
42fabf21 7103 [(set (reg FLAGS_REG)
0edb82cb 7104 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
9b70259d
JH
7105 (match_operand:SI 1 "nonimmediate_operand" "%0")))
7106 (set (match_operand:DI 0 "register_operand" "=r")
7107 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7108 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
7109 && ix86_binary_operator_ok (PLUS, SImode, operands)
7110 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 7111 ought but a memory context. */
9b70259d 7112 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
7113{
7114 switch (get_attr_type (insn))
7115 {
7116 case TYPE_INCDEC:
7117 if (operands[2] == const1_rtx)
0f40f9f7 7118 return "inc{l}\t%k0";
9b70259d 7119 else
7637e42c
NS
7120 {
7121 gcc_assert (operands[2] == constm1_rtx);
7122 return "dec{l}\t%k0";
7123 }
9b70259d
JH
7124
7125 default:
7126 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7127 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7128 if (CONST_INT_P (operands[2])
9b70259d
JH
7129 && (INTVAL (operands[2]) == 128
7130 || (INTVAL (operands[2]) < 0
7131 && INTVAL (operands[2]) != -128)))
7132 {
7133 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7134 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 7135 }
0f40f9f7 7136 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 7137 }
0f40f9f7 7138}
9b70259d
JH
7139 [(set (attr "type")
7140 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7141 (const_string "incdec")
7142 (const_string "alu")))
a952487c
JJ
7143 (set (attr "length_immediate")
7144 (if_then_else
7145 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7146 (const_string "1")
7147 (const_string "*")))
9b70259d
JH
7148 (set_attr "mode" "SI")])
7149
4aae8a9a 7150; For comparisons against 1, -1 and 128, we may generate better code
9b70259d
JH
7151; by converting cmp to add, inc or dec as done by peephole2. This pattern
7152; is matched then. We can't accept general immediate, because for
7153; case of overflows, the result is messed up.
7154; This pattern also don't hold of 0x80000000, since the value overflows
7155; when negated.
d6a7951f 7156; Also carry flag is reversed compared to cmp, so this conversion is valid
9b70259d
JH
7157; only for comparisons not depending on it.
7158(define_insn "*addsi_4"
42fabf21 7159 [(set (reg FLAGS_REG)
9b70259d
JH
7160 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7161 (match_operand:SI 2 "const_int_operand" "n")))
7162 (clobber (match_scratch:SI 0 "=rm"))]
7163 "ix86_match_ccmode (insn, CCGCmode)
7164 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
9b70259d
JH
7165{
7166 switch (get_attr_type (insn))
7167 {
7168 case TYPE_INCDEC:
7169 if (operands[2] == constm1_rtx)
0f40f9f7 7170 return "inc{l}\t%0";
9b70259d 7171 else
7637e42c
NS
7172 {
7173 gcc_assert (operands[2] == const1_rtx);
7174 return "dec{l}\t%0";
7175 }
9b70259d
JH
7176
7177 default:
7637e42c 7178 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d
JH
7179 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7180 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7181 if ((INTVAL (operands[2]) == -128
7182 || (INTVAL (operands[2]) > 0
7183 && INTVAL (operands[2]) != 128)))
0f40f9f7 7184 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 7185 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7186 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 7187 }
0f40f9f7 7188}
9b70259d
JH
7189 [(set (attr "type")
7190 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7191 (const_string "incdec")
7192 (const_string "alu")))
93cac287
JJ
7193 (set (attr "length_immediate")
7194 (if_then_else
725fd454 7195 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
93cac287
JJ
7196 (const_string "1")
7197 (const_string "*")))
9b70259d
JH
7198 (set_attr "mode" "SI")])
7199
7200(define_insn "*addsi_5"
42fabf21 7201 [(set (reg FLAGS_REG)
9b70259d
JH
7202 (compare
7203 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
0edb82cb 7204 (match_operand:SI 2 "general_operand" "g"))
6300f037 7205 (const_int 0)))
9b70259d
JH
7206 (clobber (match_scratch:SI 0 "=r"))]
7207 "ix86_match_ccmode (insn, CCGOCmode)
7656aee4 7208 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
9b70259d 7209 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 7210 ought but a memory context. */
9b70259d 7211 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
7212{
7213 switch (get_attr_type (insn))
7214 {
7215 case TYPE_INCDEC:
7637e42c 7216 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d 7217 if (operands[2] == const1_rtx)
0f40f9f7 7218 return "inc{l}\t%0";
9b70259d 7219 else
7637e42c
NS
7220 {
7221 gcc_assert (operands[2] == constm1_rtx);
7222 return "dec{l}\t%0";
7223 }
9b70259d
JH
7224
7225 default:
7637e42c 7226 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d
JH
7227 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7228 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7229 if (CONST_INT_P (operands[2])
9b70259d
JH
7230 && (INTVAL (operands[2]) == 128
7231 || (INTVAL (operands[2]) < 0
7232 && INTVAL (operands[2]) != -128)))
7233 {
7234 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7235 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 7236 }
0f40f9f7 7237 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 7238 }
0f40f9f7 7239}
9b70259d
JH
7240 [(set (attr "type")
7241 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7242 (const_string "incdec")
7243 (const_string "alu")))
a952487c
JJ
7244 (set (attr "length_immediate")
7245 (if_then_else
7246 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7247 (const_string "1")
7248 (const_string "*")))
9b70259d
JH
7249 (set_attr "mode" "SI")])
7250
7251(define_expand "addhi3"
7ae14d31
UB
7252 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7253 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7254 (match_operand:HI 2 "general_operand" "")))]
9b70259d
JH
7255 "TARGET_HIMODE_MATH"
7256 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
7257
7258;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
7259;; type optimizations enabled by define-splits. This is not important
7260;; for PII, and in fact harmful because of partial register stalls.
7261
7262(define_insn "*addhi_1_lea"
7263 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7264 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
0edb82cb 7265 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
8bc527af 7266 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
7267 "!TARGET_PARTIAL_REG_STALL
7268 && ix86_binary_operator_ok (PLUS, HImode, operands)"
9b70259d
JH
7269{
7270 switch (get_attr_type (insn))
7271 {
7272 case TYPE_LEA:
0f40f9f7 7273 return "#";
9b70259d
JH
7274 case TYPE_INCDEC:
7275 if (operands[2] == const1_rtx)
0f40f9f7 7276 return "inc{w}\t%0";
7637e42c
NS
7277 else
7278 {
7279 gcc_assert (operands[2] == constm1_rtx);
7280 return "dec{w}\t%0";
7281 }
9b70259d
JH
7282
7283 default:
7284 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7285 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7286 if (CONST_INT_P (operands[2])
9b70259d
JH
7287 && (INTVAL (operands[2]) == 128
7288 || (INTVAL (operands[2]) < 0
7289 && INTVAL (operands[2]) != -128)))
7290 {
7291 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7292 return "sub{w}\t{%2, %0|%0, %2}";
9b70259d 7293 }
0f40f9f7 7294 return "add{w}\t{%2, %0|%0, %2}";
9b70259d 7295 }
0f40f9f7 7296}
9b70259d
JH
7297 [(set (attr "type")
7298 (if_then_else (eq_attr "alternative" "2")
7299 (const_string "lea")
7300 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7301 (const_string "incdec")
7302 (const_string "alu"))))
a952487c
JJ
7303 (set (attr "length_immediate")
7304 (if_then_else
7305 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7306 (const_string "1")
7307 (const_string "*")))
9b70259d
JH
7308 (set_attr "mode" "HI,HI,SI")])
7309
7310(define_insn "*addhi_1"
7311 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7312 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
0edb82cb 7313 (match_operand:HI 2 "general_operand" "rn,rm")))
8bc527af 7314 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
7315 "TARGET_PARTIAL_REG_STALL
7316 && ix86_binary_operator_ok (PLUS, HImode, operands)"
9b70259d
JH
7317{
7318 switch (get_attr_type (insn))
7319 {
7320 case TYPE_INCDEC:
7321 if (operands[2] == const1_rtx)
0f40f9f7 7322 return "inc{w}\t%0";
7637e42c
NS
7323 else
7324 {
7325 gcc_assert (operands[2] == constm1_rtx);
7326 return "dec{w}\t%0";
7327 }
7c802a40 7328
e075ae69
RH
7329 default:
7330 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7331 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7332 if (CONST_INT_P (operands[2])
e075ae69
RH
7333 && (INTVAL (operands[2]) == 128
7334 || (INTVAL (operands[2]) < 0
7335 && INTVAL (operands[2]) != -128)))
7336 {
7337 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7338 return "sub{w}\t{%2, %0|%0, %2}";
e075ae69 7339 }
0f40f9f7 7340 return "add{w}\t{%2, %0|%0, %2}";
7c802a40 7341 }
0f40f9f7 7342}
e075ae69
RH
7343 [(set (attr "type")
7344 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7345 (const_string "incdec")
6ef67412 7346 (const_string "alu")))
a952487c
JJ
7347 (set (attr "length_immediate")
7348 (if_then_else
7349 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7350 (const_string "1")
7351 (const_string "*")))
6ef67412 7352 (set_attr "mode" "HI")])
7c802a40 7353
e075ae69 7354(define_insn "*addhi_2"
42fabf21 7355 [(set (reg FLAGS_REG)
16189740 7356 (compare
e075ae69 7357 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
0edb82cb 7358 (match_operand:HI 2 "general_operand" "rmn,rn"))
6300f037 7359 (const_int 0)))
e075ae69
RH
7360 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7361 (plus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 7362 "ix86_match_ccmode (insn, CCGOCmode)
16189740 7363 && ix86_binary_operator_ok (PLUS, HImode, operands)"
e075ae69
RH
7364{
7365 switch (get_attr_type (insn))
b980bec0 7366 {
e075ae69
RH
7367 case TYPE_INCDEC:
7368 if (operands[2] == const1_rtx)
0f40f9f7 7369 return "inc{w}\t%0";
7637e42c
NS
7370 else
7371 {
7372 gcc_assert (operands[2] == constm1_rtx);
7373 return "dec{w}\t%0";
7374 }
b980bec0 7375
e075ae69
RH
7376 default:
7377 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7378 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7379 if (CONST_INT_P (operands[2])
e075ae69
RH
7380 && (INTVAL (operands[2]) == 128
7381 || (INTVAL (operands[2]) < 0
7382 && INTVAL (operands[2]) != -128)))
7383 {
7384 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7385 return "sub{w}\t{%2, %0|%0, %2}";
e075ae69 7386 }
0f40f9f7 7387 return "add{w}\t{%2, %0|%0, %2}";
b980bec0 7388 }
0f40f9f7 7389}
e075ae69
RH
7390 [(set (attr "type")
7391 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7392 (const_string "incdec")
6ef67412 7393 (const_string "alu")))
a952487c
JJ
7394 (set (attr "length_immediate")
7395 (if_then_else
7396 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7397 (const_string "1")
7398 (const_string "*")))
6ef67412 7399 (set_attr "mode" "HI")])
e075ae69
RH
7400
7401(define_insn "*addhi_3"
42fabf21 7402 [(set (reg FLAGS_REG)
0edb82cb 7403 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
7e08e190 7404 (match_operand:HI 1 "nonimmediate_operand" "%0")))
d90ffc8d 7405 (clobber (match_scratch:HI 0 "=r"))]
7e08e190 7406 "ix86_match_ccmode (insn, CCZmode)
7656aee4 7407 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
d90ffc8d
JH
7408{
7409 switch (get_attr_type (insn))
7410 {
7411 case TYPE_INCDEC:
7412 if (operands[2] == const1_rtx)
0f40f9f7 7413 return "inc{w}\t%0";
7637e42c
NS
7414 else
7415 {
7416 gcc_assert (operands[2] == constm1_rtx);
7417 return "dec{w}\t%0";
7418 }
d90ffc8d
JH
7419
7420 default:
7421 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7422 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7423 if (CONST_INT_P (operands[2])
d90ffc8d
JH
7424 && (INTVAL (operands[2]) == 128
7425 || (INTVAL (operands[2]) < 0
7426 && INTVAL (operands[2]) != -128)))
7427 {
7428 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7429 return "sub{w}\t{%2, %0|%0, %2}";
d90ffc8d 7430 }
0f40f9f7 7431 return "add{w}\t{%2, %0|%0, %2}";
d90ffc8d 7432 }
0f40f9f7 7433}
d90ffc8d
JH
7434 [(set (attr "type")
7435 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7436 (const_string "incdec")
7437 (const_string "alu")))
a952487c
JJ
7438 (set (attr "length_immediate")
7439 (if_then_else
7440 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7441 (const_string "1")
7442 (const_string "*")))
d90ffc8d
JH
7443 (set_attr "mode" "HI")])
7444
d1c9ce9f 7445; See comments above addsi_4 for details.
d90ffc8d 7446(define_insn "*addhi_4"
42fabf21 7447 [(set (reg FLAGS_REG)
7e08e190
JH
7448 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7449 (match_operand:HI 2 "const_int_operand" "n")))
7450 (clobber (match_scratch:HI 0 "=rm"))]
7451 "ix86_match_ccmode (insn, CCGCmode)
7452 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7e08e190
JH
7453{
7454 switch (get_attr_type (insn))
7455 {
7456 case TYPE_INCDEC:
2f41793e 7457 if (operands[2] == constm1_rtx)
0f40f9f7 7458 return "inc{w}\t%0";
7e08e190 7459 else
7637e42c
NS
7460 {
7461 gcc_assert (operands[2] == const1_rtx);
7462 return "dec{w}\t%0";
7463 }
7e08e190
JH
7464
7465 default:
7637e42c 7466 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7e08e190
JH
7467 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7468 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7469 if ((INTVAL (operands[2]) == -128
7470 || (INTVAL (operands[2]) > 0
7471 && INTVAL (operands[2]) != 128)))
0f40f9f7 7472 return "sub{w}\t{%2, %0|%0, %2}";
7e08e190 7473 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7474 return "add{w}\t{%2, %0|%0, %2}";
7e08e190 7475 }
0f40f9f7 7476}
7e08e190
JH
7477 [(set (attr "type")
7478 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7479 (const_string "incdec")
7480 (const_string "alu")))
93cac287
JJ
7481 (set (attr "length_immediate")
7482 (if_then_else
725fd454 7483 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
93cac287
JJ
7484 (const_string "1")
7485 (const_string "*")))
725fd454 7486 (set_attr "mode" "HI")])
b980bec0 7487
d90ffc8d 7488
7e08e190 7489(define_insn "*addhi_5"
42fabf21 7490 [(set (reg FLAGS_REG)
9076b9c1
JH
7491 (compare
7492 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
0edb82cb 7493 (match_operand:HI 2 "general_operand" "rmn"))
6300f037 7494 (const_int 0)))
9076b9c1
JH
7495 (clobber (match_scratch:HI 0 "=r"))]
7496 "ix86_match_ccmode (insn, CCGOCmode)
7656aee4 7497 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9076b9c1
JH
7498{
7499 switch (get_attr_type (insn))
7500 {
7501 case TYPE_INCDEC:
7502 if (operands[2] == const1_rtx)
0f40f9f7 7503 return "inc{w}\t%0";
7637e42c
NS
7504 else
7505 {
7506 gcc_assert (operands[2] == constm1_rtx);
7507 return "dec{w}\t%0";
7508 }
9076b9c1
JH
7509
7510 default:
7511 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7512 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7513 if (CONST_INT_P (operands[2])
9076b9c1
JH
7514 && (INTVAL (operands[2]) == 128
7515 || (INTVAL (operands[2]) < 0
7516 && INTVAL (operands[2]) != -128)))
7517 {
7518 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7519 return "sub{w}\t{%2, %0|%0, %2}";
9076b9c1 7520 }
0f40f9f7 7521 return "add{w}\t{%2, %0|%0, %2}";
9076b9c1 7522 }
0f40f9f7 7523}
9076b9c1
JH
7524 [(set (attr "type")
7525 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7526 (const_string "incdec")
7527 (const_string "alu")))
a952487c
JJ
7528 (set (attr "length_immediate")
7529 (if_then_else
7530 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7531 (const_string "1")
7532 (const_string "*")))
9076b9c1
JH
7533 (set_attr "mode" "HI")])
7534
e075ae69 7535(define_expand "addqi3"
7ae14d31
UB
7536 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7537 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7538 (match_operand:QI 2 "general_operand" "")))]
d9f32422 7539 "TARGET_QIMODE_MATH"
e075ae69
RH
7540 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7541
7542;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
7543(define_insn "*addqi_1_lea"
7544 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7545 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
9a9286af 7546 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
8bc527af 7547 (clobber (reg:CC FLAGS_REG))]
58787064
JH
7548 "!TARGET_PARTIAL_REG_STALL
7549 && ix86_binary_operator_ok (PLUS, QImode, operands)"
58787064
JH
7550{
7551 int widen = (which_alternative == 2);
7552 switch (get_attr_type (insn))
7553 {
7554 case TYPE_LEA:
0f40f9f7 7555 return "#";
58787064
JH
7556 case TYPE_INCDEC:
7557 if (operands[2] == const1_rtx)
0f40f9f7 7558 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7637e42c
NS
7559 else
7560 {
7561 gcc_assert (operands[2] == constm1_rtx);
7562 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7563 }
58787064
JH
7564
7565 default:
7566 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7567 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7568 if (CONST_INT_P (operands[2])
58787064
JH
7569 && (INTVAL (operands[2]) == 128
7570 || (INTVAL (operands[2]) < 0
7571 && INTVAL (operands[2]) != -128)))
7572 {
7573 operands[2] = GEN_INT (-INTVAL (operands[2]));
7574 if (widen)
0f40f9f7 7575 return "sub{l}\t{%2, %k0|%k0, %2}";
58787064 7576 else
0f40f9f7 7577 return "sub{b}\t{%2, %0|%0, %2}";
58787064
JH
7578 }
7579 if (widen)
0f40f9f7 7580 return "add{l}\t{%k2, %k0|%k0, %k2}";
58787064 7581 else
0f40f9f7 7582 return "add{b}\t{%2, %0|%0, %2}";
58787064 7583 }
0f40f9f7 7584}
58787064
JH
7585 [(set (attr "type")
7586 (if_then_else (eq_attr "alternative" "3")
7587 (const_string "lea")
adc88131 7588 (if_then_else (match_operand:QI 2 "incdec_operand" "")
58787064
JH
7589 (const_string "incdec")
7590 (const_string "alu"))))
a952487c
JJ
7591 (set (attr "length_immediate")
7592 (if_then_else
7593 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7594 (const_string "1")
7595 (const_string "*")))
adc88131 7596 (set_attr "mode" "QI,QI,SI,SI")])
58787064 7597
e075ae69 7598(define_insn "*addqi_1"
7c6b971d 7599 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 7600 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 7601 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8bc527af 7602 (clobber (reg:CC FLAGS_REG))]
58787064
JH
7603 "TARGET_PARTIAL_REG_STALL
7604 && ix86_binary_operator_ok (PLUS, QImode, operands)"
e075ae69
RH
7605{
7606 int widen = (which_alternative == 2);
7607 switch (get_attr_type (insn))
5bc7cd8e 7608 {
e075ae69
RH
7609 case TYPE_INCDEC:
7610 if (operands[2] == const1_rtx)
0f40f9f7 7611 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7637e42c
NS
7612 else
7613 {
7614 gcc_assert (operands[2] == constm1_rtx);
7615 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7616 }
5bc7cd8e 7617
e075ae69
RH
7618 default:
7619 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7620 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7656aee4 7621 if (CONST_INT_P (operands[2])
e075ae69
RH
7622 && (INTVAL (operands[2]) == 128
7623 || (INTVAL (operands[2]) < 0
7624 && INTVAL (operands[2]) != -128)))
5bc7cd8e 7625 {
e075ae69
RH
7626 operands[2] = GEN_INT (-INTVAL (operands[2]));
7627 if (widen)
0f40f9f7 7628 return "sub{l}\t{%2, %k0|%k0, %2}";
e075ae69 7629 else
0f40f9f7 7630 return "sub{b}\t{%2, %0|%0, %2}";
5bc7cd8e 7631 }
e075ae69 7632 if (widen)
0f40f9f7 7633 return "add{l}\t{%k2, %k0|%k0, %k2}";
e075ae69 7634 else
0f40f9f7 7635 return "add{b}\t{%2, %0|%0, %2}";
5bc7cd8e 7636 }
0f40f9f7 7637}
e075ae69
RH
7638 [(set (attr "type")
7639 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7640 (const_string "incdec")
6ef67412 7641 (const_string "alu")))
a952487c
JJ
7642 (set (attr "length_immediate")
7643 (if_then_else
7644 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7645 (const_string "1")
7646 (const_string "*")))
6ef67412 7647 (set_attr "mode" "QI,QI,SI")])
e075ae69 7648
2f41793e
JH
7649(define_insn "*addqi_1_slp"
7650 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1b245ade
JH
7651 (plus:QI (match_dup 0)
7652 (match_operand:QI 1 "general_operand" "qn,qnm")))
8bc527af 7653 (clobber (reg:CC FLAGS_REG))]
3debdc1e 7654 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 7655 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2f41793e
JH
7656{
7657 switch (get_attr_type (insn))
7658 {
7659 case TYPE_INCDEC:
95199202 7660 if (operands[1] == const1_rtx)
2f41793e 7661 return "inc{b}\t%0";
7637e42c
NS
7662 else
7663 {
7664 gcc_assert (operands[1] == constm1_rtx);
7665 return "dec{b}\t%0";
7666 }
2f41793e
JH
7667
7668 default:
7669 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7656aee4 7670 if (CONST_INT_P (operands[1])
95199202 7671 && INTVAL (operands[1]) < 0)
2f41793e 7672 {
79551a56 7673 operands[1] = GEN_INT (-INTVAL (operands[1]));
1b245ade 7674 return "sub{b}\t{%1, %0|%0, %1}";
2f41793e 7675 }
1b245ade 7676 return "add{b}\t{%1, %0|%0, %1}";
2f41793e
JH
7677 }
7678}
7679 [(set (attr "type")
ba3ed8d8 7680 (if_then_else (match_operand:QI 1 "incdec_operand" "")
2f41793e 7681 (const_string "incdec")
95199202 7682 (const_string "alu1")))
ebc0c8bb
JJ
7683 (set (attr "memory")
7684 (if_then_else (match_operand 1 "memory_operand" "")
7685 (const_string "load")
7686 (const_string "none")))
2f41793e
JH
7687 (set_attr "mode" "QI")])
7688
e075ae69 7689(define_insn "*addqi_2"
42fabf21 7690 [(set (reg FLAGS_REG)
16189740 7691 (compare
e075ae69 7692 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
0edb82cb 7693 (match_operand:QI 2 "general_operand" "qmn,qn"))
e075ae69
RH
7694 (const_int 0)))
7695 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7696 (plus:QI (match_dup 1) (match_dup 2)))]
9076b9c1 7697 "ix86_match_ccmode (insn, CCGOCmode)
16189740 7698 && ix86_binary_operator_ok (PLUS, QImode, operands)"
e075ae69
RH
7699{
7700 switch (get_attr_type (insn))
7701 {
7702 case TYPE_INCDEC:
7703 if (operands[2] == const1_rtx)
0f40f9f7 7704 return "inc{b}\t%0";
7637e42c
NS
7705 else
7706 {
7707 gcc_assert (operands[2] == constm1_rtx
7656aee4 7708 || (CONST_INT_P (operands[2])
7637e42c
NS
7709 && INTVAL (operands[2]) == 255));
7710 return "dec{b}\t%0";
7711 }
5bc7cd8e 7712
e075ae69
RH
7713 default:
7714 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7656aee4 7715 if (CONST_INT_P (operands[2])
e075ae69
RH
7716 && INTVAL (operands[2]) < 0)
7717 {
7718 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7719 return "sub{b}\t{%2, %0|%0, %2}";
e075ae69 7720 }
0f40f9f7 7721 return "add{b}\t{%2, %0|%0, %2}";
e075ae69 7722 }
0f40f9f7 7723}
e075ae69
RH
7724 [(set (attr "type")
7725 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7726 (const_string "incdec")
6ef67412
JH
7727 (const_string "alu")))
7728 (set_attr "mode" "QI")])
e075ae69
RH
7729
7730(define_insn "*addqi_3"
42fabf21 7731 [(set (reg FLAGS_REG)
0edb82cb 7732 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7e08e190
JH
7733 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7734 (clobber (match_scratch:QI 0 "=q"))]
7735 "ix86_match_ccmode (insn, CCZmode)
7656aee4 7736 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
d90ffc8d
JH
7737{
7738 switch (get_attr_type (insn))
7739 {
7740 case TYPE_INCDEC:
7741 if (operands[2] == const1_rtx)
0f40f9f7 7742 return "inc{b}\t%0";
7637e42c
NS
7743 else
7744 {
7745 gcc_assert (operands[2] == constm1_rtx
7656aee4 7746 || (CONST_INT_P (operands[2])
7637e42c
NS
7747 && INTVAL (operands[2]) == 255));
7748 return "dec{b}\t%0";
7749 }
d90ffc8d
JH
7750
7751 default:
7752 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7656aee4 7753 if (CONST_INT_P (operands[2])
d90ffc8d
JH
7754 && INTVAL (operands[2]) < 0)
7755 {
7756 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7757 return "sub{b}\t{%2, %0|%0, %2}";
d90ffc8d 7758 }
0f40f9f7 7759 return "add{b}\t{%2, %0|%0, %2}";
d90ffc8d 7760 }
0f40f9f7 7761}
d90ffc8d
JH
7762 [(set (attr "type")
7763 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7764 (const_string "incdec")
7765 (const_string "alu")))
7766 (set_attr "mode" "QI")])
7767
d1c9ce9f 7768; See comments above addsi_4 for details.
d90ffc8d 7769(define_insn "*addqi_4"
42fabf21 7770 [(set (reg FLAGS_REG)
7e08e190
JH
7771 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7772 (match_operand:QI 2 "const_int_operand" "n")))
7773 (clobber (match_scratch:QI 0 "=qm"))]
7774 "ix86_match_ccmode (insn, CCGCmode)
7775 && (INTVAL (operands[2]) & 0xff) != 0x80"
7e08e190
JH
7776{
7777 switch (get_attr_type (insn))
7778 {
7779 case TYPE_INCDEC:
7780 if (operands[2] == constm1_rtx
7656aee4 7781 || (CONST_INT_P (operands[2])
7e08e190 7782 && INTVAL (operands[2]) == 255))
0f40f9f7 7783 return "inc{b}\t%0";
7e08e190 7784 else
7637e42c
NS
7785 {
7786 gcc_assert (operands[2] == const1_rtx);
7787 return "dec{b}\t%0";
7788 }
7e08e190
JH
7789
7790 default:
7637e42c 7791 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7e08e190
JH
7792 if (INTVAL (operands[2]) < 0)
7793 {
7794 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7795 return "add{b}\t{%2, %0|%0, %2}";
7e08e190 7796 }
0f40f9f7 7797 return "sub{b}\t{%2, %0|%0, %2}";
7e08e190 7798 }
0f40f9f7 7799}
7e08e190
JH
7800 [(set (attr "type")
7801 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7802 (const_string "incdec")
7803 (const_string "alu")))
6ef67412 7804 (set_attr "mode" "QI")])
886c62d1 7805
9dcbdc7e 7806
d90ffc8d 7807(define_insn "*addqi_5"
42fabf21 7808 [(set (reg FLAGS_REG)
9076b9c1
JH
7809 (compare
7810 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
0edb82cb 7811 (match_operand:QI 2 "general_operand" "qmn"))
9076b9c1 7812 (const_int 0)))
7e08e190 7813 (clobber (match_scratch:QI 0 "=q"))]
9076b9c1 7814 "ix86_match_ccmode (insn, CCGOCmode)
7656aee4 7815 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9076b9c1
JH
7816{
7817 switch (get_attr_type (insn))
7818 {
7819 case TYPE_INCDEC:
7820 if (operands[2] == const1_rtx)
0f40f9f7 7821 return "inc{b}\t%0";
7637e42c
NS
7822 else
7823 {
7824 gcc_assert (operands[2] == constm1_rtx
7656aee4 7825 || (CONST_INT_P (operands[2])
7637e42c
NS
7826 && INTVAL (operands[2]) == 255));
7827 return "dec{b}\t%0";
7828 }
9076b9c1
JH
7829
7830 default:
7831 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7656aee4 7832 if (CONST_INT_P (operands[2])
9076b9c1
JH
7833 && INTVAL (operands[2]) < 0)
7834 {
7835 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 7836 return "sub{b}\t{%2, %0|%0, %2}";
9076b9c1 7837 }
0f40f9f7 7838 return "add{b}\t{%2, %0|%0, %2}";
9076b9c1 7839 }
0f40f9f7 7840}
9076b9c1
JH
7841 [(set (attr "type")
7842 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7843 (const_string "incdec")
7844 (const_string "alu")))
7845 (set_attr "mode" "QI")])
7846
e075ae69
RH
7847
7848(define_insn "addqi_ext_1"
3522082b 7849 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
7850 (const_int 8)
7851 (const_int 8))
7852 (plus:SI
7853 (zero_extract:SI
7854 (match_operand 1 "ext_register_operand" "0")
7855 (const_int 8)
7856 (const_int 8))
3522082b 7857 (match_operand:QI 2 "general_operand" "Qmn")))
8bc527af 7858 (clobber (reg:CC FLAGS_REG))]
d2836273 7859 "!TARGET_64BIT"
d2836273
JH
7860{
7861 switch (get_attr_type (insn))
7862 {
7863 case TYPE_INCDEC:
7864 if (operands[2] == const1_rtx)
0f40f9f7 7865 return "inc{b}\t%h0";
7637e42c
NS
7866 else
7867 {
7868 gcc_assert (operands[2] == constm1_rtx
7656aee4 7869 || (CONST_INT_P (operands[2])
7637e42c
NS
7870 && INTVAL (operands[2]) == 255));
7871 return "dec{b}\t%h0";
7872 }
d2836273
JH
7873
7874 default:
0f40f9f7 7875 return "add{b}\t{%2, %h0|%h0, %2}";
d2836273 7876 }
0f40f9f7 7877}
d2836273
JH
7878 [(set (attr "type")
7879 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7880 (const_string "incdec")
7881 (const_string "alu")))
725fd454 7882 (set_attr "modrm" "1")
d2836273
JH
7883 (set_attr "mode" "QI")])
7884
7885(define_insn "*addqi_ext_1_rex64"
7886 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7887 (const_int 8)
7888 (const_int 8))
7889 (plus:SI
7890 (zero_extract:SI
7891 (match_operand 1 "ext_register_operand" "0")
7892 (const_int 8)
7893 (const_int 8))
7894 (match_operand:QI 2 "nonmemory_operand" "Qn")))
8bc527af 7895 (clobber (reg:CC FLAGS_REG))]
d2836273 7896 "TARGET_64BIT"
e075ae69
RH
7897{
7898 switch (get_attr_type (insn))
7899 {
7900 case TYPE_INCDEC:
7901 if (operands[2] == const1_rtx)
0f40f9f7 7902 return "inc{b}\t%h0";
7637e42c
NS
7903 else
7904 {
7905 gcc_assert (operands[2] == constm1_rtx
7656aee4 7906 || (CONST_INT_P (operands[2])
7637e42c
NS
7907 && INTVAL (operands[2]) == 255));
7908 return "dec{b}\t%h0";
7909 }
886c62d1 7910
e075ae69 7911 default:
0f40f9f7 7912 return "add{b}\t{%2, %h0|%h0, %2}";
e075ae69 7913 }
0f40f9f7 7914}
e075ae69
RH
7915 [(set (attr "type")
7916 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7917 (const_string "incdec")
6ef67412 7918 (const_string "alu")))
725fd454 7919 (set_attr "modrm" "1")
6ef67412 7920 (set_attr "mode" "QI")])
e075ae69
RH
7921
7922(define_insn "*addqi_ext_2"
d2836273 7923 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
7924 (const_int 8)
7925 (const_int 8))
7926 (plus:SI
7927 (zero_extract:SI
7928 (match_operand 1 "ext_register_operand" "%0")
7929 (const_int 8)
7930 (const_int 8))
7931 (zero_extract:SI
d2836273 7932 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
7933 (const_int 8)
7934 (const_int 8))))
8bc527af 7935 (clobber (reg:CC FLAGS_REG))]
e075ae69 7936 ""
0f40f9f7 7937 "add{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
7938 [(set_attr "type" "alu")
7939 (set_attr "mode" "QI")])
886c62d1 7940
886c62d1
JVA
7941;; The patterns that match these are at the end of this file.
7942
4fb21e90
JVA
7943(define_expand "addxf3"
7944 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
7945 (plus:XF (match_operand:XF 1 "register_operand" "")
7946 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
7947 "TARGET_80387"
7948 "")
7949
00188daa
UB
7950(define_expand "add<mode>3"
7951 [(set (match_operand:MODEF 0 "register_operand" "")
7952 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7953 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8ce94e44
JM
7954 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7955 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
886c62d1
JVA
7956 "")
7957\f
e075ae69 7958;; Subtract instructions
a269a03c 7959
28356f52
JB
7960;; %%% splits for subditi3
7961
7962(define_expand "subti3"
7ae14d31
UB
7963 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7964 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7965 (match_operand:TI 2 "x86_64_general_operand" "")))]
28356f52
JB
7966 "TARGET_64BIT"
7967 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7968
7969(define_insn "*subti3_1"
7970 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7971 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
68b8830a 7972 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
28356f52
JB
7973 (clobber (reg:CC FLAGS_REG))]
7974 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7975 "#")
7976
7977(define_split
7978 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7979 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
68b8830a 7980 (match_operand:TI 2 "x86_64_general_operand" "")))
28356f52
JB
7981 (clobber (reg:CC FLAGS_REG))]
7982 "TARGET_64BIT && reload_completed"
7983 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7984 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7985 (parallel [(set (match_dup 3)
7986 (minus:DI (match_dup 4)
7987 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7988 (match_dup 5))))
7989 (clobber (reg:CC FLAGS_REG))])]
c2b814b9 7990 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
28356f52 7991
e075ae69 7992;; %%% splits for subsidi3
2ae0f82c 7993
9b70259d 7994(define_expand "subdi3"
7ae14d31
UB
7995 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7996 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7997 (match_operand:DI 2 "x86_64_general_operand" "")))]
9b70259d
JH
7998 ""
7999 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
8000
8001(define_insn "*subdi3_1"
e075ae69 8002 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4cbfbb1b 8003 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
e075ae69 8004 (match_operand:DI 2 "general_operand" "roiF,riF")))
8bc527af 8005 (clobber (reg:CC FLAGS_REG))]
43146684 8006 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
e075ae69 8007 "#")
9c530261 8008
e075ae69
RH
8009(define_split
8010 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4cbfbb1b 8011 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
e075ae69 8012 (match_operand:DI 2 "general_operand" "")))
8bc527af 8013 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 8014 "!TARGET_64BIT && reload_completed"
8bc527af 8015 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
e075ae69
RH
8016 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8017 (parallel [(set (match_dup 3)
8018 (minus:SI (match_dup 4)
8bc527af 8019 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9dcbdc7e 8020 (match_dup 5))))
8bc527af 8021 (clobber (reg:CC FLAGS_REG))])]
c2b814b9 8022 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
e075ae69 8023
9b70259d
JH
8024(define_insn "subdi3_carry_rex64"
8025 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8026 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
9b74f3ea 8027 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
9b70259d 8028 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
8bc527af 8029 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 8030 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 8031 "sbb{q}\t{%2, %0|%0, %2}"
9b70259d 8032 [(set_attr "type" "alu")
b6837b94 8033 (set_attr "use_carry" "1")
9b70259d 8034 (set_attr "pent_pair" "pu")
9b70259d
JH
8035 (set_attr "mode" "DI")])
8036
8037(define_insn "*subdi_1_rex64"
8038 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8039 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8040 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8bc527af 8041 (clobber (reg:CC FLAGS_REG))]
9b70259d 8042 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 8043 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8044 [(set_attr "type" "alu")
8045 (set_attr "mode" "DI")])
8046
8047(define_insn "*subdi_2_rex64"
42fabf21 8048 [(set (reg FLAGS_REG)
9b70259d
JH
8049 (compare
8050 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8051 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
8052 (const_int 0)))
8053 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8054 (minus:DI (match_dup 1) (match_dup 2)))]
8055 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8056 && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 8057 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8058 [(set_attr "type" "alu")
8059 (set_attr "mode" "DI")])
8060
8061(define_insn "*subdi_3_rex63"
42fabf21 8062 [(set (reg FLAGS_REG)
9b70259d
JH
8063 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
8064 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8065 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8066 (minus:DI (match_dup 1) (match_dup 2)))]
8067 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8068 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 8069 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8070 [(set_attr "type" "alu")
8071 (set_attr "mode" "DI")])
8072
7b52eede 8073(define_insn "subqi3_carry"
d67e96cf 8074 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7b52eede 8075 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
e6e81735 8076 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
0edb82cb 8077 (match_operand:QI 2 "general_operand" "qn,qm"))))
8bc527af 8078 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
8079 "ix86_binary_operator_ok (MINUS, QImode, operands)"
8080 "sbb{b}\t{%2, %0|%0, %2}"
8081 [(set_attr "type" "alu")
b6837b94 8082 (set_attr "use_carry" "1")
7b52eede 8083 (set_attr "pent_pair" "pu")
7b52eede
JH
8084 (set_attr "mode" "QI")])
8085
8086(define_insn "subhi3_carry"
8087 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8088 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
e6e81735 8089 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
0edb82cb 8090 (match_operand:HI 2 "general_operand" "rn,rm"))))
8bc527af 8091 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
8092 "ix86_binary_operator_ok (MINUS, HImode, operands)"
8093 "sbb{w}\t{%2, %0|%0, %2}"
8094 [(set_attr "type" "alu")
b6837b94 8095 (set_attr "use_carry" "1")
7b52eede 8096 (set_attr "pent_pair" "pu")
7b52eede 8097 (set_attr "mode" "HI")])
9b70259d 8098
7e08e190 8099(define_insn "subsi3_carry"
e075ae69
RH
8100 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8101 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
e6e81735 8102 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9dcbdc7e 8103 (match_operand:SI 2 "general_operand" "ri,rm"))))
8bc527af 8104 (clobber (reg:CC FLAGS_REG))]
d525dfdf 8105 "ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 8106 "sbb{l}\t{%2, %0|%0, %2}"
e075ae69 8107 [(set_attr "type" "alu")
b6837b94 8108 (set_attr "use_carry" "1")
e075ae69 8109 (set_attr "pent_pair" "pu")
6ef67412 8110 (set_attr "mode" "SI")])
886c62d1 8111
9b70259d 8112(define_insn "subsi3_carry_zext"
a6783d12 8113 [(set (match_operand:DI 0 "register_operand" "=r")
9b70259d 8114 (zero_extend:DI
a6783d12 8115 (minus:SI (match_operand:SI 1 "register_operand" "0")
e6e81735 8116 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
73f48658 8117 (match_operand:SI 2 "general_operand" "g")))))
8bc527af 8118 (clobber (reg:CC FLAGS_REG))]
9b70259d 8119 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 8120 "sbb{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8121 [(set_attr "type" "alu")
8122 (set_attr "pent_pair" "pu")
9b70259d
JH
8123 (set_attr "mode" "SI")])
8124
2ae0f82c 8125(define_expand "subsi3"
7ae14d31
UB
8126 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8127 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
8128 (match_operand:SI 2 "general_operand" "")))]
886c62d1 8129 ""
e075ae69 8130 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
2ae0f82c 8131
e075ae69 8132(define_insn "*subsi_1"
2ae0f82c
SC
8133 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8134 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
e075ae69 8135 (match_operand:SI 2 "general_operand" "ri,rm")))
8bc527af 8136 (clobber (reg:CC FLAGS_REG))]
e075ae69 8137 "ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 8138 "sub{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8139 [(set_attr "type" "alu")
8140 (set_attr "mode" "SI")])
e075ae69 8141
9b70259d
JH
8142(define_insn "*subsi_1_zext"
8143 [(set (match_operand:DI 0 "register_operand" "=r")
8144 (zero_extend:DI
8145 (minus:SI (match_operand:SI 1 "register_operand" "0")
73f48658 8146 (match_operand:SI 2 "general_operand" "g"))))
8bc527af 8147 (clobber (reg:CC FLAGS_REG))]
9b70259d 8148 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 8149 "sub{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8150 [(set_attr "type" "alu")
8151 (set_attr "mode" "SI")])
8152
e075ae69 8153(define_insn "*subsi_2"
42fabf21 8154 [(set (reg FLAGS_REG)
16189740 8155 (compare
e075ae69
RH
8156 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8157 (match_operand:SI 2 "general_operand" "ri,rm"))
8158 (const_int 0)))
8159 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8160 (minus:SI (match_dup 1) (match_dup 2)))]
9076b9c1 8161 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 8162 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 8163 "sub{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8164 [(set_attr "type" "alu")
8165 (set_attr "mode" "SI")])
8166
9b70259d 8167(define_insn "*subsi_2_zext"
42fabf21 8168 [(set (reg FLAGS_REG)
9b70259d
JH
8169 (compare
8170 (minus:SI (match_operand:SI 1 "register_operand" "0")
73f48658 8171 (match_operand:SI 2 "general_operand" "g"))
9b70259d
JH
8172 (const_int 0)))
8173 (set (match_operand:DI 0 "register_operand" "=r")
8174 (zero_extend:DI
8175 (minus:SI (match_dup 1)
8176 (match_dup 2))))]
8177 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8178 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 8179 "sub{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8180 [(set_attr "type" "alu")
8181 (set_attr "mode" "SI")])
8182
d90ffc8d 8183(define_insn "*subsi_3"
42fabf21 8184 [(set (reg FLAGS_REG)
d90ffc8d
JH
8185 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
8186 (match_operand:SI 2 "general_operand" "ri,rm")))
8187 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8188 (minus:SI (match_dup 1) (match_dup 2)))]
16189740
RH
8189 "ix86_match_ccmode (insn, CCmode)
8190 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 8191 "sub{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8192 [(set_attr "type" "alu")
8193 (set_attr "mode" "SI")])
886c62d1 8194
9b70259d 8195(define_insn "*subsi_3_zext"
42fabf21 8196 [(set (reg FLAGS_REG)
10e9fecc 8197 (compare (match_operand:SI 1 "register_operand" "0")
73f48658 8198 (match_operand:SI 2 "general_operand" "g")))
9b70259d
JH
8199 (set (match_operand:DI 0 "register_operand" "=r")
8200 (zero_extend:DI
8201 (minus:SI (match_dup 1)
8202 (match_dup 2))))]
8362f420 8203 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
9b70259d 8204 && ix86_binary_operator_ok (MINUS, SImode, operands)"
3dcdd4e4 8205 "sub{l}\t{%2, %1|%1, %2}"
9b70259d
JH
8206 [(set_attr "type" "alu")
8207 (set_attr "mode" "DI")])
8208
2ae0f82c 8209(define_expand "subhi3"
7ae14d31
UB
8210 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8211 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
8212 (match_operand:HI 2 "general_operand" "")))]
d9f32422 8213 "TARGET_HIMODE_MATH"
e075ae69 8214 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
2ae0f82c 8215
e075ae69 8216(define_insn "*subhi_1"
2ae0f82c 8217 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
87fd1847 8218 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
0edb82cb 8219 (match_operand:HI 2 "general_operand" "rn,rm")))
8bc527af 8220 (clobber (reg:CC FLAGS_REG))]
2ae0f82c 8221 "ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 8222 "sub{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8223 [(set_attr "type" "alu")
8224 (set_attr "mode" "HI")])
e075ae69
RH
8225
8226(define_insn "*subhi_2"
42fabf21 8227 [(set (reg FLAGS_REG)
16189740 8228 (compare
e075ae69 8229 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
0edb82cb 8230 (match_operand:HI 2 "general_operand" "rn,rm"))
e075ae69
RH
8231 (const_int 0)))
8232 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8233 (minus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 8234 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 8235 && ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 8236 "sub{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8237 [(set_attr "type" "alu")
8238 (set_attr "mode" "HI")])
8239
8240(define_insn "*subhi_3"
42fabf21 8241 [(set (reg FLAGS_REG)
d90ffc8d 8242 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
0edb82cb 8243 (match_operand:HI 2 "general_operand" "rn,rm")))
d90ffc8d
JH
8244 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8245 (minus:HI (match_dup 1) (match_dup 2)))]
16189740
RH
8246 "ix86_match_ccmode (insn, CCmode)
8247 && ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 8248 "sub{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8249 [(set_attr "type" "alu")
8250 (set_attr "mode" "HI")])
886c62d1 8251
2ae0f82c 8252(define_expand "subqi3"
7ae14d31
UB
8253 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8254 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
8255 (match_operand:QI 2 "general_operand" "")))]
d9f32422 8256 "TARGET_QIMODE_MATH"
e075ae69 8257 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
2ae0f82c 8258
e075ae69 8259(define_insn "*subqi_1"
2ae0f82c
SC
8260 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8261 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
0edb82cb 8262 (match_operand:QI 2 "general_operand" "qn,qm")))
8bc527af 8263 (clobber (reg:CC FLAGS_REG))]
e075ae69 8264 "ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 8265 "sub{b}\t{%2, %0|%0, %2}"
6ef67412
JH
8266 [(set_attr "type" "alu")
8267 (set_attr "mode" "QI")])
e075ae69 8268
2f41793e
JH
8269(define_insn "*subqi_1_slp"
8270 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1b245ade 8271 (minus:QI (match_dup 0)
0edb82cb 8272 (match_operand:QI 1 "general_operand" "qn,qm")))
8bc527af 8273 (clobber (reg:CC FLAGS_REG))]
3debdc1e 8274 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 8275 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1b245ade 8276 "sub{b}\t{%1, %0|%0, %1}"
95199202 8277 [(set_attr "type" "alu1")
2f41793e
JH
8278 (set_attr "mode" "QI")])
8279
e075ae69 8280(define_insn "*subqi_2"
42fabf21 8281 [(set (reg FLAGS_REG)
16189740 8282 (compare
e075ae69 8283 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
0edb82cb 8284 (match_operand:QI 2 "general_operand" "qn,qm"))
e075ae69 8285 (const_int 0)))
0edb82cb
UB
8286 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8287 (minus:QI (match_dup 1) (match_dup 2)))]
9076b9c1 8288 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 8289 && ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 8290 "sub{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8291 [(set_attr "type" "alu")
8292 (set_attr "mode" "QI")])
8293
8294(define_insn "*subqi_3"
42fabf21 8295 [(set (reg FLAGS_REG)
d90ffc8d 8296 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
0edb82cb
UB
8297 (match_operand:QI 2 "general_operand" "qn,qm")))
8298 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8299 (minus:QI (match_dup 1) (match_dup 2)))]
16189740
RH
8300 "ix86_match_ccmode (insn, CCmode)
8301 && ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 8302 "sub{b}\t{%2, %0|%0, %2}"
6ef67412
JH
8303 [(set_attr "type" "alu")
8304 (set_attr "mode" "QI")])
2ae0f82c 8305
886c62d1
JVA
8306;; The patterns that match these are at the end of this file.
8307
4fb21e90
JVA
8308(define_expand "subxf3"
8309 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
8310 (minus:XF (match_operand:XF 1 "register_operand" "")
8311 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
8312 "TARGET_80387"
8313 "")
8314
00188daa
UB
8315(define_expand "sub<mode>3"
8316 [(set (match_operand:MODEF 0 "register_operand" "")
8317 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
8318 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8ce94e44
JM
8319 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8320 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
886c62d1
JVA
8321 "")
8322\f
e075ae69 8323;; Multiply instructions
886c62d1 8324
9b70259d
JH
8325(define_expand "muldi3"
8326 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8327 (mult:DI (match_operand:DI 1 "register_operand" "")
8328 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 8329 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
8330 "TARGET_64BIT"
8331 "")
8332
4f3f76e6 8333;; On AMDFAM10
21efb4d4
HJ
8334;; IMUL reg64, reg64, imm8 Direct
8335;; IMUL reg64, mem64, imm8 VectorPath
8336;; IMUL reg64, reg64, imm32 Direct
4f3f76e6 8337;; IMUL reg64, mem64, imm32 VectorPath
21efb4d4
HJ
8338;; IMUL reg64, reg64 Direct
8339;; IMUL reg64, mem64 Direct
8340
9b70259d
JH
8341(define_insn "*muldi3_1_rex64"
8342 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
f56e86bd 8343 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
9b70259d 8344 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
8bc527af 8345 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 8346 "TARGET_64BIT
7656aee4 8347 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9b70259d 8348 "@
0f40f9f7
ZW
8349 imul{q}\t{%2, %1, %0|%0, %1, %2}
8350 imul{q}\t{%2, %1, %0|%0, %1, %2}
8351 imul{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8352 [(set_attr "type" "imul")
8353 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
8354 (set (attr "athlon_decode")
8355 (cond [(eq_attr "cpu" "athlon")
8356 (const_string "vector")
8357 (eq_attr "alternative" "1")
8358 (const_string "vector")
8359 (and (eq_attr "alternative" "2")
8360 (match_operand 1 "memory_operand" ""))
8361 (const_string "vector")]
8362 (const_string "direct")))
21efb4d4
HJ
8363 (set (attr "amdfam10_decode")
8364 (cond [(and (eq_attr "alternative" "0,1")
8365 (match_operand 1 "memory_operand" ""))
8366 (const_string "vector")]
4f3f76e6 8367 (const_string "direct")))
9b70259d
JH
8368 (set_attr "mode" "DI")])
8369
d525dfdf
JH
8370(define_expand "mulsi3"
8371 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8372 (mult:SI (match_operand:SI 1 "register_operand" "")
8373 (match_operand:SI 2 "general_operand" "")))
8bc527af 8374 (clobber (reg:CC FLAGS_REG))])]
d525dfdf
JH
8375 ""
8376 "")
8377
4f3f76e6 8378;; On AMDFAM10
21efb4d4
HJ
8379;; IMUL reg32, reg32, imm8 Direct
8380;; IMUL reg32, mem32, imm8 VectorPath
8381;; IMUL reg32, reg32, imm32 Direct
8382;; IMUL reg32, mem32, imm32 VectorPath
8383;; IMUL reg32, reg32 Direct
8384;; IMUL reg32, mem32 Direct
8385
d525dfdf 8386(define_insn "*mulsi3_1"
e075ae69 8387 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
f56e86bd 8388 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
e075ae69 8389 (match_operand:SI 2 "general_operand" "K,i,mr")))
8bc527af 8390 (clobber (reg:CC FLAGS_REG))]
7656aee4 8391 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
e075ae69 8392 "@
0f40f9f7
ZW
8393 imul{l}\t{%2, %1, %0|%0, %1, %2}
8394 imul{l}\t{%2, %1, %0|%0, %1, %2}
8395 imul{l}\t{%2, %0|%0, %2}"
e075ae69 8396 [(set_attr "type" "imul")
6ef67412 8397 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
8398 (set (attr "athlon_decode")
8399 (cond [(eq_attr "cpu" "athlon")
8400 (const_string "vector")
8401 (eq_attr "alternative" "1")
8402 (const_string "vector")
8403 (and (eq_attr "alternative" "2")
8404 (match_operand 1 "memory_operand" ""))
8405 (const_string "vector")]
8406 (const_string "direct")))
21efb4d4
HJ
8407 (set (attr "amdfam10_decode")
8408 (cond [(and (eq_attr "alternative" "0,1")
8409 (match_operand 1 "memory_operand" ""))
8410 (const_string "vector")]
4f3f76e6 8411 (const_string "direct")))
6ef67412 8412 (set_attr "mode" "SI")])
886c62d1 8413
9b70259d
JH
8414(define_insn "*mulsi3_1_zext"
8415 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8416 (zero_extend:DI
f56e86bd 8417 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9b70259d 8418 (match_operand:SI 2 "general_operand" "K,i,mr"))))
8bc527af 8419 (clobber (reg:CC FLAGS_REG))]
9b70259d 8420 "TARGET_64BIT
7656aee4 8421 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9b70259d 8422 "@
0f40f9f7
ZW
8423 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8424 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8425 imul{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8426 [(set_attr "type" "imul")
8427 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
8428 (set (attr "athlon_decode")
8429 (cond [(eq_attr "cpu" "athlon")
8430 (const_string "vector")
8431 (eq_attr "alternative" "1")
8432 (const_string "vector")
8433 (and (eq_attr "alternative" "2")
8434 (match_operand 1 "memory_operand" ""))
8435 (const_string "vector")]
8436 (const_string "direct")))
21efb4d4
HJ
8437 (set (attr "amdfam10_decode")
8438 (cond [(and (eq_attr "alternative" "0,1")
8439 (match_operand 1 "memory_operand" ""))
8440 (const_string "vector")]
4f3f76e6 8441 (const_string "direct")))
9b70259d
JH
8442 (set_attr "mode" "SI")])
8443
d525dfdf
JH
8444(define_expand "mulhi3"
8445 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8446 (mult:HI (match_operand:HI 1 "register_operand" "")
8447 (match_operand:HI 2 "general_operand" "")))
8bc527af 8448 (clobber (reg:CC FLAGS_REG))])]
d9f32422 8449 "TARGET_HIMODE_MATH"
d525dfdf
JH
8450 "")
8451
21efb4d4
HJ
8452;; On AMDFAM10
8453;; IMUL reg16, reg16, imm8 VectorPath
8454;; IMUL reg16, mem16, imm8 VectorPath
8455;; IMUL reg16, reg16, imm16 VectorPath
8456;; IMUL reg16, mem16, imm16 VectorPath
8457;; IMUL reg16, reg16 Direct
8458;; IMUL reg16, mem16 Direct
d525dfdf 8459(define_insn "*mulhi3_1"
6ef67412 8460 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
f56e86bd 8461 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
0edb82cb 8462 (match_operand:HI 2 "general_operand" "K,n,mr")))
8bc527af 8463 (clobber (reg:CC FLAGS_REG))]
7656aee4 8464 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
e075ae69 8465 "@
0f40f9f7
ZW
8466 imul{w}\t{%2, %1, %0|%0, %1, %2}
8467 imul{w}\t{%2, %1, %0|%0, %1, %2}
8468 imul{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8469 [(set_attr "type" "imul")
8470 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
8471 (set (attr "athlon_decode")
8472 (cond [(eq_attr "cpu" "athlon")
8473 (const_string "vector")
8474 (eq_attr "alternative" "1,2")
8475 (const_string "vector")]
8476 (const_string "direct")))
21efb4d4
HJ
8477 (set (attr "amdfam10_decode")
8478 (cond [(eq_attr "alternative" "0,1")
8479 (const_string "vector")]
8480 (const_string "direct")))
6ef67412 8481 (set_attr "mode" "HI")])
886c62d1 8482
558740bf
JH
8483(define_expand "mulqi3"
8484 [(parallel [(set (match_operand:QI 0 "register_operand" "")
8485 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8486 (match_operand:QI 2 "register_operand" "")))
8bc527af 8487 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8488 "TARGET_QIMODE_MATH"
8489 "")
8490
21efb4d4
HJ
8491;;On AMDFAM10
8492;; MUL reg8 Direct
8493;; MUL mem8 Direct
8494
558740bf 8495(define_insn "*mulqi3_1"
765a46f9 8496 [(set (match_operand:QI 0 "register_operand" "=a")
558740bf 8497 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
765a46f9 8498 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8bc527af 8499 (clobber (reg:CC FLAGS_REG))]
558740bf 8500 "TARGET_QIMODE_MATH
7656aee4 8501 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8502 "mul{b}\t%2"
6ef67412
JH
8503 [(set_attr "type" "imul")
8504 (set_attr "length_immediate" "0")
f56e86bd
JH
8505 (set (attr "athlon_decode")
8506 (if_then_else (eq_attr "cpu" "athlon")
8507 (const_string "vector")
8508 (const_string "direct")))
4f3f76e6 8509 (set_attr "amdfam10_decode" "direct")
6ef67412 8510 (set_attr "mode" "QI")])
765a46f9 8511
558740bf
JH
8512(define_expand "umulqihi3"
8513 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8514 (mult:HI (zero_extend:HI
8515 (match_operand:QI 1 "nonimmediate_operand" ""))
8516 (zero_extend:HI
8517 (match_operand:QI 2 "register_operand" ""))))
8bc527af 8518 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8519 "TARGET_QIMODE_MATH"
8520 "")
8521
8522(define_insn "*umulqihi3_1"
2ae0f82c 8523 [(set (match_operand:HI 0 "register_operand" "=a")
558740bf 8524 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
e075ae69 8525 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8bc527af 8526 (clobber (reg:CC FLAGS_REG))]
558740bf 8527 "TARGET_QIMODE_MATH
7656aee4 8528 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8529 "mul{b}\t%2"
6ef67412
JH
8530 [(set_attr "type" "imul")
8531 (set_attr "length_immediate" "0")
f56e86bd
JH
8532 (set (attr "athlon_decode")
8533 (if_then_else (eq_attr "cpu" "athlon")
8534 (const_string "vector")
8535 (const_string "direct")))
04e1d06b 8536 (set_attr "amdfam10_decode" "direct")
6ef67412 8537 (set_attr "mode" "QI")])
886c62d1 8538
558740bf
JH
8539(define_expand "mulqihi3"
8540 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8541 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8542 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8bc527af 8543 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8544 "TARGET_QIMODE_MATH"
8545 "")
8546
8547(define_insn "*mulqihi3_insn"
2ae0f82c 8548 [(set (match_operand:HI 0 "register_operand" "=a")
558740bf 8549 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
e075ae69 8550 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8bc527af 8551 (clobber (reg:CC FLAGS_REG))]
558740bf 8552 "TARGET_QIMODE_MATH
7656aee4 8553 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8554 "imul{b}\t%2"
6ef67412
JH
8555 [(set_attr "type" "imul")
8556 (set_attr "length_immediate" "0")
f56e86bd
JH
8557 (set (attr "athlon_decode")
8558 (if_then_else (eq_attr "cpu" "athlon")
8559 (const_string "vector")
8560 (const_string "direct")))
4f3f76e6 8561 (set_attr "amdfam10_decode" "direct")
6ef67412 8562 (set_attr "mode" "QI")])
4b71cd6e 8563
558740bf
JH
8564(define_expand "umulditi3"
8565 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8566 (mult:TI (zero_extend:TI
8567 (match_operand:DI 1 "nonimmediate_operand" ""))
8568 (zero_extend:TI
8569 (match_operand:DI 2 "register_operand" ""))))
8bc527af 8570 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8571 "TARGET_64BIT"
8572 "")
8573
8574(define_insn "*umulditi3_insn"
9b70259d 8575 [(set (match_operand:TI 0 "register_operand" "=A")
558740bf 8576 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
9b70259d 8577 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8bc527af 8578 (clobber (reg:CC FLAGS_REG))]
558740bf 8579 "TARGET_64BIT
7656aee4 8580 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8581 "mul{q}\t%2"
1e07edd3 8582 [(set_attr "type" "imul")
1e07edd3 8583 (set_attr "length_immediate" "0")
f56e86bd
JH
8584 (set (attr "athlon_decode")
8585 (if_then_else (eq_attr "cpu" "athlon")
8586 (const_string "vector")
8587 (const_string "double")))
4f3f76e6 8588 (set_attr "amdfam10_decode" "double")
9b70259d 8589 (set_attr "mode" "DI")])
1e07edd3
JH
8590
8591;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
558740bf
JH
8592(define_expand "umulsidi3"
8593 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8594 (mult:DI (zero_extend:DI
8595 (match_operand:SI 1 "nonimmediate_operand" ""))
8596 (zero_extend:DI
8597 (match_operand:SI 2 "register_operand" ""))))
8bc527af 8598 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8599 "!TARGET_64BIT"
8600 "")
8601
8602(define_insn "*umulsidi3_insn"
4b71cd6e 8603 [(set (match_operand:DI 0 "register_operand" "=A")
558740bf 8604 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
e075ae69 8605 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8bc527af 8606 (clobber (reg:CC FLAGS_REG))]
558740bf 8607 "!TARGET_64BIT
7656aee4 8608 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8609 "mul{l}\t%2"
e075ae69 8610 [(set_attr "type" "imul")
6ef67412 8611 (set_attr "length_immediate" "0")
f56e86bd
JH
8612 (set (attr "athlon_decode")
8613 (if_then_else (eq_attr "cpu" "athlon")
8614 (const_string "vector")
8615 (const_string "double")))
4f3f76e6 8616 (set_attr "amdfam10_decode" "double")
6ef67412 8617 (set_attr "mode" "SI")])
4b71cd6e 8618
558740bf
JH
8619(define_expand "mulditi3"
8620 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8621 (mult:TI (sign_extend:TI
8622 (match_operand:DI 1 "nonimmediate_operand" ""))
8623 (sign_extend:TI
8624 (match_operand:DI 2 "register_operand" ""))))
8bc527af 8625 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8626 "TARGET_64BIT"
8627 "")
8628
8629(define_insn "*mulditi3_insn"
9b70259d 8630 [(set (match_operand:TI 0 "register_operand" "=A")
558740bf 8631 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
9b70259d 8632 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8bc527af 8633 (clobber (reg:CC FLAGS_REG))]
558740bf 8634 "TARGET_64BIT
7656aee4 8635 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8636 "imul{q}\t%2"
9b70259d
JH
8637 [(set_attr "type" "imul")
8638 (set_attr "length_immediate" "0")
f56e86bd
JH
8639 (set (attr "athlon_decode")
8640 (if_then_else (eq_attr "cpu" "athlon")
8641 (const_string "vector")
8642 (const_string "double")))
21efb4d4 8643 (set_attr "amdfam10_decode" "double")
9b70259d
JH
8644 (set_attr "mode" "DI")])
8645
558740bf
JH
8646(define_expand "mulsidi3"
8647 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8648 (mult:DI (sign_extend:DI
8649 (match_operand:SI 1 "nonimmediate_operand" ""))
8650 (sign_extend:DI
8651 (match_operand:SI 2 "register_operand" ""))))
8bc527af 8652 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8653 "!TARGET_64BIT"
8654 "")
8655
8656(define_insn "*mulsidi3_insn"
4b71cd6e 8657 [(set (match_operand:DI 0 "register_operand" "=A")
558740bf 8658 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
e075ae69 8659 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8bc527af 8660 (clobber (reg:CC FLAGS_REG))]
558740bf 8661 "!TARGET_64BIT
7656aee4 8662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8663 "imul{l}\t%2"
6ef67412
JH
8664 [(set_attr "type" "imul")
8665 (set_attr "length_immediate" "0")
f56e86bd
JH
8666 (set (attr "athlon_decode")
8667 (if_then_else (eq_attr "cpu" "athlon")
8668 (const_string "vector")
8669 (const_string "double")))
4f3f76e6 8670 (set_attr "amdfam10_decode" "double")
6ef67412 8671 (set_attr "mode" "SI")])
2f2a49e8 8672
558740bf
JH
8673(define_expand "umuldi3_highpart"
8674 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8675 (truncate:DI
8676 (lshiftrt:TI
8677 (mult:TI (zero_extend:TI
8678 (match_operand:DI 1 "nonimmediate_operand" ""))
8679 (zero_extend:TI
8680 (match_operand:DI 2 "register_operand" "")))
8681 (const_int 64))))
8682 (clobber (match_scratch:DI 3 ""))
8bc527af 8683 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8684 "TARGET_64BIT"
8685 "")
8686
9b70259d
JH
8687(define_insn "*umuldi3_highpart_rex64"
8688 [(set (match_operand:DI 0 "register_operand" "=d")
8689 (truncate:DI
8690 (lshiftrt:TI
8691 (mult:TI (zero_extend:TI
558740bf 8692 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9b70259d
JH
8693 (zero_extend:TI
8694 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8695 (const_int 64))))
558740bf 8696 (clobber (match_scratch:DI 3 "=1"))
8bc527af 8697 (clobber (reg:CC FLAGS_REG))]
558740bf 8698 "TARGET_64BIT
7656aee4 8699 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8700 "mul{q}\t%2"
9b70259d 8701 [(set_attr "type" "imul")
9b70259d 8702 (set_attr "length_immediate" "0")
f56e86bd
JH
8703 (set (attr "athlon_decode")
8704 (if_then_else (eq_attr "cpu" "athlon")
8705 (const_string "vector")
8706 (const_string "double")))
4f3f76e6 8707 (set_attr "amdfam10_decode" "double")
9b70259d
JH
8708 (set_attr "mode" "DI")])
8709
558740bf
JH
8710(define_expand "umulsi3_highpart"
8711 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8712 (truncate:SI
8713 (lshiftrt:DI
8714 (mult:DI (zero_extend:DI
8715 (match_operand:SI 1 "nonimmediate_operand" ""))
8716 (zero_extend:DI
8717 (match_operand:SI 2 "register_operand" "")))
8718 (const_int 32))))
8719 (clobber (match_scratch:SI 3 ""))
8bc527af 8720 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8721 ""
8722 "")
8723
8724(define_insn "*umulsi3_highpart_insn"
2f2a49e8 8725 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
8726 (truncate:SI
8727 (lshiftrt:DI
8728 (mult:DI (zero_extend:DI
558740bf 8729 (match_operand:SI 1 "nonimmediate_operand" "%a"))
e075ae69
RH
8730 (zero_extend:DI
8731 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8732 (const_int 32))))
558740bf 8733 (clobber (match_scratch:SI 3 "=1"))
8bc527af 8734 (clobber (reg:CC FLAGS_REG))]
7656aee4 8735 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8736 "mul{l}\t%2"
32ee7d1d 8737 [(set_attr "type" "imul")
32ee7d1d 8738 (set_attr "length_immediate" "0")
f56e86bd
JH
8739 (set (attr "athlon_decode")
8740 (if_then_else (eq_attr "cpu" "athlon")
8741 (const_string "vector")
8742 (const_string "double")))
21efb4d4 8743 (set_attr "amdfam10_decode" "double")
32ee7d1d
JH
8744 (set_attr "mode" "SI")])
8745
8746(define_insn "*umulsi3_highpart_zext"
8747 [(set (match_operand:DI 0 "register_operand" "=d")
8748 (zero_extend:DI (truncate:SI
8749 (lshiftrt:DI
8750 (mult:DI (zero_extend:DI
558740bf 8751 (match_operand:SI 1 "nonimmediate_operand" "%a"))
32ee7d1d
JH
8752 (zero_extend:DI
8753 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8754 (const_int 32)))))
558740bf 8755 (clobber (match_scratch:SI 3 "=1"))
8bc527af 8756 (clobber (reg:CC FLAGS_REG))]
558740bf 8757 "TARGET_64BIT
7656aee4 8758 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8759 "mul{l}\t%2"
e075ae69 8760 [(set_attr "type" "imul")
6ef67412 8761 (set_attr "length_immediate" "0")
f56e86bd
JH
8762 (set (attr "athlon_decode")
8763 (if_then_else (eq_attr "cpu" "athlon")
8764 (const_string "vector")
8765 (const_string "double")))
21efb4d4 8766 (set_attr "amdfam10_decode" "double")
6ef67412 8767 (set_attr "mode" "SI")])
2f2a49e8 8768
558740bf 8769(define_expand "smuldi3_highpart"
00188daa 8770 [(parallel [(set (match_operand:DI 0 "register_operand" "")
558740bf
JH
8771 (truncate:DI
8772 (lshiftrt:TI
8773 (mult:TI (sign_extend:TI
8774 (match_operand:DI 1 "nonimmediate_operand" ""))
8775 (sign_extend:TI
8776 (match_operand:DI 2 "register_operand" "")))
8777 (const_int 64))))
8778 (clobber (match_scratch:DI 3 ""))
8bc527af 8779 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8780 "TARGET_64BIT"
8781 "")
8782
9b70259d
JH
8783(define_insn "*smuldi3_highpart_rex64"
8784 [(set (match_operand:DI 0 "register_operand" "=d")
8785 (truncate:DI
8786 (lshiftrt:TI
8787 (mult:TI (sign_extend:TI
558740bf 8788 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9b70259d
JH
8789 (sign_extend:TI
8790 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8791 (const_int 64))))
558740bf 8792 (clobber (match_scratch:DI 3 "=1"))
8bc527af 8793 (clobber (reg:CC FLAGS_REG))]
558740bf 8794 "TARGET_64BIT
7656aee4 8795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8796 "imul{q}\t%2"
9b70259d 8797 [(set_attr "type" "imul")
f56e86bd
JH
8798 (set (attr "athlon_decode")
8799 (if_then_else (eq_attr "cpu" "athlon")
8800 (const_string "vector")
8801 (const_string "double")))
21efb4d4 8802 (set_attr "amdfam10_decode" "double")
9b70259d
JH
8803 (set_attr "mode" "DI")])
8804
558740bf
JH
8805(define_expand "smulsi3_highpart"
8806 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8807 (truncate:SI
8808 (lshiftrt:DI
8809 (mult:DI (sign_extend:DI
8810 (match_operand:SI 1 "nonimmediate_operand" ""))
8811 (sign_extend:DI
8812 (match_operand:SI 2 "register_operand" "")))
8813 (const_int 32))))
8814 (clobber (match_scratch:SI 3 ""))
8bc527af 8815 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
8816 ""
8817 "")
8818
8819(define_insn "*smulsi3_highpart_insn"
2f2a49e8 8820 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
8821 (truncate:SI
8822 (lshiftrt:DI
8823 (mult:DI (sign_extend:DI
558740bf 8824 (match_operand:SI 1 "nonimmediate_operand" "%a"))
e075ae69
RH
8825 (sign_extend:DI
8826 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8827 (const_int 32))))
558740bf 8828 (clobber (match_scratch:SI 3 "=1"))
8bc527af 8829 (clobber (reg:CC FLAGS_REG))]
7656aee4 8830 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8831 "imul{l}\t%2"
e075ae69 8832 [(set_attr "type" "imul")
f56e86bd
JH
8833 (set (attr "athlon_decode")
8834 (if_then_else (eq_attr "cpu" "athlon")
8835 (const_string "vector")
8836 (const_string "double")))
21efb4d4 8837 (set_attr "amdfam10_decode" "double")
6ef67412 8838 (set_attr "mode" "SI")])
4b71cd6e 8839
9b70259d
JH
8840(define_insn "*smulsi3_highpart_zext"
8841 [(set (match_operand:DI 0 "register_operand" "=d")
8842 (zero_extend:DI (truncate:SI
8843 (lshiftrt:DI
8844 (mult:DI (sign_extend:DI
558740bf 8845 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9b70259d
JH
8846 (sign_extend:DI
8847 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8848 (const_int 32)))))
558740bf 8849 (clobber (match_scratch:SI 3 "=1"))
8bc527af 8850 (clobber (reg:CC FLAGS_REG))]
558740bf 8851 "TARGET_64BIT
7656aee4 8852 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 8853 "imul{l}\t%2"
9b70259d 8854 [(set_attr "type" "imul")
f56e86bd
JH
8855 (set (attr "athlon_decode")
8856 (if_then_else (eq_attr "cpu" "athlon")
8857 (const_string "vector")
8858 (const_string "double")))
21efb4d4 8859 (set_attr "amdfam10_decode" "double")
9b70259d
JH
8860 (set_attr "mode" "SI")])
8861
886c62d1
JVA
8862;; The patterns that match these are at the end of this file.
8863
4fb21e90
JVA
8864(define_expand "mulxf3"
8865 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
8866 (mult:XF (match_operand:XF 1 "register_operand" "")
8867 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
8868 "TARGET_80387"
8869 "")
8870
00188daa
UB
8871(define_expand "mul<mode>3"
8872 [(set (match_operand:MODEF 0 "register_operand" "")
8873 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8874 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8ce94e44
JM
8875 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8876 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
886c62d1 8877 "")
04e1d06b
MM
8878
8879;; SSE5 scalar multiply/add instructions are defined in sse.md.
8880
886c62d1 8881\f
e075ae69 8882;; Divide instructions
886c62d1
JVA
8883
8884(define_insn "divqi3"
2ae0f82c
SC
8885 [(set (match_operand:QI 0 "register_operand" "=a")
8886 (div:QI (match_operand:HI 1 "register_operand" "0")
e075ae69 8887 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8bc527af 8888 (clobber (reg:CC FLAGS_REG))]
d9f32422 8889 "TARGET_QIMODE_MATH"
0f40f9f7 8890 "idiv{b}\t%2"
e075ae69 8891 [(set_attr "type" "idiv")
56bab446 8892 (set_attr "mode" "QI")])
886c62d1
JVA
8893
8894(define_insn "udivqi3"
2ae0f82c
SC
8895 [(set (match_operand:QI 0 "register_operand" "=a")
8896 (udiv:QI (match_operand:HI 1 "register_operand" "0")
e075ae69 8897 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8bc527af 8898 (clobber (reg:CC FLAGS_REG))]
d9f32422 8899 "TARGET_QIMODE_MATH"
0f40f9f7 8900 "div{b}\t%2"
e075ae69 8901 [(set_attr "type" "idiv")
56bab446 8902 (set_attr "mode" "QI")])
886c62d1
JVA
8903
8904;; The patterns that match these are at the end of this file.
8905
4fb21e90
JVA
8906(define_expand "divxf3"
8907 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
8908 (div:XF (match_operand:XF 1 "register_operand" "")
8909 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
8910 "TARGET_80387"
8911 "")
8912
a78cb986
SC
8913(define_expand "divdf3"
8914 [(set (match_operand:DF 0 "register_operand" "")
8915 (div:DF (match_operand:DF 1 "register_operand" "")
8916 (match_operand:DF 2 "nonimmediate_operand" "")))]
8ce94e44
JM
8917 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8918 || (TARGET_SSE2 && TARGET_SSE_MATH)"
a78cb986 8919 "")
6300f037 8920
886c62d1
JVA
8921(define_expand "divsf3"
8922 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 8923 (div:SF (match_operand:SF 1 "register_operand" "")
886c62d1 8924 (match_operand:SF 2 "nonimmediate_operand" "")))]
8ce94e44
JM
8925 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8926 || TARGET_SSE_MATH"
6b889d89 8927{
18bd082d 8928 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
6b889d89
UB
8929 && flag_finite_math_only && !flag_trapping_math
8930 && flag_unsafe_math_optimizations)
8931 {
8932 ix86_emit_swdivsf (operands[0], operands[1],
8933 operands[2], SFmode);
8934 DONE;
8935 }
8936})
886c62d1
JVA
8937\f
8938;; Remainder instructions.
9b70259d
JH
8939
8940(define_expand "divmoddi4"
8941 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8942 (div:DI (match_operand:DI 1 "register_operand" "")
8943 (match_operand:DI 2 "nonimmediate_operand" "")))
8944 (set (match_operand:DI 3 "register_operand" "")
8945 (mod:DI (match_dup 1) (match_dup 2)))
8bc527af 8946 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
8947 "TARGET_64BIT"
8948 "")
8949
8950;; Allow to come the parameter in eax or edx to avoid extra moves.
d1f87653 8951;; Penalize eax case slightly because it results in worse scheduling
9b70259d
JH
8952;; of code.
8953(define_insn "*divmoddi4_nocltd_rex64"
8954 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8955 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8956 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8957 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8958 (mod:DI (match_dup 2) (match_dup 3)))
8bc527af 8959 (clobber (reg:CC FLAGS_REG))]
3debdc1e 8960 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
9b70259d
JH
8961 "#"
8962 [(set_attr "type" "multi")])
8963
8964(define_insn "*divmoddi4_cltd_rex64"
8965 [(set (match_operand:DI 0 "register_operand" "=a")
8966 (div:DI (match_operand:DI 2 "register_operand" "a")
8967 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8968 (set (match_operand:DI 1 "register_operand" "=&d")
8969 (mod:DI (match_dup 2) (match_dup 3)))
8bc527af 8970 (clobber (reg:CC FLAGS_REG))]
3debdc1e 8971 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
9b70259d
JH
8972 "#"
8973 [(set_attr "type" "multi")])
8974
8975(define_insn "*divmoddi_noext_rex64"
8976 [(set (match_operand:DI 0 "register_operand" "=a")
8977 (div:DI (match_operand:DI 1 "register_operand" "0")
8978 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8979 (set (match_operand:DI 3 "register_operand" "=d")
8980 (mod:DI (match_dup 1) (match_dup 2)))
8981 (use (match_operand:DI 4 "register_operand" "3"))
8bc527af 8982 (clobber (reg:CC FLAGS_REG))]
9b70259d 8983 "TARGET_64BIT"
0f40f9f7 8984 "idiv{q}\t%2"
9b70259d 8985 [(set_attr "type" "idiv")
56bab446 8986 (set_attr "mode" "DI")])
9b70259d
JH
8987
8988(define_split
8989 [(set (match_operand:DI 0 "register_operand" "")
8990 (div:DI (match_operand:DI 1 "register_operand" "")
8991 (match_operand:DI 2 "nonimmediate_operand" "")))
8992 (set (match_operand:DI 3 "register_operand" "")
8993 (mod:DI (match_dup 1) (match_dup 2)))
8bc527af 8994 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8995 "TARGET_64BIT && reload_completed"
8996 [(parallel [(set (match_dup 3)
8997 (ashiftrt:DI (match_dup 4) (const_int 63)))
8bc527af 8998 (clobber (reg:CC FLAGS_REG))])
9b70259d
JH
8999 (parallel [(set (match_dup 0)
9000 (div:DI (reg:DI 0) (match_dup 2)))
9001 (set (match_dup 3)
9002 (mod:DI (reg:DI 0) (match_dup 2)))
9003 (use (match_dup 3))
8bc527af 9004 (clobber (reg:CC FLAGS_REG))])]
9b70259d 9005{
9cd10576 9006 /* Avoid use of cltd in favor of a mov+shift. */
3debdc1e 9007 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9b70259d
JH
9008 {
9009 if (true_regnum (operands[1]))
9010 emit_move_insn (operands[0], operands[1]);
9011 else
9012 emit_move_insn (operands[3], operands[1]);
9013 operands[4] = operands[3];
9014 }
9015 else
9016 {
7637e42c 9017 gcc_assert (!true_regnum (operands[1]));
9b70259d
JH
9018 operands[4] = operands[1];
9019 }
0f40f9f7 9020})
9b70259d
JH
9021
9022
40745eec
JH
9023(define_expand "divmodsi4"
9024 [(parallel [(set (match_operand:SI 0 "register_operand" "")
9025 (div:SI (match_operand:SI 1 "register_operand" "")
9026 (match_operand:SI 2 "nonimmediate_operand" "")))
9027 (set (match_operand:SI 3 "register_operand" "")
9028 (mod:SI (match_dup 1) (match_dup 2)))
8bc527af 9029 (clobber (reg:CC FLAGS_REG))])]
40745eec
JH
9030 ""
9031 "")
9032
9033;; Allow to come the parameter in eax or edx to avoid extra moves.
d1f87653 9034;; Penalize eax case slightly because it results in worse scheduling
40745eec
JH
9035;; of code.
9036(define_insn "*divmodsi4_nocltd"
9037 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
9038 (div:SI (match_operand:SI 2 "register_operand" "1,0")
9039 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
9040 (set (match_operand:SI 1 "register_operand" "=&d,&d")
9041 (mod:SI (match_dup 2) (match_dup 3)))
8bc527af 9042 (clobber (reg:CC FLAGS_REG))]
3debdc1e 9043 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
40745eec
JH
9044 "#"
9045 [(set_attr "type" "multi")])
886c62d1 9046
40745eec 9047(define_insn "*divmodsi4_cltd"
2bb7a0f5 9048 [(set (match_operand:SI 0 "register_operand" "=a")
40745eec
JH
9049 (div:SI (match_operand:SI 2 "register_operand" "a")
9050 (match_operand:SI 3 "nonimmediate_operand" "rm")))
9051 (set (match_operand:SI 1 "register_operand" "=&d")
9052 (mod:SI (match_dup 2) (match_dup 3)))
8bc527af 9053 (clobber (reg:CC FLAGS_REG))]
3debdc1e 9054 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
40745eec 9055 "#"
e075ae69
RH
9056 [(set_attr "type" "multi")])
9057
6343a50e 9058(define_insn "*divmodsi_noext"
e075ae69 9059 [(set (match_operand:SI 0 "register_operand" "=a")
40745eec 9060 (div:SI (match_operand:SI 1 "register_operand" "0")
e075ae69
RH
9061 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9062 (set (match_operand:SI 3 "register_operand" "=d")
9063 (mod:SI (match_dup 1) (match_dup 2)))
40745eec 9064 (use (match_operand:SI 4 "register_operand" "3"))
8bc527af 9065 (clobber (reg:CC FLAGS_REG))]
e075ae69 9066 ""
0f40f9f7 9067 "idiv{l}\t%2"
e075ae69 9068 [(set_attr "type" "idiv")
56bab446 9069 (set_attr "mode" "SI")])
e075ae69
RH
9070
9071(define_split
9072 [(set (match_operand:SI 0 "register_operand" "")
9073 (div:SI (match_operand:SI 1 "register_operand" "")
9074 (match_operand:SI 2 "nonimmediate_operand" "")))
9075 (set (match_operand:SI 3 "register_operand" "")
9076 (mod:SI (match_dup 1) (match_dup 2)))
8bc527af 9077 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
9078 "reload_completed"
9079 [(parallel [(set (match_dup 3)
9080 (ashiftrt:SI (match_dup 4) (const_int 31)))
8bc527af 9081 (clobber (reg:CC FLAGS_REG))])
e075ae69 9082 (parallel [(set (match_dup 0)
40745eec 9083 (div:SI (reg:SI 0) (match_dup 2)))
e075ae69 9084 (set (match_dup 3)
40745eec 9085 (mod:SI (reg:SI 0) (match_dup 2)))
e075ae69 9086 (use (match_dup 3))
8bc527af 9087 (clobber (reg:CC FLAGS_REG))])]
886c62d1 9088{
9cd10576 9089 /* Avoid use of cltd in favor of a mov+shift. */
3debdc1e 9090 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
e075ae69 9091 {
40745eec
JH
9092 if (true_regnum (operands[1]))
9093 emit_move_insn (operands[0], operands[1]);
9094 else
9095 emit_move_insn (operands[3], operands[1]);
e075ae69
RH
9096 operands[4] = operands[3];
9097 }
9098 else
40745eec 9099 {
7637e42c 9100 gcc_assert (!true_regnum (operands[1]));
40745eec
JH
9101 operands[4] = operands[1];
9102 }
0f40f9f7 9103})
e075ae69 9104;; %%% Split me.
886c62d1 9105(define_insn "divmodhi4"
2bb7a0f5
RS
9106 [(set (match_operand:HI 0 "register_operand" "=a")
9107 (div:HI (match_operand:HI 1 "register_operand" "0")
2ae0f82c 9108 (match_operand:HI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 9109 (set (match_operand:HI 3 "register_operand" "=&d")
e075ae69 9110 (mod:HI (match_dup 1) (match_dup 2)))
8bc527af 9111 (clobber (reg:CC FLAGS_REG))]
d9f32422 9112 "TARGET_HIMODE_MATH"
0f40f9f7 9113 "cwtd\;idiv{w}\t%2"
6ef67412
JH
9114 [(set_attr "type" "multi")
9115 (set_attr "length_immediate" "0")
9116 (set_attr "mode" "SI")])
886c62d1 9117
9b70259d
JH
9118(define_insn "udivmoddi4"
9119 [(set (match_operand:DI 0 "register_operand" "=a")
9120 (udiv:DI (match_operand:DI 1 "register_operand" "0")
9121 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9122 (set (match_operand:DI 3 "register_operand" "=&d")
9123 (umod:DI (match_dup 1) (match_dup 2)))
8bc527af 9124 (clobber (reg:CC FLAGS_REG))]
9b70259d 9125 "TARGET_64BIT"
0f40f9f7 9126 "xor{q}\t%3, %3\;div{q}\t%2"
9b70259d
JH
9127 [(set_attr "type" "multi")
9128 (set_attr "length_immediate" "0")
9129 (set_attr "mode" "DI")])
9130
9131(define_insn "*udivmoddi4_noext"
9132 [(set (match_operand:DI 0 "register_operand" "=a")
9133 (udiv:DI (match_operand:DI 1 "register_operand" "0")
9134 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9135 (set (match_operand:DI 3 "register_operand" "=d")
9136 (umod:DI (match_dup 1) (match_dup 2)))
9137 (use (match_dup 3))
8bc527af 9138 (clobber (reg:CC FLAGS_REG))]
9b70259d 9139 "TARGET_64BIT"
0f40f9f7 9140 "div{q}\t%2"
9b70259d 9141 [(set_attr "type" "idiv")
9b70259d
JH
9142 (set_attr "mode" "DI")])
9143
9144(define_split
9145 [(set (match_operand:DI 0 "register_operand" "")
9146 (udiv:DI (match_operand:DI 1 "register_operand" "")
9147 (match_operand:DI 2 "nonimmediate_operand" "")))
9148 (set (match_operand:DI 3 "register_operand" "")
9149 (umod:DI (match_dup 1) (match_dup 2)))
8bc527af 9150 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 9151 "TARGET_64BIT && reload_completed"
9b70259d
JH
9152 [(set (match_dup 3) (const_int 0))
9153 (parallel [(set (match_dup 0)
9154 (udiv:DI (match_dup 1) (match_dup 2)))
9155 (set (match_dup 3)
9156 (umod:DI (match_dup 1) (match_dup 2)))
9157 (use (match_dup 3))
8bc527af 9158 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
9159 "")
9160
886c62d1 9161(define_insn "udivmodsi4"
2bb7a0f5
RS
9162 [(set (match_operand:SI 0 "register_operand" "=a")
9163 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 9164 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 9165 (set (match_operand:SI 3 "register_operand" "=&d")
e075ae69 9166 (umod:SI (match_dup 1) (match_dup 2)))
8bc527af 9167 (clobber (reg:CC FLAGS_REG))]
886c62d1 9168 ""
0f40f9f7 9169 "xor{l}\t%3, %3\;div{l}\t%2"
6ef67412
JH
9170 [(set_attr "type" "multi")
9171 (set_attr "length_immediate" "0")
9172 (set_attr "mode" "SI")])
886c62d1 9173
6343a50e 9174(define_insn "*udivmodsi4_noext"
2bb7a0f5 9175 [(set (match_operand:SI 0 "register_operand" "=a")
e075ae69 9176 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 9177 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 9178 (set (match_operand:SI 3 "register_operand" "=d")
e075ae69
RH
9179 (umod:SI (match_dup 1) (match_dup 2)))
9180 (use (match_dup 3))
8bc527af 9181 (clobber (reg:CC FLAGS_REG))]
886c62d1 9182 ""
0f40f9f7 9183 "div{l}\t%2"
e075ae69 9184 [(set_attr "type" "idiv")
6ef67412 9185 (set_attr "mode" "SI")])
886c62d1 9186
e075ae69
RH
9187(define_split
9188 [(set (match_operand:SI 0 "register_operand" "")
9189 (udiv:SI (match_operand:SI 1 "register_operand" "")
9190 (match_operand:SI 2 "nonimmediate_operand" "")))
9191 (set (match_operand:SI 3 "register_operand" "")
9192 (umod:SI (match_dup 1) (match_dup 2)))
8bc527af 9193 (clobber (reg:CC FLAGS_REG))]
e075ae69 9194 "reload_completed"
591702de 9195 [(set (match_dup 3) (const_int 0))
e075ae69
RH
9196 (parallel [(set (match_dup 0)
9197 (udiv:SI (match_dup 1) (match_dup 2)))
9198 (set (match_dup 3)
9199 (umod:SI (match_dup 1) (match_dup 2)))
9200 (use (match_dup 3))
8bc527af 9201 (clobber (reg:CC FLAGS_REG))])]
e075ae69 9202 "")
886c62d1 9203
e075ae69 9204(define_expand "udivmodhi4"
591702de 9205 [(set (match_dup 4) (const_int 0))
40745eec
JH
9206 (parallel [(set (match_operand:HI 0 "register_operand" "")
9207 (udiv:HI (match_operand:HI 1 "register_operand" "")
9208 (match_operand:HI 2 "nonimmediate_operand" "")))
9209 (set (match_operand:HI 3 "register_operand" "")
e075ae69
RH
9210 (umod:HI (match_dup 1) (match_dup 2)))
9211 (use (match_dup 4))
8bc527af 9212 (clobber (reg:CC FLAGS_REG))])]
d9f32422 9213 "TARGET_HIMODE_MATH"
e075ae69 9214 "operands[4] = gen_reg_rtx (HImode);")
886c62d1 9215
6343a50e 9216(define_insn "*udivmodhi_noext"
e075ae69
RH
9217 [(set (match_operand:HI 0 "register_operand" "=a")
9218 (udiv:HI (match_operand:HI 1 "register_operand" "0")
9219 (match_operand:HI 2 "nonimmediate_operand" "rm")))
9220 (set (match_operand:HI 3 "register_operand" "=d")
9221 (umod:HI (match_dup 1) (match_dup 2)))
9222 (use (match_operand:HI 4 "register_operand" "3"))
8bc527af 9223 (clobber (reg:CC FLAGS_REG))]
e075ae69 9224 ""
0f40f9f7 9225 "div{w}\t%2"
e075ae69 9226 [(set_attr "type" "idiv")
56bab446 9227 (set_attr "mode" "HI")])
e075ae69 9228
1e5f1716 9229;; We cannot use div/idiv for double division, because it causes
e075ae69
RH
9230;; "division by zero" on the overflow and that's not what we expect
9231;; from truncate. Because true (non truncating) double division is
9232;; never generated, we can't create this insn anyway.
9233;
9234;(define_insn ""
9235; [(set (match_operand:SI 0 "register_operand" "=a")
9236; (truncate:SI
9237; (udiv:DI (match_operand:DI 1 "register_operand" "A")
9238; (zero_extend:DI
9239; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
9240; (set (match_operand:SI 3 "register_operand" "=d")
9241; (truncate:SI
9242; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8bc527af 9243; (clobber (reg:CC FLAGS_REG))]
e075ae69 9244; ""
0f40f9f7 9245; "div{l}\t{%2, %0|%0, %2}"
56bab446 9246; [(set_attr "type" "idiv")])
886c62d1 9247\f
e075ae69
RH
9248;;- Logical AND instructions
9249
9250;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
9251;; Note that this excludes ah.
9252
9b70259d 9253(define_insn "*testdi_1_rex64"
42fabf21 9254 [(set (reg FLAGS_REG)
9b70259d 9255 (compare
2bac97f7 9256 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
e1fea6ee 9257 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
9b70259d 9258 (const_int 0)))]
e1fea6ee 9259 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7656aee4 9260 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9b70259d 9261 "@
5a0855a0
JJ
9262 test{l}\t{%k1, %k0|%k0, %k1}
9263 test{l}\t{%k1, %k0|%k0, %k1}
9264 test{q}\t{%1, %0|%0, %1}
9265 test{q}\t{%1, %0|%0, %1}
0f40f9f7 9266 test{q}\t{%1, %0|%0, %1}"
9b70259d
JH
9267 [(set_attr "type" "test")
9268 (set_attr "modrm" "0,1,0,1,1")
9269 (set_attr "mode" "SI,SI,DI,DI,DI")
9270 (set_attr "pent_pair" "uv,np,uv,np,uv")])
9076b9c1
JH
9271
9272(define_insn "testsi_1"
42fabf21 9273 [(set (reg FLAGS_REG)
9076b9c1 9274 (compare
2bac97f7 9275 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
0edb82cb 9276 (match_operand:SI 1 "general_operand" "i,i,ri"))
16189740 9277 (const_int 0)))]
e1fea6ee 9278 "ix86_match_ccmode (insn, CCNOmode)
7656aee4 9279 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 9280 "test{l}\t{%1, %0|%0, %1}"
6ef67412
JH
9281 [(set_attr "type" "test")
9282 (set_attr "modrm" "0,1,1")
9283 (set_attr "mode" "SI")
e075ae69
RH
9284 (set_attr "pent_pair" "uv,np,uv")])
9285
9076b9c1 9286(define_expand "testsi_ccno_1"
8bc527af 9287 [(set (reg:CCNO FLAGS_REG)
16189740 9288 (compare:CCNO
9076b9c1
JH
9289 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
9290 (match_operand:SI 1 "nonmemory_operand" ""))
16189740 9291 (const_int 0)))]
a1cbdd7f 9292 ""
9076b9c1 9293 "")
16189740
RH
9294
9295(define_insn "*testhi_1"
42fabf21 9296 [(set (reg FLAGS_REG)
2bac97f7 9297 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
e1fea6ee 9298 (match_operand:HI 1 "general_operand" "n,n,rn"))
16189740 9299 (const_int 0)))]
e1fea6ee 9300 "ix86_match_ccmode (insn, CCNOmode)
7656aee4 9301 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 9302 "test{w}\t{%1, %0|%0, %1}"
6ef67412
JH
9303 [(set_attr "type" "test")
9304 (set_attr "modrm" "0,1,1")
9305 (set_attr "mode" "HI")
e075ae69
RH
9306 (set_attr "pent_pair" "uv,np,uv")])
9307
9076b9c1 9308(define_expand "testqi_ccz_1"
8bc527af 9309 [(set (reg:CCZ FLAGS_REG)
9076b9c1
JH
9310 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
9311 (match_operand:QI 1 "nonmemory_operand" ""))
9312 (const_int 0)))]
16189740 9313 ""
9076b9c1 9314 "")
16189740 9315
88d60956 9316(define_insn "*testqi_1_maybe_si"
93330ea1 9317 [(set (reg FLAGS_REG)
88d60956
RH
9318 (compare
9319 (and:QI
9320 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
9321 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
9322 (const_int 0)))]
7656aee4 9323 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
88d60956 9324 && ix86_match_ccmode (insn,
7656aee4 9325 CONST_INT_P (operands[1])
88d60956 9326 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
adc88131
JJ
9327{
9328 if (which_alternative == 3)
9329 {
7656aee4 9330 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
adc88131 9331 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
0f40f9f7 9332 return "test{l}\t{%1, %k0|%k0, %1}";
adc88131 9333 }
0f40f9f7
ZW
9334 return "test{b}\t{%1, %0|%0, %1}";
9335}
6ef67412
JH
9336 [(set_attr "type" "test")
9337 (set_attr "modrm" "0,1,1,1")
9338 (set_attr "mode" "QI,QI,QI,SI")
9339 (set_attr "pent_pair" "uv,np,uv,np")])
e075ae69 9340
88d60956
RH
9341(define_insn "*testqi_1"
9342 [(set (reg FLAGS_REG)
9343 (compare
9344 (and:QI
9345 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
9346 (match_operand:QI 1 "general_operand" "n,n,qn"))
9347 (const_int 0)))]
7656aee4 9348 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
88d60956
RH
9349 && ix86_match_ccmode (insn, CCNOmode)"
9350 "test{b}\t{%1, %0|%0, %1}"
9351 [(set_attr "type" "test")
9352 (set_attr "modrm" "0,1,1")
9353 (set_attr "mode" "QI")
9354 (set_attr "pent_pair" "uv,np,uv")])
9355
9076b9c1 9356(define_expand "testqi_ext_ccno_0"
8bc527af 9357 [(set (reg:CCNO FLAGS_REG)
9076b9c1 9358 (compare:CCNO
16189740
RH
9359 (and:SI
9360 (zero_extract:SI
9076b9c1 9361 (match_operand 0 "ext_register_operand" "")
16189740
RH
9362 (const_int 8)
9363 (const_int 8))
9076b9c1 9364 (match_operand 1 "const_int_operand" ""))
16189740 9365 (const_int 0)))]
9076b9c1
JH
9366 ""
9367 "")
e075ae69 9368
9076b9c1 9369(define_insn "*testqi_ext_0"
42fabf21 9370 [(set (reg FLAGS_REG)
9076b9c1 9371 (compare
e075ae69
RH
9372 (and:SI
9373 (zero_extract:SI
d2836273 9374 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
9375 (const_int 8)
9376 (const_int 8))
9377 (match_operand 1 "const_int_operand" "n"))
9378 (const_int 0)))]
2f41793e 9379 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 9380 "test{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
9381 [(set_attr "type" "test")
9382 (set_attr "mode" "QI")
9383 (set_attr "length_immediate" "1")
725fd454 9384 (set_attr "modrm" "1")
e075ae69
RH
9385 (set_attr "pent_pair" "np")])
9386
9387(define_insn "*testqi_ext_1"
42fabf21 9388 [(set (reg FLAGS_REG)
16189740 9389 (compare
e075ae69
RH
9390 (and:SI
9391 (zero_extract:SI
d2836273 9392 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
9393 (const_int 8)
9394 (const_int 8))
9395 (zero_extend:SI
e1fea6ee 9396 (match_operand:QI 1 "general_operand" "Qm")))
e075ae69 9397 (const_int 0)))]
e1fea6ee 9398 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7656aee4 9399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 9400 "test{b}\t{%1, %h0|%h0, %1}"
d2836273
JH
9401 [(set_attr "type" "test")
9402 (set_attr "mode" "QI")])
9403
9404(define_insn "*testqi_ext_1_rex64"
42fabf21 9405 [(set (reg FLAGS_REG)
d2836273
JH
9406 (compare
9407 (and:SI
9408 (zero_extract:SI
9409 (match_operand 0 "ext_register_operand" "Q")
9410 (const_int 8)
9411 (const_int 8))
9412 (zero_extend:SI
3522082b 9413 (match_operand:QI 1 "register_operand" "Q")))
d2836273
JH
9414 (const_int 0)))]
9415 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 9416 "test{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
9417 [(set_attr "type" "test")
9418 (set_attr "mode" "QI")])
e075ae69
RH
9419
9420(define_insn "*testqi_ext_2"
42fabf21 9421 [(set (reg FLAGS_REG)
16189740 9422 (compare
e075ae69
RH
9423 (and:SI
9424 (zero_extract:SI
d2836273 9425 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
9426 (const_int 8)
9427 (const_int 8))
9428 (zero_extract:SI
d2836273 9429 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
9430 (const_int 8)
9431 (const_int 8)))
9432 (const_int 0)))]
16189740 9433 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 9434 "test{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
9435 [(set_attr "type" "test")
9436 (set_attr "mode" "QI")])
e075ae69
RH
9437
9438;; Combine likes to form bit extractions for some tests. Humor it.
6343a50e 9439(define_insn "*testqi_ext_3"
42fabf21 9440 [(set (reg FLAGS_REG)
16189740
RH
9441 (compare (zero_extract:SI
9442 (match_operand 0 "nonimmediate_operand" "rm")
9443 (match_operand:SI 1 "const_int_operand" "")
9444 (match_operand:SI 2 "const_int_operand" ""))
9445 (const_int 0)))]
9446 "ix86_match_ccmode (insn, CCNOmode)
d90ee6be
JJ
9447 && INTVAL (operands[1]) > 0
9448 && INTVAL (operands[2]) >= 0
9449 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
16189740 9450 && (GET_MODE (operands[0]) == SImode
9b70259d
JH
9451 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
9452 || GET_MODE (operands[0]) == HImode
9453 || GET_MODE (operands[0]) == QImode)"
9454 "#")
9455
9456(define_insn "*testqi_ext_3_rex64"
42fabf21 9457 [(set (reg FLAGS_REG)
9b70259d
JH
9458 (compare (zero_extract:DI
9459 (match_operand 0 "nonimmediate_operand" "rm")
9460 (match_operand:DI 1 "const_int_operand" "")
9461 (match_operand:DI 2 "const_int_operand" ""))
9462 (const_int 0)))]
1b0c37d7
ZW
9463 "TARGET_64BIT
9464 && ix86_match_ccmode (insn, CCNOmode)
d90ee6be
JJ
9465 && INTVAL (operands[1]) > 0
9466 && INTVAL (operands[2]) >= 0
44cf5b6a
JH
9467 /* Ensure that resulting mask is zero or sign extended operand. */
9468 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9469 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9470 && INTVAL (operands[1]) > 32))
9b70259d
JH
9471 && (GET_MODE (operands[0]) == SImode
9472 || GET_MODE (operands[0]) == DImode
16189740
RH
9473 || GET_MODE (operands[0]) == HImode
9474 || GET_MODE (operands[0]) == QImode)"
e075ae69 9475 "#")
4fce8e83 9476
e075ae69 9477(define_split
25da5dc7
RH
9478 [(set (match_operand 0 "flags_reg_operand" "")
9479 (match_operator 1 "compare_operator"
9480 [(zero_extract
9481 (match_operand 2 "nonimmediate_operand" "")
9482 (match_operand 3 "const_int_operand" "")
9483 (match_operand 4 "const_int_operand" ""))
9484 (const_int 0)]))]
16189740 9485 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7 9486 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
e075ae69 9487{
25da5dc7
RH
9488 rtx val = operands[2];
9489 HOST_WIDE_INT len = INTVAL (operands[3]);
9490 HOST_WIDE_INT pos = INTVAL (operands[4]);
e075ae69 9491 HOST_WIDE_INT mask;
592188a5 9492 enum machine_mode mode, submode;
886c62d1 9493
25da5dc7 9494 mode = GET_MODE (val);
7656aee4 9495 if (MEM_P (val))
5bc7cd8e 9496 {
e075ae69
RH
9497 /* ??? Combine likes to put non-volatile mem extractions in QImode
9498 no matter the size of the test. So find a mode that works. */
25da5dc7 9499 if (! MEM_VOLATILE_P (val))
e075ae69
RH
9500 {
9501 mode = smallest_mode_for_size (pos + len, MODE_INT);
25da5dc7 9502 val = adjust_address (val, mode, 0);
e075ae69 9503 }
5bc7cd8e 9504 }
25da5dc7
RH
9505 else if (GET_CODE (val) == SUBREG
9506 && (submode = GET_MODE (SUBREG_REG (val)),
592188a5
RH
9507 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9508 && pos + len <= GET_MODE_BITSIZE (submode))
9509 {
9510 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9511 mode = submode;
25da5dc7 9512 val = SUBREG_REG (val);
592188a5 9513 }
e075ae69 9514 else if (mode == HImode && pos + len <= 8)
5bc7cd8e 9515 {
e075ae69
RH
9516 /* Small HImode tests can be converted to QImode. */
9517 mode = QImode;
25da5dc7 9518 val = gen_lowpart (QImode, val);
5bc7cd8e
SC
9519 }
9520
d90ee6be
JJ
9521 if (len == HOST_BITS_PER_WIDE_INT)
9522 mask = -1;
9523 else
9524 mask = ((HOST_WIDE_INT)1 << len) - 1;
9525 mask <<= pos;
886c62d1 9526
25da5dc7 9527 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
0f40f9f7 9528})
886c62d1 9529
6c81a490
JH
9530;; Convert HImode/SImode test instructions with immediate to QImode ones.
9531;; i386 does not allow to encode test with 8bit sign extended immediate, so
9532;; this is relatively important trick.
d1f87653 9533;; Do the conversion only post-reload to avoid limiting of the register class
6c81a490
JH
9534;; to QI regs.
9535(define_split
25da5dc7
RH
9536 [(set (match_operand 0 "flags_reg_operand" "")
9537 (match_operator 1 "compare_operator"
9538 [(and (match_operand 2 "register_operand" "")
9539 (match_operand 3 "const_int_operand" ""))
9540 (const_int 0)]))]
2f41793e 9541 "reload_completed
25da5dc7
RH
9542 && QI_REG_P (operands[2])
9543 && GET_MODE (operands[2]) != QImode
6c81a490 9544 && ((ix86_match_ccmode (insn, CCZmode)
25da5dc7 9545 && !(INTVAL (operands[3]) & ~(255 << 8)))
6c81a490 9546 || (ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
9547 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9548 [(set (match_dup 0)
9549 (match_op_dup 1
9550 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9551 (match_dup 3))
9552 (const_int 0)]))]
9553 "operands[2] = gen_lowpart (SImode, operands[2]);
9554 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
6c81a490
JH
9555
9556(define_split
25da5dc7
RH
9557 [(set (match_operand 0 "flags_reg_operand" "")
9558 (match_operator 1 "compare_operator"
9559 [(and (match_operand 2 "nonimmediate_operand" "")
9560 (match_operand 3 "const_int_operand" ""))
9561 (const_int 0)]))]
2f41793e 9562 "reload_completed
25da5dc7
RH
9563 && GET_MODE (operands[2]) != QImode
9564 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
6c81a490 9565 && ((ix86_match_ccmode (insn, CCZmode)
25da5dc7 9566 && !(INTVAL (operands[3]) & ~255))
6c81a490 9567 || (ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
9568 && !(INTVAL (operands[3]) & ~127)))"
9569 [(set (match_dup 0)
9570 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9571 (const_int 0)]))]
9572 "operands[2] = gen_lowpart (QImode, operands[2]);
9573 operands[3] = gen_lowpart (QImode, operands[3]);")
6c81a490
JH
9574
9575
e075ae69
RH
9576;; %%% This used to optimize known byte-wide and operations to memory,
9577;; and sometimes to QImode registers. If this is considered useful,
9578;; it should be done with splitters.
9579
9b70259d
JH
9580(define_expand "anddi3"
9581 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9582 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7ae14d31 9583 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9b70259d
JH
9584 "TARGET_64BIT"
9585 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9586
9587(define_insn "*anddi_1_rex64"
9588 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9589 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9590 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8bc527af 9591 (clobber (reg:CC FLAGS_REG))]
9b70259d 9592 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9b70259d
JH
9593{
9594 switch (get_attr_type (insn))
9595 {
9596 case TYPE_IMOVX:
9597 {
9598 enum machine_mode mode;
9599
7656aee4 9600 gcc_assert (CONST_INT_P (operands[2]));
9b70259d
JH
9601 if (INTVAL (operands[2]) == 0xff)
9602 mode = QImode;
9b70259d 9603 else
7637e42c
NS
9604 {
9605 gcc_assert (INTVAL (operands[2]) == 0xffff);
9606 mode = HImode;
9607 }
6300f037 9608
9b70259d
JH
9609 operands[1] = gen_lowpart (mode, operands[1]);
9610 if (mode == QImode)
725fd454 9611 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
9b70259d 9612 else
725fd454 9613 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
9b70259d
JH
9614 }
9615
9616 default:
7637e42c 9617 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9b70259d 9618 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 9619 return "and{l}\t{%k2, %k0|%k0, %k2}";
9b70259d 9620 else
0f40f9f7 9621 return "and{q}\t{%2, %0|%0, %2}";
9b70259d 9622 }
0f40f9f7 9623}
9b70259d
JH
9624 [(set_attr "type" "alu,alu,alu,imovx")
9625 (set_attr "length_immediate" "*,*,*,0")
725fd454
JJ
9626 (set (attr "prefix_rex")
9627 (if_then_else
9628 (and (eq_attr "type" "imovx")
9629 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9630 (match_operand 1 "ext_QIreg_nomode_operand" "")))
9631 (const_string "1")
9632 (const_string "*")))
9633 (set_attr "mode" "SI,DI,DI,SI")])
9b70259d
JH
9634
9635(define_insn "*anddi_2"
42fabf21 9636 [(set (reg FLAGS_REG)
9b70259d
JH
9637 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9638 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9639 (const_int 0)))
9640 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9641 (and:DI (match_dup 1) (match_dup 2)))]
9642 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9643 && ix86_binary_operator_ok (AND, DImode, operands)"
9644 "@
5a0855a0
JJ
9645 and{l}\t{%k2, %k0|%k0, %k2}
9646 and{q}\t{%2, %0|%0, %2}
0f40f9f7 9647 and{q}\t{%2, %0|%0, %2}"
9b70259d
JH
9648 [(set_attr "type" "alu")
9649 (set_attr "mode" "SI,DI,DI")])
9650
e075ae69
RH
9651(define_expand "andsi3"
9652 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9653 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7ae14d31 9654 (match_operand:SI 2 "general_operand" "")))]
e075ae69
RH
9655 ""
9656 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9657
9658(define_insn "*andsi_1"
9659 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9660 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9661 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8bc527af 9662 (clobber (reg:CC FLAGS_REG))]
e075ae69 9663 "ix86_binary_operator_ok (AND, SImode, operands)"
886c62d1 9664{
e075ae69 9665 switch (get_attr_type (insn))
886c62d1 9666 {
e075ae69
RH
9667 case TYPE_IMOVX:
9668 {
9669 enum machine_mode mode;
5bc7cd8e 9670
7656aee4 9671 gcc_assert (CONST_INT_P (operands[2]));
e075ae69
RH
9672 if (INTVAL (operands[2]) == 0xff)
9673 mode = QImode;
e075ae69 9674 else
7637e42c
NS
9675 {
9676 gcc_assert (INTVAL (operands[2]) == 0xffff);
9677 mode = HImode;
9678 }
6300f037 9679
e075ae69
RH
9680 operands[1] = gen_lowpart (mode, operands[1]);
9681 if (mode == QImode)
725fd454 9682 return "movz{bl|x}\t{%1, %0|%0, %1}";
e075ae69 9683 else
725fd454 9684 return "movz{wl|x}\t{%1, %0|%0, %1}";
e075ae69 9685 }
5bc7cd8e 9686
e075ae69 9687 default:
7637e42c 9688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
0f40f9f7 9689 return "and{l}\t{%2, %0|%0, %2}";
886c62d1 9690 }
0f40f9f7 9691}
6ef67412 9692 [(set_attr "type" "alu,alu,imovx")
725fd454
JJ
9693 (set (attr "prefix_rex")
9694 (if_then_else
9695 (and (eq_attr "type" "imovx")
9696 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9697 (match_operand 1 "ext_QIreg_nomode_operand" "")))
9698 (const_string "1")
9699 (const_string "*")))
6ef67412
JH
9700 (set_attr "length_immediate" "*,*,0")
9701 (set_attr "mode" "SI")])
9702
9703(define_split
05b432db 9704 [(set (match_operand 0 "register_operand" "")
9b70259d
JH
9705 (and (match_dup 0)
9706 (const_int -65536)))
8bc527af 9707 (clobber (reg:CC FLAGS_REG))]
3debdc1e 9708 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
6ef67412
JH
9709 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9710 "operands[1] = gen_lowpart (HImode, operands[0]);")
9711
9712(define_split
3522082b 9713 [(set (match_operand 0 "ext_register_operand" "")
5e1a2fc7 9714 (and (match_dup 0)
9b70259d 9715 (const_int -256)))
8bc527af 9716 (clobber (reg:CC FLAGS_REG))]
3debdc1e 9717 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
6ef67412
JH
9718 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9719 "operands[1] = gen_lowpart (QImode, operands[0]);")
9720
9721(define_split
3522082b 9722 [(set (match_operand 0 "ext_register_operand" "")
6ef67412
JH
9723 (and (match_dup 0)
9724 (const_int -65281)))
8bc527af 9725 (clobber (reg:CC FLAGS_REG))]
3debdc1e 9726 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
6ef67412
JH
9727 [(parallel [(set (zero_extract:SI (match_dup 0)
9728 (const_int 8)
9729 (const_int 8))
6300f037 9730 (xor:SI
6ef67412
JH
9731 (zero_extract:SI (match_dup 0)
9732 (const_int 8)
9733 (const_int 8))
9734 (zero_extract:SI (match_dup 0)
9735 (const_int 8)
9736 (const_int 8))))
8bc527af 9737 (clobber (reg:CC FLAGS_REG))])]
6ef67412 9738 "operands[0] = gen_lowpart (SImode, operands[0]);")
e075ae69 9739
9b70259d
JH
9740;; See comment for addsi_1_zext why we do use nonimmediate_operand
9741(define_insn "*andsi_1_zext"
9742 [(set (match_operand:DI 0 "register_operand" "=r")
9743 (zero_extend:DI
9744 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
73f48658 9745 (match_operand:SI 2 "general_operand" "g"))))
8bc527af 9746 (clobber (reg:CC FLAGS_REG))]
9b70259d 9747 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 9748 "and{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
9749 [(set_attr "type" "alu")
9750 (set_attr "mode" "SI")])
9751
e075ae69 9752(define_insn "*andsi_2"
42fabf21 9753 [(set (reg FLAGS_REG)
16189740 9754 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
73f48658 9755 (match_operand:SI 2 "general_operand" "g,ri"))
16189740 9756 (const_int 0)))
e075ae69
RH
9757 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9758 (and:SI (match_dup 1) (match_dup 2)))]
16189740
RH
9759 "ix86_match_ccmode (insn, CCNOmode)
9760 && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 9761 "and{l}\t{%2, %0|%0, %2}"
6ef67412
JH
9762 [(set_attr "type" "alu")
9763 (set_attr "mode" "SI")])
e075ae69 9764
9b70259d
JH
9765;; See comment for addsi_1_zext why we do use nonimmediate_operand
9766(define_insn "*andsi_2_zext"
42fabf21 9767 [(set (reg FLAGS_REG)
9b70259d 9768 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
73f48658 9769 (match_operand:SI 2 "general_operand" "g"))
9b70259d
JH
9770 (const_int 0)))
9771 (set (match_operand:DI 0 "register_operand" "=r")
9772 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9773 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9774 && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 9775 "and{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
9776 [(set_attr "type" "alu")
9777 (set_attr "mode" "SI")])
9778
e075ae69
RH
9779(define_expand "andhi3"
9780 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9781 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
7ae14d31 9782 (match_operand:HI 2 "general_operand" "")))]
d9f32422 9783 "TARGET_HIMODE_MATH"
e075ae69
RH
9784 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9785
9786(define_insn "*andhi_1"
9787 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9788 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
0edb82cb 9789 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8bc527af 9790 (clobber (reg:CC FLAGS_REG))]
e075ae69 9791 "ix86_binary_operator_ok (AND, HImode, operands)"
886c62d1 9792{
e075ae69 9793 switch (get_attr_type (insn))
886c62d1 9794 {
e075ae69 9795 case TYPE_IMOVX:
7656aee4 9796 gcc_assert (CONST_INT_P (operands[2]));
7637e42c
NS
9797 gcc_assert (INTVAL (operands[2]) == 0xff);
9798 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
886c62d1 9799
e075ae69 9800 default:
7637e42c 9801 gcc_assert (rtx_equal_p (operands[0], operands[1]));
886c62d1 9802
0f40f9f7 9803 return "and{w}\t{%2, %0|%0, %2}";
5bc7cd8e 9804 }
0f40f9f7 9805}
6ef67412
JH
9806 [(set_attr "type" "alu,alu,imovx")
9807 (set_attr "length_immediate" "*,*,0")
725fd454
JJ
9808 (set (attr "prefix_rex")
9809 (if_then_else
9810 (and (eq_attr "type" "imovx")
9811 (match_operand 1 "ext_QIreg_nomode_operand" ""))
9812 (const_string "1")
9813 (const_string "*")))
6ef67412 9814 (set_attr "mode" "HI,HI,SI")])
5bc7cd8e 9815
e075ae69 9816(define_insn "*andhi_2"
42fabf21 9817 [(set (reg FLAGS_REG)
16189740 9818 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
0edb82cb 9819 (match_operand:HI 2 "general_operand" "rmn,rn"))
16189740 9820 (const_int 0)))
e075ae69
RH
9821 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9822 (and:HI (match_dup 1) (match_dup 2)))]
16189740
RH
9823 "ix86_match_ccmode (insn, CCNOmode)
9824 && ix86_binary_operator_ok (AND, HImode, operands)"
0f40f9f7 9825 "and{w}\t{%2, %0|%0, %2}"
6ef67412
JH
9826 [(set_attr "type" "alu")
9827 (set_attr "mode" "HI")])
5bc7cd8e 9828
e075ae69
RH
9829(define_expand "andqi3"
9830 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9831 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
7ae14d31 9832 (match_operand:QI 2 "general_operand" "")))]
d9f32422 9833 "TARGET_QIMODE_MATH"
e075ae69
RH
9834 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9835
9836;; %%% Potential partial reg stall on alternative 2. What to do?
9837(define_insn "*andqi_1"
7c6b971d 9838 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 9839 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
0edb82cb 9840 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8bc527af 9841 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
9842 "ix86_binary_operator_ok (AND, QImode, operands)"
9843 "@
0f40f9f7
ZW
9844 and{b}\t{%2, %0|%0, %2}
9845 and{b}\t{%2, %0|%0, %2}
9846 and{l}\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
9847 [(set_attr "type" "alu")
9848 (set_attr "mode" "QI,QI,SI")])
e075ae69 9849
a1b8572c
JH
9850(define_insn "*andqi_1_slp"
9851 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9852 (and:QI (match_dup 0)
0edb82cb 9853 (match_operand:QI 1 "general_operand" "qn,qmn")))
8bc527af 9854 (clobber (reg:CC FLAGS_REG))]
3debdc1e 9855 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 9856 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 9857 "and{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
9858 [(set_attr "type" "alu1")
9859 (set_attr "mode" "QI")])
9860
88d60956 9861(define_insn "*andqi_2_maybe_si"
42fabf21 9862 [(set (reg FLAGS_REG)
16189740 9863 (compare (and:QI
88d60956 9864 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
0edb82cb 9865 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
16189740 9866 (const_int 0)))
e075ae69
RH
9867 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9868 (and:QI (match_dup 1) (match_dup 2)))]
88d60956
RH
9869 "ix86_binary_operator_ok (AND, QImode, operands)
9870 && ix86_match_ccmode (insn,
7656aee4 9871 CONST_INT_P (operands[2])
88d60956 9872 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
adc88131
JJ
9873{
9874 if (which_alternative == 2)
9875 {
7656aee4 9876 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
adc88131 9877 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
0f40f9f7 9878 return "and{l}\t{%2, %k0|%k0, %2}";
adc88131 9879 }
0f40f9f7
ZW
9880 return "and{b}\t{%2, %0|%0, %2}";
9881}
6ef67412
JH
9882 [(set_attr "type" "alu")
9883 (set_attr "mode" "QI,QI,SI")])
e075ae69 9884
88d60956
RH
9885(define_insn "*andqi_2"
9886 [(set (reg FLAGS_REG)
9887 (compare (and:QI
9888 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
0edb82cb 9889 (match_operand:QI 2 "general_operand" "qmn,qn"))
88d60956
RH
9890 (const_int 0)))
9891 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9892 (and:QI (match_dup 1) (match_dup 2)))]
9893 "ix86_match_ccmode (insn, CCNOmode)
9894 && ix86_binary_operator_ok (AND, QImode, operands)"
9895 "and{b}\t{%2, %0|%0, %2}"
9896 [(set_attr "type" "alu")
9897 (set_attr "mode" "QI")])
9898
a1b8572c 9899(define_insn "*andqi_2_slp"
42fabf21 9900 [(set (reg FLAGS_REG)
a1b8572c
JH
9901 (compare (and:QI
9902 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
0edb82cb 9903 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
a1b8572c
JH
9904 (const_int 0)))
9905 (set (strict_low_part (match_dup 0))
9906 (and:QI (match_dup 0) (match_dup 1)))]
3debdc1e 9907 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1b245ade 9908 && ix86_match_ccmode (insn, CCNOmode)
7656aee4 9909 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 9910 "and{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
9911 [(set_attr "type" "alu1")
9912 (set_attr "mode" "QI")])
9913
e075ae69
RH
9914;; ??? A bug in recog prevents it from recognizing a const_int as an
9915;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9916;; for a QImode operand, which of course failed.
9917
9918(define_insn "andqi_ext_0"
d2836273 9919 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
9920 (const_int 8)
9921 (const_int 8))
6300f037 9922 (and:SI
e075ae69
RH
9923 (zero_extract:SI
9924 (match_operand 1 "ext_register_operand" "0")
9925 (const_int 8)
9926 (const_int 8))
9927 (match_operand 2 "const_int_operand" "n")))
8bc527af 9928 (clobber (reg:CC FLAGS_REG))]
2f41793e 9929 ""
0f40f9f7 9930 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
9931 [(set_attr "type" "alu")
9932 (set_attr "length_immediate" "1")
725fd454 9933 (set_attr "modrm" "1")
6ef67412 9934 (set_attr "mode" "QI")])
e075ae69
RH
9935
9936;; Generated by peephole translating test to and. This shows up
9937;; often in fp comparisons.
9938
9939(define_insn "*andqi_ext_0_cc"
42fabf21 9940 [(set (reg FLAGS_REG)
16189740 9941 (compare
e075ae69
RH
9942 (and:SI
9943 (zero_extract:SI
084e679a 9944 (match_operand 1 "ext_register_operand" "0")
3522082b 9945 (const_int 8)
e075ae69
RH
9946 (const_int 8))
9947 (match_operand 2 "const_int_operand" "n"))
9948 (const_int 0)))
d2836273 9949 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
9950 (const_int 8)
9951 (const_int 8))
6300f037 9952 (and:SI
e075ae69
RH
9953 (zero_extract:SI
9954 (match_dup 1)
9955 (const_int 8)
9956 (const_int 8))
9957 (match_dup 2)))]
2f41793e 9958 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 9959 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
9960 [(set_attr "type" "alu")
9961 (set_attr "length_immediate" "1")
725fd454 9962 (set_attr "modrm" "1")
6ef67412 9963 (set_attr "mode" "QI")])
e075ae69
RH
9964
9965(define_insn "*andqi_ext_1"
d2836273 9966 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
9967 (const_int 8)
9968 (const_int 8))
6300f037 9969 (and:SI
e075ae69
RH
9970 (zero_extract:SI
9971 (match_operand 1 "ext_register_operand" "0")
9972 (const_int 8)
9973 (const_int 8))
9974 (zero_extend:SI
d2836273 9975 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 9976 (clobber (reg:CC FLAGS_REG))]
d2836273 9977 "!TARGET_64BIT"
0f40f9f7 9978 "and{b}\t{%2, %h0|%h0, %2}"
d2836273
JH
9979 [(set_attr "type" "alu")
9980 (set_attr "length_immediate" "0")
9981 (set_attr "mode" "QI")])
9982
9983(define_insn "*andqi_ext_1_rex64"
9984 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9985 (const_int 8)
9986 (const_int 8))
6300f037 9987 (and:SI
d2836273
JH
9988 (zero_extract:SI
9989 (match_operand 1 "ext_register_operand" "0")
9990 (const_int 8)
9991 (const_int 8))
9992 (zero_extend:SI
3522082b 9993 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 9994 (clobber (reg:CC FLAGS_REG))]
d2836273 9995 "TARGET_64BIT"
0f40f9f7 9996 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
9997 [(set_attr "type" "alu")
9998 (set_attr "length_immediate" "0")
9999 (set_attr "mode" "QI")])
e075ae69
RH
10000
10001(define_insn "*andqi_ext_2"
d2836273 10002 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
10003 (const_int 8)
10004 (const_int 8))
10005 (and:SI
10006 (zero_extract:SI
10007 (match_operand 1 "ext_register_operand" "%0")
10008 (const_int 8)
10009 (const_int 8))
10010 (zero_extract:SI
d2836273 10011 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
10012 (const_int 8)
10013 (const_int 8))))
8bc527af 10014 (clobber (reg:CC FLAGS_REG))]
e075ae69 10015 ""
0f40f9f7 10016 "and{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
10017 [(set_attr "type" "alu")
10018 (set_attr "length_immediate" "0")
10019 (set_attr "mode" "QI")])
2f41793e
JH
10020
10021;; Convert wide AND instructions with immediate operand to shorter QImode
10022;; equivalents when possible.
d1f87653 10023;; Don't do the splitting with memory operands, since it introduces risk
2f41793e
JH
10024;; of memory mismatch stalls. We may want to do the splitting for optimizing
10025;; for size, but that can (should?) be handled by generic code instead.
10026(define_split
10027 [(set (match_operand 0 "register_operand" "")
10028 (and (match_operand 1 "register_operand" "")
10029 (match_operand 2 "const_int_operand" "")))
8bc527af 10030 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
10031 "reload_completed
10032 && QI_REG_P (operands[0])
3debdc1e 10033 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2f41793e
JH
10034 && !(~INTVAL (operands[2]) & ~(255 << 8))
10035 && GET_MODE (operands[0]) != QImode"
10036 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10037 (and:SI (zero_extract:SI (match_dup 1)
10038 (const_int 8) (const_int 8))
10039 (match_dup 2)))
8bc527af 10040 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
10041 "operands[0] = gen_lowpart (SImode, operands[0]);
10042 operands[1] = gen_lowpart (SImode, operands[1]);
10043 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10044
10045;; Since AND can be encoded with sign extended immediate, this is only
10046;; profitable when 7th bit is not set.
10047(define_split
10048 [(set (match_operand 0 "register_operand" "")
10049 (and (match_operand 1 "general_operand" "")
10050 (match_operand 2 "const_int_operand" "")))
8bc527af 10051 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
10052 "reload_completed
10053 && ANY_QI_REG_P (operands[0])
3debdc1e 10054 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2f41793e
JH
10055 && !(~INTVAL (operands[2]) & ~255)
10056 && !(INTVAL (operands[2]) & 128)
10057 && GET_MODE (operands[0]) != QImode"
10058 [(parallel [(set (strict_low_part (match_dup 0))
10059 (and:QI (match_dup 1)
10060 (match_dup 2)))
8bc527af 10061 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
10062 "operands[0] = gen_lowpart (QImode, operands[0]);
10063 operands[1] = gen_lowpart (QImode, operands[1]);
10064 operands[2] = gen_lowpart (QImode, operands[2]);")
886c62d1 10065\f
e075ae69 10066;; Logical inclusive OR instructions
57dbca5e 10067
e075ae69
RH
10068;; %%% This used to optimize known byte-wide and operations to memory.
10069;; If this is considered useful, it should be done with splitters.
10070
9b70259d
JH
10071(define_expand "iordi3"
10072 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10073 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
7ae14d31 10074 (match_operand:DI 2 "x86_64_general_operand" "")))]
9b70259d
JH
10075 "TARGET_64BIT"
10076 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
10077
10078(define_insn "*iordi_1_rex64"
10079 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10080 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10081 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8bc527af 10082 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
10083 "TARGET_64BIT
10084 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 10085 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
10086 [(set_attr "type" "alu")
10087 (set_attr "mode" "DI")])
10088
10089(define_insn "*iordi_2_rex64"
42fabf21 10090 [(set (reg FLAGS_REG)
9b70259d
JH
10091 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10092 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10093 (const_int 0)))
10094 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10095 (ior:DI (match_dup 1) (match_dup 2)))]
10096 "TARGET_64BIT
10097 && ix86_match_ccmode (insn, CCNOmode)
10098 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 10099 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
10100 [(set_attr "type" "alu")
10101 (set_attr "mode" "DI")])
10102
10103(define_insn "*iordi_3_rex64"
42fabf21 10104 [(set (reg FLAGS_REG)
9b70259d
JH
10105 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10106 (match_operand:DI 2 "x86_64_general_operand" "rem"))
10107 (const_int 0)))
10108 (clobber (match_scratch:DI 0 "=r"))]
10109 "TARGET_64BIT
10110 && ix86_match_ccmode (insn, CCNOmode)
10111 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 10112 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
10113 [(set_attr "type" "alu")
10114 (set_attr "mode" "DI")])
10115
10116
e075ae69
RH
10117(define_expand "iorsi3"
10118 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10119 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
7ae14d31 10120 (match_operand:SI 2 "general_operand" "")))]
57dbca5e 10121 ""
e075ae69
RH
10122 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
10123
10124(define_insn "*iorsi_1"
10125 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10126 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
73f48658 10127 (match_operand:SI 2 "general_operand" "ri,g")))
8bc527af 10128 (clobber (reg:CC FLAGS_REG))]
e075ae69 10129 "ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 10130 "or{l}\t{%2, %0|%0, %2}"
6ef67412
JH
10131 [(set_attr "type" "alu")
10132 (set_attr "mode" "SI")])
e075ae69 10133
9b70259d
JH
10134;; See comment for addsi_1_zext why we do use nonimmediate_operand
10135(define_insn "*iorsi_1_zext"
a6783d12 10136 [(set (match_operand:DI 0 "register_operand" "=r")
9b70259d
JH
10137 (zero_extend:DI
10138 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
73f48658 10139 (match_operand:SI 2 "general_operand" "g"))))
8bc527af 10140 (clobber (reg:CC FLAGS_REG))]
9b70259d 10141 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 10142 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
10143 [(set_attr "type" "alu")
10144 (set_attr "mode" "SI")])
10145
10146(define_insn "*iorsi_1_zext_imm"
a6783d12 10147 [(set (match_operand:DI 0 "register_operand" "=r")
9b70259d
JH
10148 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10149 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8bc527af 10150 (clobber (reg:CC FLAGS_REG))]
9b70259d 10151 "TARGET_64BIT"
0f40f9f7 10152 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
10153 [(set_attr "type" "alu")
10154 (set_attr "mode" "SI")])
10155
e075ae69 10156(define_insn "*iorsi_2"
42fabf21 10157 [(set (reg FLAGS_REG)
16189740 10158 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
73f48658 10159 (match_operand:SI 2 "general_operand" "g,ri"))
16189740 10160 (const_int 0)))
e075ae69
RH
10161 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10162 (ior:SI (match_dup 1) (match_dup 2)))]
16189740
RH
10163 "ix86_match_ccmode (insn, CCNOmode)
10164 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 10165 "or{l}\t{%2, %0|%0, %2}"
6ef67412
JH
10166 [(set_attr "type" "alu")
10167 (set_attr "mode" "SI")])
e075ae69 10168
9b70259d
JH
10169;; See comment for addsi_1_zext why we do use nonimmediate_operand
10170;; ??? Special case for immediate operand is missing - it is tricky.
10171(define_insn "*iorsi_2_zext"
42fabf21 10172 [(set (reg FLAGS_REG)
9b70259d 10173 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
73f48658 10174 (match_operand:SI 2 "general_operand" "g"))
9b70259d
JH
10175 (const_int 0)))
10176 (set (match_operand:DI 0 "register_operand" "=r")
10177 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
10178 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10179 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 10180 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
10181 [(set_attr "type" "alu")
10182 (set_attr "mode" "SI")])
10183
10184(define_insn "*iorsi_2_zext_imm"
42fabf21 10185 [(set (reg FLAGS_REG)
9b70259d
JH
10186 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10187 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10188 (const_int 0)))
10189 (set (match_operand:DI 0 "register_operand" "=r")
10190 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10191 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10192 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 10193 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
10194 [(set_attr "type" "alu")
10195 (set_attr "mode" "SI")])
10196
d90ffc8d 10197(define_insn "*iorsi_3"
42fabf21 10198 [(set (reg FLAGS_REG)
d90ffc8d 10199 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
73f48658 10200 (match_operand:SI 2 "general_operand" "g"))
d90ffc8d
JH
10201 (const_int 0)))
10202 (clobber (match_scratch:SI 0 "=r"))]
10203 "ix86_match_ccmode (insn, CCNOmode)
7656aee4 10204 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 10205 "or{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
10206 [(set_attr "type" "alu")
10207 (set_attr "mode" "SI")])
10208
e075ae69
RH
10209(define_expand "iorhi3"
10210 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10211 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
7ae14d31 10212 (match_operand:HI 2 "general_operand" "")))]
d9f32422 10213 "TARGET_HIMODE_MATH"
e075ae69
RH
10214 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
10215
10216(define_insn "*iorhi_1"
10217 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10218 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
0edb82cb 10219 (match_operand:HI 2 "general_operand" "rmn,rn")))
8bc527af 10220 (clobber (reg:CC FLAGS_REG))]
e075ae69 10221 "ix86_binary_operator_ok (IOR, HImode, operands)"
0f40f9f7 10222 "or{w}\t{%2, %0|%0, %2}"
6ef67412
JH
10223 [(set_attr "type" "alu")
10224 (set_attr "mode" "HI")])
e075ae69 10225
e075ae69 10226(define_insn "*iorhi_2"
42fabf21 10227 [(set (reg FLAGS_REG)
16189740 10228 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
0edb82cb 10229 (match_operand:HI 2 "general_operand" "rmn,rn"))
16189740 10230 (const_int 0)))
e075ae69
RH
10231 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10232 (ior:HI (match_dup 1) (match_dup 2)))]
16189740
RH
10233 "ix86_match_ccmode (insn, CCNOmode)
10234 && ix86_binary_operator_ok (IOR, HImode, operands)"
0f40f9f7 10235 "or{w}\t{%2, %0|%0, %2}"
6ef67412
JH
10236 [(set_attr "type" "alu")
10237 (set_attr "mode" "HI")])
e075ae69 10238
d90ffc8d 10239(define_insn "*iorhi_3"
42fabf21 10240 [(set (reg FLAGS_REG)
d90ffc8d 10241 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
0edb82cb 10242 (match_operand:HI 2 "general_operand" "rmn"))
d90ffc8d
JH
10243 (const_int 0)))
10244 (clobber (match_scratch:HI 0 "=r"))]
10245 "ix86_match_ccmode (insn, CCNOmode)
7656aee4 10246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 10247 "or{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
10248 [(set_attr "type" "alu")
10249 (set_attr "mode" "HI")])
10250
e075ae69
RH
10251(define_expand "iorqi3"
10252 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10253 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
7ae14d31 10254 (match_operand:QI 2 "general_operand" "")))]
d9f32422 10255 "TARGET_QIMODE_MATH"
e075ae69
RH
10256 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
10257
10258;; %%% Potential partial reg stall on alternative 2. What to do?
10259(define_insn "*iorqi_1"
7c6b971d 10260 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
e075ae69 10261 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
0edb82cb 10262 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8bc527af 10263 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
10264 "ix86_binary_operator_ok (IOR, QImode, operands)"
10265 "@
0f40f9f7
ZW
10266 or{b}\t{%2, %0|%0, %2}
10267 or{b}\t{%2, %0|%0, %2}
10268 or{l}\t{%k2, %k0|%k0, %k2}"
6ef67412 10269 [(set_attr "type" "alu")
a1b8572c
JH
10270 (set_attr "mode" "QI,QI,SI")])
10271
10272(define_insn "*iorqi_1_slp"
10273 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
10274 (ior:QI (match_dup 0)
0edb82cb 10275 (match_operand:QI 1 "general_operand" "qmn,qn")))
8bc527af 10276 (clobber (reg:CC FLAGS_REG))]
3debdc1e 10277 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 10278 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 10279 "or{b}\t{%1, %0|%0, %1}"
a1b8572c 10280 [(set_attr "type" "alu1")
6ef67412 10281 (set_attr "mode" "QI")])
e075ae69
RH
10282
10283(define_insn "*iorqi_2"
42fabf21 10284 [(set (reg FLAGS_REG)
16189740 10285 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
0edb82cb 10286 (match_operand:QI 2 "general_operand" "qmn,qn"))
16189740 10287 (const_int 0)))
e075ae69
RH
10288 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10289 (ior:QI (match_dup 1) (match_dup 2)))]
16189740
RH
10290 "ix86_match_ccmode (insn, CCNOmode)
10291 && ix86_binary_operator_ok (IOR, QImode, operands)"
0f40f9f7 10292 "or{b}\t{%2, %0|%0, %2}"
6ef67412
JH
10293 [(set_attr "type" "alu")
10294 (set_attr "mode" "QI")])
d90ffc8d 10295
a1b8572c 10296(define_insn "*iorqi_2_slp"
42fabf21 10297 [(set (reg FLAGS_REG)
a1b8572c 10298 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
0edb82cb 10299 (match_operand:QI 1 "general_operand" "qmn,qn"))
a1b8572c
JH
10300 (const_int 0)))
10301 (set (strict_low_part (match_dup 0))
10302 (ior:QI (match_dup 0) (match_dup 1)))]
3debdc1e 10303 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1b245ade 10304 && ix86_match_ccmode (insn, CCNOmode)
7656aee4 10305 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
0f40f9f7 10306 "or{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
10307 [(set_attr "type" "alu1")
10308 (set_attr "mode" "QI")])
10309
d90ffc8d 10310(define_insn "*iorqi_3"
42fabf21 10311 [(set (reg FLAGS_REG)
d90ffc8d 10312 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
0edb82cb 10313 (match_operand:QI 2 "general_operand" "qmn"))
d90ffc8d 10314 (const_int 0)))
7e08e190 10315 (clobber (match_scratch:QI 0 "=q"))]
d90ffc8d 10316 "ix86_match_ccmode (insn, CCNOmode)
7656aee4 10317 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 10318 "or{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
10319 [(set_attr "type" "alu")
10320 (set_attr "mode" "QI")])
10321
3debdc1e 10322(define_insn "*iorqi_ext_0"
2f41793e
JH
10323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10324 (const_int 8)
10325 (const_int 8))
6300f037 10326 (ior:SI
2f41793e
JH
10327 (zero_extract:SI
10328 (match_operand 1 "ext_register_operand" "0")
10329 (const_int 8)
10330 (const_int 8))
10331 (match_operand 2 "const_int_operand" "n")))
8bc527af 10332 (clobber (reg:CC FLAGS_REG))]
3debdc1e 10333 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
2f41793e
JH
10334 "or{b}\t{%2, %h0|%h0, %2}"
10335 [(set_attr "type" "alu")
10336 (set_attr "length_immediate" "1")
725fd454 10337 (set_attr "modrm" "1")
2f41793e
JH
10338 (set_attr "mode" "QI")])
10339
10340(define_insn "*iorqi_ext_1"
10341 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10342 (const_int 8)
10343 (const_int 8))
6300f037 10344 (ior:SI
2f41793e
JH
10345 (zero_extract:SI
10346 (match_operand 1 "ext_register_operand" "0")
10347 (const_int 8)
10348 (const_int 8))
10349 (zero_extend:SI
10350 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 10351 (clobber (reg:CC FLAGS_REG))]
2f41793e 10352 "!TARGET_64BIT
3debdc1e 10353 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
2f41793e
JH
10354 "or{b}\t{%2, %h0|%h0, %2}"
10355 [(set_attr "type" "alu")
10356 (set_attr "length_immediate" "0")
10357 (set_attr "mode" "QI")])
10358
10359(define_insn "*iorqi_ext_1_rex64"
10360 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10361 (const_int 8)
10362 (const_int 8))
6300f037 10363 (ior:SI
2f41793e
JH
10364 (zero_extract:SI
10365 (match_operand 1 "ext_register_operand" "0")
10366 (const_int 8)
10367 (const_int 8))
10368 (zero_extend:SI
10369 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 10370 (clobber (reg:CC FLAGS_REG))]
2f41793e 10371 "TARGET_64BIT
3debdc1e 10372 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
2f41793e
JH
10373 "or{b}\t{%2, %h0|%h0, %2}"
10374 [(set_attr "type" "alu")
10375 (set_attr "length_immediate" "0")
10376 (set_attr "mode" "QI")])
10377
10378(define_insn "*iorqi_ext_2"
10379 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10380 (const_int 8)
10381 (const_int 8))
6300f037 10382 (ior:SI
2f41793e
JH
10383 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10384 (const_int 8)
10385 (const_int 8))
10386 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10387 (const_int 8)
10388 (const_int 8))))
8bc527af 10389 (clobber (reg:CC FLAGS_REG))]
3debdc1e 10390 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
2f41793e
JH
10391 "ior{b}\t{%h2, %h0|%h0, %h2}"
10392 [(set_attr "type" "alu")
10393 (set_attr "length_immediate" "0")
10394 (set_attr "mode" "QI")])
10395
10396(define_split
10397 [(set (match_operand 0 "register_operand" "")
10398 (ior (match_operand 1 "register_operand" "")
10399 (match_operand 2 "const_int_operand" "")))
8bc527af 10400 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
10401 "reload_completed
10402 && QI_REG_P (operands[0])
3debdc1e 10403 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2f41793e
JH
10404 && !(INTVAL (operands[2]) & ~(255 << 8))
10405 && GET_MODE (operands[0]) != QImode"
10406 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10407 (ior:SI (zero_extract:SI (match_dup 1)
10408 (const_int 8) (const_int 8))
10409 (match_dup 2)))
8bc527af 10410 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
10411 "operands[0] = gen_lowpart (SImode, operands[0]);
10412 operands[1] = gen_lowpart (SImode, operands[1]);
10413 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10414
10415;; Since OR can be encoded with sign extended immediate, this is only
10416;; profitable when 7th bit is set.
10417(define_split
10418 [(set (match_operand 0 "register_operand" "")
10419 (ior (match_operand 1 "general_operand" "")
10420 (match_operand 2 "const_int_operand" "")))
8bc527af 10421 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
10422 "reload_completed
10423 && ANY_QI_REG_P (operands[0])
3debdc1e 10424 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2f41793e
JH
10425 && !(INTVAL (operands[2]) & ~255)
10426 && (INTVAL (operands[2]) & 128)
10427 && GET_MODE (operands[0]) != QImode"
10428 [(parallel [(set (strict_low_part (match_dup 0))
10429 (ior:QI (match_dup 1)
10430 (match_dup 2)))
8bc527af 10431 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
10432 "operands[0] = gen_lowpart (QImode, operands[0]);
10433 operands[1] = gen_lowpart (QImode, operands[1]);
10434 operands[2] = gen_lowpart (QImode, operands[2]);")
e075ae69
RH
10435\f
10436;; Logical XOR instructions
a269a03c 10437
e075ae69
RH
10438;; %%% This used to optimize known byte-wide and operations to memory.
10439;; If this is considered useful, it should be done with splitters.
57dbca5e 10440
9b70259d
JH
10441(define_expand "xordi3"
10442 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10443 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
7ae14d31 10444 (match_operand:DI 2 "x86_64_general_operand" "")))]
9b70259d
JH
10445 "TARGET_64BIT"
10446 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
10447
10448(define_insn "*xordi_1_rex64"
10449 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10450 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10451 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8bc527af 10452 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
10453 "TARGET_64BIT
10454 && ix86_binary_operator_ok (XOR, DImode, operands)"
8c32cbc9 10455 "xor{q}\t{%2, %0|%0, %2}"
9b70259d 10456 [(set_attr "type" "alu")
8c32cbc9 10457 (set_attr "mode" "DI")])
9b70259d
JH
10458
10459(define_insn "*xordi_2_rex64"
42fabf21 10460 [(set (reg FLAGS_REG)
9b70259d
JH
10461 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10462 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10463 (const_int 0)))
10464 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10465 (xor:DI (match_dup 1) (match_dup 2)))]
10466 "TARGET_64BIT
10467 && ix86_match_ccmode (insn, CCNOmode)
10468 && ix86_binary_operator_ok (XOR, DImode, operands)"
8c32cbc9 10469 "xor{q}\t{%2, %0|%0, %2}"
9b70259d 10470 [(set_attr "type" "alu")
8c32cbc9 10471 (set_attr "mode" "DI")])
9b70259d
JH
10472
10473(define_insn "*xordi_3_rex64"
42fabf21 10474 [(set (reg FLAGS_REG)
9b70259d
JH
10475 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10476 (match_operand:DI 2 "x86_64_general_operand" "rem"))
10477 (const_int 0)))
10478 (clobber (match_scratch:DI 0 "=r"))]
10479 "TARGET_64BIT
10480 && ix86_match_ccmode (insn, CCNOmode)
10481 && ix86_binary_operator_ok (XOR, DImode, operands)"
0f40f9f7 10482 "xor{q}\t{%2, %0|%0, %2}"
9b70259d
JH
10483 [(set_attr "type" "alu")
10484 (set_attr "mode" "DI")])
10485
e075ae69
RH
10486(define_expand "xorsi3"
10487 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10488 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
7ae14d31 10489 (match_operand:SI 2 "general_operand" "")))]
57dbca5e 10490 ""
e075ae69 10491 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
a269a03c 10492
e075ae69
RH
10493(define_insn "*xorsi_1"
10494 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10495 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10496 (match_operand:SI 2 "general_operand" "ri,rm")))
8bc527af 10497 (clobber (reg:CC FLAGS_REG))]
e075ae69 10498 "ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 10499 "xor{l}\t{%2, %0|%0, %2}"
6ef67412
JH
10500 [(set_attr "type" "alu")
10501 (set_attr "mode" "SI")])
e075ae69 10502
9b70259d
JH
10503;; See comment for addsi_1_zext why we do use nonimmediate_operand
10504;; Add speccase for immediates
10505(define_insn "*xorsi_1_zext"
10506 [(set (match_operand:DI 0 "register_operand" "=r")
10507 (zero_extend:DI
10508 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
73f48658 10509 (match_operand:SI 2 "general_operand" "g"))))
8bc527af 10510 (clobber (reg:CC FLAGS_REG))]
9b70259d 10511 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 10512 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
10513 [(set_attr "type" "alu")
10514 (set_attr "mode" "SI")])
10515
10516(define_insn "*xorsi_1_zext_imm"
10517 [(set (match_operand:DI 0 "register_operand" "=r")
10518 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10519 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8bc527af 10520 (clobber (reg:CC FLAGS_REG))]
9b70259d 10521 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 10522 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
10523 [(set_attr "type" "alu")
10524 (set_attr "mode" "SI")])
10525
e075ae69 10526(define_insn "*xorsi_2"
42fabf21 10527 [(set (reg FLAGS_REG)
16189740 10528 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
73f48658 10529 (match_operand:SI 2 "general_operand" "g,ri"))
16189740 10530 (const_int 0)))
e075ae69
RH
10531 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10532 (xor:SI (match_dup 1) (match_dup 2)))]
16189740
RH
10533 "ix86_match_ccmode (insn, CCNOmode)
10534 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 10535 "xor{l}\t{%2, %0|%0, %2}"
6ef67412
JH
10536 [(set_attr "type" "alu")
10537 (set_attr "mode" "SI")])
e075ae69 10538
9b70259d
JH
10539;; See comment for addsi_1_zext why we do use nonimmediate_operand
10540;; ??? Special case for immediate operand is missing - it is tricky.
10541(define_insn "*xorsi_2_zext"
42fabf21 10542 [(set (reg FLAGS_REG)
9b70259d 10543 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
73f48658 10544 (match_operand:SI 2 "general_operand" "g"))
9b70259d
JH
10545 (const_int 0)))
10546 (set (match_operand:DI 0 "register_operand" "=r")
10547 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10548 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10549 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 10550 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
10551 [(set_attr "type" "alu")
10552 (set_attr "mode" "SI")])
10553
10554(define_insn "*xorsi_2_zext_imm"
42fabf21 10555 [(set (reg FLAGS_REG)
9b70259d
JH
10556 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10557 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10558 (const_int 0)))
10559 (set (match_operand:DI 0 "register_operand" "=r")
10560 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10561 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10562 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 10563 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
10564 [(set_attr "type" "alu")
10565 (set_attr "mode" "SI")])
10566
d90ffc8d 10567(define_insn "*xorsi_3"
42fabf21 10568 [(set (reg FLAGS_REG)
d90ffc8d 10569 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
73f48658 10570 (match_operand:SI 2 "general_operand" "g"))
d90ffc8d
JH
10571 (const_int 0)))
10572 (clobber (match_scratch:SI 0 "=r"))]
10573 "ix86_match_ccmode (insn, CCNOmode)
7656aee4 10574 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 10575 "xor{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
10576 [(set_attr "type" "alu")
10577 (set_attr "mode" "SI")])
10578
e075ae69
RH
10579(define_expand "xorhi3"
10580 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10581 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
7ae14d31 10582 (match_operand:HI 2 "general_operand" "")))]
d9f32422 10583 "TARGET_HIMODE_MATH"
e075ae69
RH
10584 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10585
10586(define_insn "*xorhi_1"
10587 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10588 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
0edb82cb 10589 (match_operand:HI 2 "general_operand" "rmn,rn")))
8bc527af 10590 (clobber (reg:CC FLAGS_REG))]
e075ae69 10591 "ix86_binary_operator_ok (XOR, HImode, operands)"
0f40f9f7 10592 "xor{w}\t{%2, %0|%0, %2}"
6ef67412
JH
10593 [(set_attr "type" "alu")
10594 (set_attr "mode" "HI")])
57dbca5e 10595
e075ae69 10596(define_insn "*xorhi_2"
42fabf21 10597 [(set (reg FLAGS_REG)
16189740 10598 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
0edb82cb 10599 (match_operand:HI 2 "general_operand" "rmn,rn"))
16189740 10600 (const_int 0)))
e075ae69
RH
10601 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10602 (xor:HI (match_dup 1) (match_dup 2)))]
16189740
RH
10603 "ix86_match_ccmode (insn, CCNOmode)
10604 && ix86_binary_operator_ok (XOR, HImode, operands)"
0f40f9f7 10605 "xor{w}\t{%2, %0|%0, %2}"
6ef67412
JH
10606 [(set_attr "type" "alu")
10607 (set_attr "mode" "HI")])
e075ae69 10608
d90ffc8d 10609(define_insn "*xorhi_3"
42fabf21 10610 [(set (reg FLAGS_REG)
d90ffc8d 10611 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
0edb82cb 10612 (match_operand:HI 2 "general_operand" "rmn"))
d90ffc8d
JH
10613 (const_int 0)))
10614 (clobber (match_scratch:HI 0 "=r"))]
10615 "ix86_match_ccmode (insn, CCNOmode)
7656aee4 10616 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 10617 "xor{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
10618 [(set_attr "type" "alu")
10619 (set_attr "mode" "HI")])
10620
e075ae69
RH
10621(define_expand "xorqi3"
10622 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10623 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
7ae14d31 10624 (match_operand:QI 2 "general_operand" "")))]
d9f32422 10625 "TARGET_QIMODE_MATH"
e075ae69
RH
10626 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10627
10628;; %%% Potential partial reg stall on alternative 2. What to do?
10629(define_insn "*xorqi_1"
7c6b971d 10630 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
e075ae69 10631 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
0edb82cb 10632 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8bc527af 10633 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
10634 "ix86_binary_operator_ok (XOR, QImode, operands)"
10635 "@
0f40f9f7
ZW
10636 xor{b}\t{%2, %0|%0, %2}
10637 xor{b}\t{%2, %0|%0, %2}
10638 xor{l}\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
10639 [(set_attr "type" "alu")
10640 (set_attr "mode" "QI,QI,SI")])
10641
b6bb1d56
JH
10642(define_insn "*xorqi_1_slp"
10643 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10644 (xor:QI (match_dup 0)
0edb82cb 10645 (match_operand:QI 1 "general_operand" "qn,qmn")))
8bc527af 10646 (clobber (reg:CC FLAGS_REG))]
3debdc1e 10647 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 10648 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
b6bb1d56
JH
10649 "xor{b}\t{%1, %0|%0, %1}"
10650 [(set_attr "type" "alu1")
10651 (set_attr "mode" "QI")])
10652
3debdc1e 10653(define_insn "*xorqi_ext_0"
2f41793e
JH
10654 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10655 (const_int 8)
10656 (const_int 8))
6300f037 10657 (xor:SI
2f41793e
JH
10658 (zero_extract:SI
10659 (match_operand 1 "ext_register_operand" "0")
10660 (const_int 8)
10661 (const_int 8))
10662 (match_operand 2 "const_int_operand" "n")))
8bc527af 10663 (clobber (reg:CC FLAGS_REG))]
3debdc1e 10664 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
2f41793e
JH
10665 "xor{b}\t{%2, %h0|%h0, %2}"
10666 [(set_attr "type" "alu")
10667 (set_attr "length_immediate" "1")
725fd454 10668 (set_attr "modrm" "1")
2f41793e
JH
10669 (set_attr "mode" "QI")])
10670
a4414093 10671(define_insn "*xorqi_ext_1"
2f41793e
JH
10672 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10673 (const_int 8)
10674 (const_int 8))
6300f037 10675 (xor:SI
2f41793e
JH
10676 (zero_extract:SI
10677 (match_operand 1 "ext_register_operand" "0")
10678 (const_int 8)
10679 (const_int 8))
10680 (zero_extend:SI
10681 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 10682 (clobber (reg:CC FLAGS_REG))]
2f41793e 10683 "!TARGET_64BIT
3debdc1e 10684 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
2f41793e
JH
10685 "xor{b}\t{%2, %h0|%h0, %2}"
10686 [(set_attr "type" "alu")
10687 (set_attr "length_immediate" "0")
10688 (set_attr "mode" "QI")])
10689
10690(define_insn "*xorqi_ext_1_rex64"
10691 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10692 (const_int 8)
10693 (const_int 8))
6300f037 10694 (xor:SI
2f41793e
JH
10695 (zero_extract:SI
10696 (match_operand 1 "ext_register_operand" "0")
10697 (const_int 8)
10698 (const_int 8))
10699 (zero_extend:SI
10700 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 10701 (clobber (reg:CC FLAGS_REG))]
2f41793e 10702 "TARGET_64BIT
3debdc1e 10703 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
2f41793e
JH
10704 "xor{b}\t{%2, %h0|%h0, %2}"
10705 [(set_attr "type" "alu")
10706 (set_attr "length_immediate" "0")
10707 (set_attr "mode" "QI")])
10708
10709(define_insn "*xorqi_ext_2"
d2836273 10710 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6ef67412
JH
10711 (const_int 8)
10712 (const_int 8))
6300f037 10713 (xor:SI
6ef67412
JH
10714 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10715 (const_int 8)
10716 (const_int 8))
d2836273 10717 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6ef67412
JH
10718 (const_int 8)
10719 (const_int 8))))
8bc527af 10720 (clobber (reg:CC FLAGS_REG))]
3debdc1e 10721 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
0f40f9f7 10722 "xor{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
10723 [(set_attr "type" "alu")
10724 (set_attr "length_immediate" "0")
10725 (set_attr "mode" "QI")])
e075ae69 10726
7abd4e00 10727(define_insn "*xorqi_cc_1"
42fabf21 10728 [(set (reg FLAGS_REG)
16189740 10729 (compare
e075ae69 10730 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
0edb82cb 10731 (match_operand:QI 2 "general_operand" "qmn,qn"))
e075ae69
RH
10732 (const_int 0)))
10733 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10734 (xor:QI (match_dup 1) (match_dup 2)))]
16189740
RH
10735 "ix86_match_ccmode (insn, CCNOmode)
10736 && ix86_binary_operator_ok (XOR, QImode, operands)"
0f40f9f7 10737 "xor{b}\t{%2, %0|%0, %2}"
6ef67412
JH
10738 [(set_attr "type" "alu")
10739 (set_attr "mode" "QI")])
e075ae69 10740
b6bb1d56 10741(define_insn "*xorqi_2_slp"
42fabf21 10742 [(set (reg FLAGS_REG)
b6bb1d56 10743 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
0edb82cb 10744 (match_operand:QI 1 "general_operand" "qmn,qn"))
b6bb1d56
JH
10745 (const_int 0)))
10746 (set (strict_low_part (match_dup 0))
10747 (xor:QI (match_dup 0) (match_dup 1)))]
3debdc1e 10748 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1b245ade 10749 && ix86_match_ccmode (insn, CCNOmode)
7656aee4 10750 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
b6bb1d56
JH
10751 "xor{b}\t{%1, %0|%0, %1}"
10752 [(set_attr "type" "alu1")
10753 (set_attr "mode" "QI")])
10754
d90ffc8d 10755(define_insn "*xorqi_cc_2"
42fabf21 10756 [(set (reg FLAGS_REG)
d90ffc8d
JH
10757 (compare
10758 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
0edb82cb 10759 (match_operand:QI 2 "general_operand" "qmn"))
d90ffc8d 10760 (const_int 0)))
7e08e190 10761 (clobber (match_scratch:QI 0 "=q"))]
d90ffc8d 10762 "ix86_match_ccmode (insn, CCNOmode)
7656aee4 10763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
0f40f9f7 10764 "xor{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
10765 [(set_attr "type" "alu")
10766 (set_attr "mode" "QI")])
10767
9076b9c1 10768(define_insn "*xorqi_cc_ext_1"
42fabf21 10769 [(set (reg FLAGS_REG)
9076b9c1 10770 (compare
e075ae69
RH
10771 (xor:SI
10772 (zero_extract:SI
10773 (match_operand 1 "ext_register_operand" "0")
10774 (const_int 8)
10775 (const_int 8))
10776 (match_operand:QI 2 "general_operand" "qmn"))
10777 (const_int 0)))
10778 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10779 (const_int 8)
10780 (const_int 8))
6300f037 10781 (xor:SI
e075ae69
RH
10782 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10783 (match_dup 2)))]
d2836273 10784 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 10785 "xor{b}\t{%2, %h0|%h0, %2}"
d2836273 10786 [(set_attr "type" "alu")
725fd454 10787 (set_attr "modrm" "1")
d2836273
JH
10788 (set_attr "mode" "QI")])
10789
10790(define_insn "*xorqi_cc_ext_1_rex64"
42fabf21 10791 [(set (reg FLAGS_REG)
d2836273
JH
10792 (compare
10793 (xor:SI
10794 (zero_extract:SI
10795 (match_operand 1 "ext_register_operand" "0")
10796 (const_int 8)
10797 (const_int 8))
10798 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10799 (const_int 0)))
10800 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10801 (const_int 8)
10802 (const_int 8))
6300f037 10803 (xor:SI
d2836273
JH
10804 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10805 (match_dup 2)))]
10806 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 10807 "xor{b}\t{%2, %h0|%h0, %2}"
6ef67412 10808 [(set_attr "type" "alu")
725fd454 10809 (set_attr "modrm" "1")
6ef67412 10810 (set_attr "mode" "QI")])
9076b9c1
JH
10811
10812(define_expand "xorqi_cc_ext_1"
10813 [(parallel [
8bc527af 10814 (set (reg:CCNO FLAGS_REG)
9076b9c1
JH
10815 (compare:CCNO
10816 (xor:SI
10817 (zero_extract:SI
10818 (match_operand 1 "ext_register_operand" "")
10819 (const_int 8)
10820 (const_int 8))
10821 (match_operand:QI 2 "general_operand" ""))
10822 (const_int 0)))
10823 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10824 (const_int 8)
10825 (const_int 8))
6300f037 10826 (xor:SI
9076b9c1
JH
10827 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10828 (match_dup 2)))])]
10829 ""
10830 "")
2f41793e
JH
10831
10832(define_split
10833 [(set (match_operand 0 "register_operand" "")
10834 (xor (match_operand 1 "register_operand" "")
10835 (match_operand 2 "const_int_operand" "")))
8bc527af 10836 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
10837 "reload_completed
10838 && QI_REG_P (operands[0])
3debdc1e 10839 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2f41793e
JH
10840 && !(INTVAL (operands[2]) & ~(255 << 8))
10841 && GET_MODE (operands[0]) != QImode"
10842 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10843 (xor:SI (zero_extract:SI (match_dup 1)
10844 (const_int 8) (const_int 8))
10845 (match_dup 2)))
8bc527af 10846 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
10847 "operands[0] = gen_lowpart (SImode, operands[0]);
10848 operands[1] = gen_lowpart (SImode, operands[1]);
10849 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10850
10851;; Since XOR can be encoded with sign extended immediate, this is only
10852;; profitable when 7th bit is set.
10853(define_split
10854 [(set (match_operand 0 "register_operand" "")
10855 (xor (match_operand 1 "general_operand" "")
10856 (match_operand 2 "const_int_operand" "")))
8bc527af 10857 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
10858 "reload_completed
10859 && ANY_QI_REG_P (operands[0])
3debdc1e 10860 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2f41793e
JH
10861 && !(INTVAL (operands[2]) & ~255)
10862 && (INTVAL (operands[2]) & 128)
10863 && GET_MODE (operands[0]) != QImode"
10864 [(parallel [(set (strict_low_part (match_dup 0))
10865 (xor:QI (match_dup 1)
10866 (match_dup 2)))
8bc527af 10867 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
10868 "operands[0] = gen_lowpart (QImode, operands[0]);
10869 operands[1] = gen_lowpart (QImode, operands[1]);
10870 operands[2] = gen_lowpart (QImode, operands[2]);")
e075ae69
RH
10871\f
10872;; Negation instructions
57dbca5e 10873
28356f52 10874(define_expand "negti2"
7ae14d31
UB
10875 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10876 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
28356f52
JB
10877 "TARGET_64BIT"
10878 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10879
10880(define_insn "*negti2_1"
10881 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
68b8830a 10882 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
28356f52
JB
10883 (clobber (reg:CC FLAGS_REG))]
10884 "TARGET_64BIT
10885 && ix86_unary_operator_ok (NEG, TImode, operands)"
10886 "#")
10887
10888(define_split
10889 [(set (match_operand:TI 0 "nonimmediate_operand" "")
68b8830a 10890 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
28356f52
JB
10891 (clobber (reg:CC FLAGS_REG))]
10892 "TARGET_64BIT && reload_completed"
10893 [(parallel
10894 [(set (reg:CCZ FLAGS_REG)
c2b814b9
UB
10895 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10896 (set (match_dup 0) (neg:DI (match_dup 1)))])
28356f52 10897 (parallel
c2b814b9 10898 [(set (match_dup 2)
28356f52
JB
10899 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10900 (match_dup 3))
10901 (const_int 0)))
10902 (clobber (reg:CC FLAGS_REG))])
10903 (parallel
c2b814b9
UB
10904 [(set (match_dup 2)
10905 (neg:DI (match_dup 2)))
28356f52 10906 (clobber (reg:CC FLAGS_REG))])]
c2b814b9 10907 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
28356f52 10908
06a964de 10909(define_expand "negdi2"
7ae14d31
UB
10910 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10911 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
06a964de
JH
10912 ""
10913 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10914
10915(define_insn "*negdi2_1"
e075ae69
RH
10916 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10917 (neg:DI (match_operand:DI 1 "general_operand" "0")))
8bc527af 10918 (clobber (reg:CC FLAGS_REG))]
d2836273
JH
10919 "!TARGET_64BIT
10920 && ix86_unary_operator_ok (NEG, DImode, operands)"
e075ae69 10921 "#")
886c62d1 10922
e075ae69
RH
10923(define_split
10924 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10925 (neg:DI (match_operand:DI 1 "general_operand" "")))
8bc527af 10926 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 10927 "!TARGET_64BIT && reload_completed"
e075ae69 10928 [(parallel
8bc527af 10929 [(set (reg:CCZ FLAGS_REG)
c2b814b9
UB
10930 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10931 (set (match_dup 0) (neg:SI (match_dup 1)))])
e075ae69 10932 (parallel
c2b814b9 10933 [(set (match_dup 2)
8bc527af 10934 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9dcbdc7e
JH
10935 (match_dup 3))
10936 (const_int 0)))
8bc527af 10937 (clobber (reg:CC FLAGS_REG))])
e075ae69 10938 (parallel
c2b814b9
UB
10939 [(set (match_dup 2)
10940 (neg:SI (match_dup 2)))
8bc527af 10941 (clobber (reg:CC FLAGS_REG))])]
c2b814b9 10942 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
886c62d1 10943
9b70259d
JH
10944(define_insn "*negdi2_1_rex64"
10945 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10946 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
8bc527af 10947 (clobber (reg:CC FLAGS_REG))]
9b70259d 10948 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
0f40f9f7 10949 "neg{q}\t%0"
9b70259d
JH
10950 [(set_attr "type" "negnot")
10951 (set_attr "mode" "DI")])
10952
10953;; The problem with neg is that it does not perform (compare x 0),
10954;; it really performs (compare 0 x), which leaves us with the zero
10955;; flag being the only useful item.
10956
10957(define_insn "*negdi2_cmpz_rex64"
8bc527af 10958 [(set (reg:CCZ FLAGS_REG)
9b70259d
JH
10959 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10960 (const_int 0)))
10961 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10962 (neg:DI (match_dup 1)))]
10963 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
0f40f9f7 10964 "neg{q}\t%0"
9b70259d
JH
10965 [(set_attr "type" "negnot")
10966 (set_attr "mode" "DI")])
10967
10968
06a964de 10969(define_expand "negsi2"
7ae14d31
UB
10970 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10971 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
06a964de
JH
10972 ""
10973 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10974
10975(define_insn "*negsi2_1"
2ae0f82c 10976 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 10977 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
8bc527af 10978 (clobber (reg:CC FLAGS_REG))]
06a964de 10979 "ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 10980 "neg{l}\t%0"
6ef67412
JH
10981 [(set_attr "type" "negnot")
10982 (set_attr "mode" "SI")])
e075ae69 10983
9b70259d
JH
10984;; Combine is quite creative about this pattern.
10985(define_insn "*negsi2_1_zext"
10986 [(set (match_operand:DI 0 "register_operand" "=r")
10987 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10988 (const_int 32)))
10989 (const_int 32)))
8bc527af 10990 (clobber (reg:CC FLAGS_REG))]
9b70259d 10991 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 10992 "neg{l}\t%k0"
9b70259d
JH
10993 [(set_attr "type" "negnot")
10994 (set_attr "mode" "SI")])
10995
16189740
RH
10996;; The problem with neg is that it does not perform (compare x 0),
10997;; it really performs (compare 0 x), which leaves us with the zero
10998;; flag being the only useful item.
e075ae69 10999
16189740 11000(define_insn "*negsi2_cmpz"
8bc527af 11001 [(set (reg:CCZ FLAGS_REG)
16189740
RH
11002 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11003 (const_int 0)))
e075ae69
RH
11004 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11005 (neg:SI (match_dup 1)))]
06a964de 11006 "ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 11007 "neg{l}\t%0"
6ef67412
JH
11008 [(set_attr "type" "negnot")
11009 (set_attr "mode" "SI")])
886c62d1 11010
9b70259d 11011(define_insn "*negsi2_cmpz_zext"
8bc527af 11012 [(set (reg:CCZ FLAGS_REG)
9b70259d
JH
11013 (compare:CCZ (lshiftrt:DI
11014 (neg:DI (ashift:DI
11015 (match_operand:DI 1 "register_operand" "0")
11016 (const_int 32)))
11017 (const_int 32))
11018 (const_int 0)))
11019 (set (match_operand:DI 0 "register_operand" "=r")
11020 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
11021 (const_int 32)))
11022 (const_int 32)))]
11023 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 11024 "neg{l}\t%k0"
9b70259d
JH
11025 [(set_attr "type" "negnot")
11026 (set_attr "mode" "SI")])
11027
06a964de 11028(define_expand "neghi2"
7ae14d31
UB
11029 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11030 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
d9f32422 11031 "TARGET_HIMODE_MATH"
06a964de
JH
11032 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
11033
11034(define_insn "*neghi2_1"
2ae0f82c 11035 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 11036 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
8bc527af 11037 (clobber (reg:CC FLAGS_REG))]
06a964de 11038 "ix86_unary_operator_ok (NEG, HImode, operands)"
0f40f9f7 11039 "neg{w}\t%0"
6ef67412
JH
11040 [(set_attr "type" "negnot")
11041 (set_attr "mode" "HI")])
e075ae69 11042
16189740 11043(define_insn "*neghi2_cmpz"
8bc527af 11044 [(set (reg:CCZ FLAGS_REG)
16189740
RH
11045 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11046 (const_int 0)))
e075ae69
RH
11047 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11048 (neg:HI (match_dup 1)))]
06a964de 11049 "ix86_unary_operator_ok (NEG, HImode, operands)"
0f40f9f7 11050 "neg{w}\t%0"
6ef67412
JH
11051 [(set_attr "type" "negnot")
11052 (set_attr "mode" "HI")])
886c62d1 11053
06a964de 11054(define_expand "negqi2"
7ae14d31
UB
11055 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11056 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
d9f32422 11057 "TARGET_QIMODE_MATH"
06a964de
JH
11058 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
11059
11060(define_insn "*negqi2_1"
2ae0f82c 11061 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 11062 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
8bc527af 11063 (clobber (reg:CC FLAGS_REG))]
06a964de 11064 "ix86_unary_operator_ok (NEG, QImode, operands)"
0f40f9f7 11065 "neg{b}\t%0"
6ef67412
JH
11066 [(set_attr "type" "negnot")
11067 (set_attr "mode" "QI")])
e075ae69 11068
16189740 11069(define_insn "*negqi2_cmpz"
8bc527af 11070 [(set (reg:CCZ FLAGS_REG)
16189740
RH
11071 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11072 (const_int 0)))
e075ae69
RH
11073 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11074 (neg:QI (match_dup 1)))]
06a964de 11075 "ix86_unary_operator_ok (NEG, QImode, operands)"
0f40f9f7 11076 "neg{b}\t%0"
6ef67412
JH
11077 [(set_attr "type" "negnot")
11078 (set_attr "mode" "QI")])
886c62d1 11079
06a964de 11080;; Changing of sign for FP values is doable using integer unit too.
1ce485ec 11081
6dd18eb1 11082(define_expand "<code><mode>2"
6b761851 11083 [(set (match_operand:X87MODEF 0 "register_operand" "")
6dd18eb1 11084 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
6b761851 11085 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6dd18eb1 11086 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
b3298882 11087
6b761851
UB
11088(define_insn "*absneg<mode>2_mixed"
11089 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
11090 (match_operator:MODEF 3 "absneg_operator"
11091 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
11092 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8bc527af 11093 (clobber (reg:CC FLAGS_REG))]
6b761851 11094 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
141e454b
JH
11095 "#")
11096
6b761851
UB
11097(define_insn "*absneg<mode>2_sse"
11098 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
11099 (match_operator:MODEF 3 "absneg_operator"
11100 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
11101 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8bc527af 11102 (clobber (reg:CC FLAGS_REG))]
6b761851 11103 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
b3298882
JH
11104 "#")
11105
6b761851
UB
11106(define_insn "*absneg<mode>2_i387"
11107 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
11108 (match_operator:X87MODEF 3 "absneg_operator"
11109 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
7cacf53e 11110 (use (match_operand 2 "" ""))
8bc527af 11111 (clobber (reg:CC FLAGS_REG))]
6b761851 11112 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7cacf53e
RH
11113 "#")
11114
6dd18eb1 11115(define_expand "<code>tf2"
6b761851 11116 [(set (match_operand:TF 0 "register_operand" "")
6dd18eb1 11117 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
5bb77598 11118 "TARGET_SSE2"
6dd18eb1 11119 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
edc5bbcd
UB
11120
11121(define_insn "*absnegtf2_sse"
6b761851 11122 [(set (match_operand:TF 0 "register_operand" "=x,x")
edc5bbcd 11123 (match_operator:TF 3 "absneg_operator"
6b761851
UB
11124 [(match_operand:TF 1 "register_operand" "0,x")]))
11125 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
edc5bbcd 11126 (clobber (reg:CC FLAGS_REG))]
5bb77598 11127 "TARGET_SSE2"
edc5bbcd
UB
11128 "#")
11129
7cacf53e 11130;; Splitters for fp abs and neg.
b3298882 11131
141e454b 11132(define_split
7cacf53e
RH
11133 [(set (match_operand 0 "fp_register_operand" "")
11134 (match_operator 1 "absneg_operator" [(match_dup 0)]))
11135 (use (match_operand 2 "" ""))
8bc527af 11136 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
11137 "reload_completed"
11138 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
141e454b 11139
b3298882 11140(define_split
7cacf53e
RH
11141 [(set (match_operand 0 "register_operand" "")
11142 (match_operator 3 "absneg_operator"
11143 [(match_operand 1 "register_operand" "")]))
11144 (use (match_operand 2 "nonimmediate_operand" ""))
8bc527af 11145 (clobber (reg:CC FLAGS_REG))]
b3298882 11146 "reload_completed && SSE_REG_P (operands[0])"
7cacf53e 11147 [(set (match_dup 0) (match_dup 3))]
b3298882 11148{
7cacf53e
RH
11149 enum machine_mode mode = GET_MODE (operands[0]);
11150 enum machine_mode vmode = GET_MODE (operands[2]);
11151 rtx tmp;
6300f037 11152
7cacf53e
RH
11153 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
11154 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
b3298882
JH
11155 if (operands_match_p (operands[0], operands[2]))
11156 {
b3298882
JH
11157 tmp = operands[1];
11158 operands[1] = operands[2];
11159 operands[2] = tmp;
11160 }
7cacf53e
RH
11161 if (GET_CODE (operands[3]) == ABS)
11162 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
11163 else
11164 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
11165 operands[3] = tmp;
0f40f9f7 11166})
06a964de 11167
1ce485ec 11168(define_split
7cacf53e
RH
11169 [(set (match_operand:SF 0 "register_operand" "")
11170 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
11171 (use (match_operand:V4SF 2 "" ""))
8bc527af 11172 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
11173 "reload_completed"
11174 [(parallel [(set (match_dup 0) (match_dup 1))
11175 (clobber (reg:CC FLAGS_REG))])]
6300f037 11176{
7cacf53e
RH
11177 rtx tmp;
11178 operands[0] = gen_lowpart (SImode, operands[0]);
11179 if (GET_CODE (operands[1]) == ABS)
11180 {
11181 tmp = gen_int_mode (0x7fffffff, SImode);
11182 tmp = gen_rtx_AND (SImode, operands[0], tmp);
11183 }
11184 else
11185 {
11186 tmp = gen_int_mode (0x80000000, SImode);
11187 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11188 }
11189 operands[1] = tmp;
11190})
1ce485ec
JH
11191
11192(define_split
7cacf53e
RH
11193 [(set (match_operand:DF 0 "register_operand" "")
11194 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
11195 (use (match_operand 2 "" ""))
8bc527af 11196 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
11197 "reload_completed"
11198 [(parallel [(set (match_dup 0) (match_dup 1))
8bc527af 11199 (clobber (reg:CC FLAGS_REG))])]
7cacf53e
RH
11200{
11201 rtx tmp;
11202 if (TARGET_64BIT)
11203 {
11204 tmp = gen_lowpart (DImode, operands[0]);
11205 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
11206 operands[0] = tmp;
2b589241 11207
7cacf53e
RH
11208 if (GET_CODE (operands[1]) == ABS)
11209 tmp = const0_rtx;
11210 else
11211 tmp = gen_rtx_NOT (DImode, tmp);
11212 }
11213 else
11214 {
11215 operands[0] = gen_highpart (SImode, operands[0]);
11216 if (GET_CODE (operands[1]) == ABS)
11217 {
11218 tmp = gen_int_mode (0x7fffffff, SImode);
11219 tmp = gen_rtx_AND (SImode, operands[0], tmp);
11220 }
11221 else
11222 {
11223 tmp = gen_int_mode (0x80000000, SImode);
11224 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11225 }
11226 }
11227 operands[1] = tmp;
11228})
1ce485ec
JH
11229
11230(define_split
7cacf53e
RH
11231 [(set (match_operand:XF 0 "register_operand" "")
11232 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
11233 (use (match_operand 2 "" ""))
8bc527af 11234 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
11235 "reload_completed"
11236 [(parallel [(set (match_dup 0) (match_dup 1))
11237 (clobber (reg:CC FLAGS_REG))])]
11238{
11239 rtx tmp;
11240 operands[0] = gen_rtx_REG (SImode,
11241 true_regnum (operands[0])
11242 + (TARGET_64BIT ? 1 : 2));
11243 if (GET_CODE (operands[1]) == ABS)
11244 {
11245 tmp = GEN_INT (0x7fff);
11246 tmp = gen_rtx_AND (SImode, operands[0], tmp);
11247 }
11248 else
11249 {
11250 tmp = GEN_INT (0x8000);
11251 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11252 }
11253 operands[1] = tmp;
11254})
1ce485ec 11255
6300f037 11256;; Conditionalize these after reload. If they match before reload, we
1ce485ec
JH
11257;; lose the clobber and ability to use integer instructions.
11258
6dd18eb1 11259(define_insn "*<code><mode>2_1"
6b761851 11260 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6dd18eb1 11261 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
6b761851 11262 "TARGET_80387
6dd18eb1
UB
11263 && (reload_completed
11264 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
11265 "f<absnegprefix>"
7cacf53e 11266 [(set_attr "type" "fsgn")
6b761851 11267 (set_attr "mode" "<MODE>")])
4fb21e90 11268
6dd18eb1 11269(define_insn "*<code>extendsfdf2"
886c62d1 11270 [(set (match_operand:DF 0 "register_operand" "=f")
6dd18eb1
UB
11271 (absneg:DF (float_extend:DF
11272 (match_operand:SF 1 "register_operand" "0"))))]
7cacf53e 11273 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
6dd18eb1 11274 "f<absnegprefix>"
6ef67412
JH
11275 [(set_attr "type" "fsgn")
11276 (set_attr "mode" "DF")])
4fb21e90 11277
6dd18eb1 11278(define_insn "*<code>extendsfxf2"
4fb21e90 11279 [(set (match_operand:XF 0 "register_operand" "=f")
6dd18eb1
UB
11280 (absneg:XF (float_extend:XF
11281 (match_operand:SF 1 "register_operand" "0"))))]
f8a1ebc6 11282 "TARGET_80387"
6dd18eb1 11283 "f<absnegprefix>"
6ef67412
JH
11284 [(set_attr "type" "fsgn")
11285 (set_attr "mode" "XF")])
a199fdd6 11286
6dd18eb1 11287(define_insn "*<code>extenddfxf2"
58733f96 11288 [(set (match_operand:XF 0 "register_operand" "=f")
6dd18eb1
UB
11289 (absneg:XF (float_extend:XF
11290 (match_operand:DF 1 "register_operand" "0"))))]
2b589241 11291 "TARGET_80387"
6dd18eb1 11292 "f<absnegprefix>"
2b589241
JH
11293 [(set_attr "type" "fsgn")
11294 (set_attr "mode" "XF")])
edc5bbcd
UB
11295
11296;; Copysign instructions
11297
3abcb3a7 11298(define_mode_iterator CSGNMODE [SF DF TF])
edc5bbcd
UB
11299(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
11300
11301(define_expand "copysign<mode>3"
11302 [(match_operand:CSGNMODE 0 "register_operand" "")
11303 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
11304 (match_operand:CSGNMODE 2 "register_operand" "")]
11305 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5bb77598 11306 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
edc5bbcd
UB
11307{
11308 ix86_expand_copysign (operands);
11309 DONE;
11310})
11311
11312(define_insn_and_split "copysign<mode>3_const"
11313 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
11314 (unspec:CSGNMODE
11315 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
11316 (match_operand:CSGNMODE 2 "register_operand" "0")
11317 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
11318 UNSPEC_COPYSIGN))]
11319 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5bb77598 11320 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
edc5bbcd
UB
11321 "#"
11322 "&& reload_completed"
11323 [(const_int 0)]
11324{
11325 ix86_split_copysign_const (operands);
11326 DONE;
11327})
11328
11329(define_insn "copysign<mode>3_var"
11330 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
11331 (unspec:CSGNMODE
11332 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
11333 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
11334 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
11335 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
11336 UNSPEC_COPYSIGN))
11337 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
11338 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5bb77598 11339 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
edc5bbcd
UB
11340 "#")
11341
11342(define_split
11343 [(set (match_operand:CSGNMODE 0 "register_operand" "")
11344 (unspec:CSGNMODE
11345 [(match_operand:CSGNMODE 2 "register_operand" "")
11346 (match_operand:CSGNMODE 3 "register_operand" "")
11347 (match_operand:<CSGNVMODE> 4 "" "")
11348 (match_operand:<CSGNVMODE> 5 "" "")]
11349 UNSPEC_COPYSIGN))
11350 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
11351 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5bb77598 11352 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
edc5bbcd
UB
11353 && reload_completed"
11354 [(const_int 0)]
11355{
11356 ix86_split_copysign_var (operands);
11357 DONE;
11358})
886c62d1 11359\f
e075ae69 11360;; One complement instructions
886c62d1 11361
9b70259d
JH
11362(define_expand "one_cmpldi2"
11363 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11364 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
11365 "TARGET_64BIT"
11366 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
11367
11368(define_insn "*one_cmpldi2_1_rex64"
11369 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11370 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
11371 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
0f40f9f7 11372 "not{q}\t%0"
9b70259d
JH
11373 [(set_attr "type" "negnot")
11374 (set_attr "mode" "DI")])
11375
11376(define_insn "*one_cmpldi2_2_rex64"
42fabf21 11377 [(set (reg FLAGS_REG)
9b70259d
JH
11378 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
11379 (const_int 0)))
11380 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11381 (not:DI (match_dup 1)))]
11382 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11383 && ix86_unary_operator_ok (NOT, DImode, operands)"
11384 "#"
11385 [(set_attr "type" "alu1")
11386 (set_attr "mode" "DI")])
11387
11388(define_split
25da5dc7
RH
11389 [(set (match_operand 0 "flags_reg_operand" "")
11390 (match_operator 2 "compare_operator"
11391 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
11392 (const_int 0)]))
11393 (set (match_operand:DI 1 "nonimmediate_operand" "")
11394 (not:DI (match_dup 3)))]
9b70259d 11395 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
11396 [(parallel [(set (match_dup 0)
11397 (match_op_dup 2
11398 [(xor:DI (match_dup 3) (const_int -1))
11399 (const_int 0)]))
11400 (set (match_dup 1)
11401 (xor:DI (match_dup 3) (const_int -1)))])]
9b70259d
JH
11402 "")
11403
06a964de 11404(define_expand "one_cmplsi2"
a1cbdd7f
JH
11405 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11406 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
06a964de
JH
11407 ""
11408 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
11409
11410(define_insn "*one_cmplsi2_1"
2ae0f82c
SC
11411 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11412 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
a1cbdd7f 11413 "ix86_unary_operator_ok (NOT, SImode, operands)"
0f40f9f7 11414 "not{l}\t%0"
6ef67412
JH
11415 [(set_attr "type" "negnot")
11416 (set_attr "mode" "SI")])
bb524860 11417
9b70259d
JH
11418;; ??? Currently never generated - xor is used instead.
11419(define_insn "*one_cmplsi2_1_zext"
11420 [(set (match_operand:DI 0 "register_operand" "=r")
11421 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
11422 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
0f40f9f7 11423 "not{l}\t%k0"
9b70259d
JH
11424 [(set_attr "type" "negnot")
11425 (set_attr "mode" "SI")])
11426
06a964de 11427(define_insn "*one_cmplsi2_2"
42fabf21 11428 [(set (reg FLAGS_REG)
16189740
RH
11429 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11430 (const_int 0)))
e075ae69
RH
11431 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11432 (not:SI (match_dup 1)))]
16189740
RH
11433 "ix86_match_ccmode (insn, CCNOmode)
11434 && ix86_unary_operator_ok (NOT, SImode, operands)"
e075ae69 11435 "#"
6ef67412
JH
11436 [(set_attr "type" "alu1")
11437 (set_attr "mode" "SI")])
e075ae69
RH
11438
11439(define_split
25da5dc7
RH
11440 [(set (match_operand 0 "flags_reg_operand" "")
11441 (match_operator 2 "compare_operator"
11442 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
11443 (const_int 0)]))
11444 (set (match_operand:SI 1 "nonimmediate_operand" "")
11445 (not:SI (match_dup 3)))]
16189740 11446 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
11447 [(parallel [(set (match_dup 0)
11448 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11449 (const_int 0)]))
11450 (set (match_dup 1)
11451 (xor:SI (match_dup 3) (const_int -1)))])]
e075ae69 11452 "")
886c62d1 11453
9b70259d
JH
11454;; ??? Currently never generated - xor is used instead.
11455(define_insn "*one_cmplsi2_2_zext"
42fabf21 11456 [(set (reg FLAGS_REG)
9b70259d
JH
11457 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
11458 (const_int 0)))
11459 (set (match_operand:DI 0 "register_operand" "=r")
11460 (zero_extend:DI (not:SI (match_dup 1))))]
11461 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11462 && ix86_unary_operator_ok (NOT, SImode, operands)"
11463 "#"
11464 [(set_attr "type" "alu1")
11465 (set_attr "mode" "SI")])
11466
11467(define_split
25da5dc7
RH
11468 [(set (match_operand 0 "flags_reg_operand" "")
11469 (match_operator 2 "compare_operator"
11470 [(not:SI (match_operand:SI 3 "register_operand" ""))
11471 (const_int 0)]))
11472 (set (match_operand:DI 1 "register_operand" "")
11473 (zero_extend:DI (not:SI (match_dup 3))))]
9b70259d 11474 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
11475 [(parallel [(set (match_dup 0)
11476 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11477 (const_int 0)]))
11478 (set (match_dup 1)
11479 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9b70259d
JH
11480 "")
11481
06a964de 11482(define_expand "one_cmplhi2"
a1cbdd7f
JH
11483 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11484 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
d9f32422 11485 "TARGET_HIMODE_MATH"
06a964de
JH
11486 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11487
11488(define_insn "*one_cmplhi2_1"
2ae0f82c
SC
11489 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11490 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
a1cbdd7f 11491 "ix86_unary_operator_ok (NOT, HImode, operands)"
0f40f9f7 11492 "not{w}\t%0"
6ef67412
JH
11493 [(set_attr "type" "negnot")
11494 (set_attr "mode" "HI")])
bb524860 11495
06a964de 11496(define_insn "*one_cmplhi2_2"
42fabf21 11497 [(set (reg FLAGS_REG)
16189740
RH
11498 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11499 (const_int 0)))
e075ae69
RH
11500 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11501 (not:HI (match_dup 1)))]
16189740
RH
11502 "ix86_match_ccmode (insn, CCNOmode)
11503 && ix86_unary_operator_ok (NEG, HImode, operands)"
e075ae69 11504 "#"
6ef67412
JH
11505 [(set_attr "type" "alu1")
11506 (set_attr "mode" "HI")])
e075ae69
RH
11507
11508(define_split
25da5dc7
RH
11509 [(set (match_operand 0 "flags_reg_operand" "")
11510 (match_operator 2 "compare_operator"
11511 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11512 (const_int 0)]))
11513 (set (match_operand:HI 1 "nonimmediate_operand" "")
11514 (not:HI (match_dup 3)))]
16189740 11515 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
11516 [(parallel [(set (match_dup 0)
11517 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11518 (const_int 0)]))
11519 (set (match_dup 1)
11520 (xor:HI (match_dup 3) (const_int -1)))])]
e075ae69 11521 "")
886c62d1 11522
e075ae69 11523;; %%% Potential partial reg stall on alternative 1. What to do?
06a964de 11524(define_expand "one_cmplqi2"
a1cbdd7f
JH
11525 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11526 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
d9f32422 11527 "TARGET_QIMODE_MATH"
06a964de
JH
11528 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11529
11530(define_insn "*one_cmplqi2_1"
7c6b971d 11531 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
e075ae69 11532 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
a1cbdd7f 11533 "ix86_unary_operator_ok (NOT, QImode, operands)"
e075ae69 11534 "@
0f40f9f7
ZW
11535 not{b}\t%0
11536 not{l}\t%k0"
6ef67412
JH
11537 [(set_attr "type" "negnot")
11538 (set_attr "mode" "QI,SI")])
bb524860 11539
06a964de 11540(define_insn "*one_cmplqi2_2"
42fabf21 11541 [(set (reg FLAGS_REG)
16189740
RH
11542 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11543 (const_int 0)))
e075ae69
RH
11544 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11545 (not:QI (match_dup 1)))]
16189740
RH
11546 "ix86_match_ccmode (insn, CCNOmode)
11547 && ix86_unary_operator_ok (NOT, QImode, operands)"
e075ae69 11548 "#"
6ef67412
JH
11549 [(set_attr "type" "alu1")
11550 (set_attr "mode" "QI")])
e075ae69
RH
11551
11552(define_split
25da5dc7
RH
11553 [(set (match_operand 0 "flags_reg_operand" "")
11554 (match_operator 2 "compare_operator"
11555 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11556 (const_int 0)]))
11557 (set (match_operand:QI 1 "nonimmediate_operand" "")
11558 (not:QI (match_dup 3)))]
16189740 11559 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
11560 [(parallel [(set (match_dup 0)
11561 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11562 (const_int 0)]))
11563 (set (match_dup 1)
11564 (xor:QI (match_dup 3) (const_int -1)))])]
e075ae69 11565 "")
886c62d1 11566\f
e075ae69 11567;; Arithmetic shift instructions
886c62d1
JVA
11568
11569;; DImode shifts are implemented using the i386 "shift double" opcode,
11570;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11571;; is variable, then the count is in %cl and the "imm" operand is dropped
11572;; from the assembler input.
e075ae69 11573;;
886c62d1
JVA
11574;; This instruction shifts the target reg/mem as usual, but instead of
11575;; shifting in zeros, bits are shifted in from reg operand. If the insn
11576;; is a left shift double, bits are taken from the high order bits of
11577;; reg, else if the insn is a shift right double, bits are taken from the
11578;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11579;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
e075ae69 11580;;
886c62d1
JVA
11581;; Since sh[lr]d does not change the `reg' operand, that is done
11582;; separately, making all shifts emit pairs of shift double and normal
11583;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11584;; support a 63 bit shift, each shift where the count is in a reg expands
f58acb67 11585;; to a pair of shifts, a branch, a shift by 32 and a label.
e075ae69 11586;;
886c62d1
JVA
11587;; If the shift count is a constant, we need never emit more than one
11588;; shift pair, instead using moves and sign extension for counts greater
11589;; than 31.
11590
28356f52 11591(define_expand "ashlti3"
934f2a96
UB
11592 [(set (match_operand:TI 0 "register_operand" "")
11593 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11594 (match_operand:QI 2 "nonmemory_operand" "")))]
28356f52 11595 "TARGET_64BIT"
934f2a96 11596 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
28356f52 11597
934f2a96
UB
11598;; This pattern must be defined before *ashlti3_1 to prevent
11599;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
69c553ef 11600
95879c72
L
11601(define_insn "*avx_ashlti3"
11602 [(set (match_operand:TI 0 "register_operand" "=x")
11603 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11604 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11605 "TARGET_AVX"
11606{
11607 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11608 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11609}
11610 [(set_attr "type" "sseishft")
11611 (set_attr "prefix" "vex")
725fd454 11612 (set_attr "length_immediate" "1")
95879c72
L
11613 (set_attr "mode" "TI")])
11614
69c553ef
UB
11615(define_insn "sse2_ashlti3"
11616 [(set (match_operand:TI 0 "register_operand" "=x")
11617 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11618 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11619 "TARGET_SSE2"
11620{
11621 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11622 return "pslldq\t{%2, %0|%0, %2}";
11623}
11624 [(set_attr "type" "sseishft")
11625 (set_attr "prefix_data16" "1")
725fd454 11626 (set_attr "length_immediate" "1")
69c553ef
UB
11627 (set_attr "mode" "TI")])
11628
934f2a96
UB
11629(define_insn "*ashlti3_1"
11630 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11631 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11632 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
28356f52
JB
11633 (clobber (reg:CC FLAGS_REG))]
11634 "TARGET_64BIT"
11635 "#"
11636 [(set_attr "type" "multi")])
11637
934f2a96
UB
11638(define_peephole2
11639 [(match_scratch:DI 3 "r")
11640 (parallel [(set (match_operand:TI 0 "register_operand" "")
11641 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11642 (match_operand:QI 2 "nonmemory_operand" "")))
11643 (clobber (reg:CC FLAGS_REG))])
11644 (match_dup 3)]
11645 "TARGET_64BIT"
28356f52
JB
11646 [(const_int 0)]
11647 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11648
11649(define_split
11650 [(set (match_operand:TI 0 "register_operand" "")
934f2a96
UB
11651 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11652 (match_operand:QI 2 "nonmemory_operand" "")))
28356f52 11653 (clobber (reg:CC FLAGS_REG))]
934f2a96
UB
11654 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11655 ? epilogue_completed : reload_completed)"
28356f52
JB
11656 [(const_int 0)]
11657 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11658
11659(define_insn "x86_64_shld"
934f2a96 11660 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
28356f52 11661 (ior:DI (ashift:DI (match_dup 0)
934f2a96
UB
11662 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11663 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
28356f52
JB
11664 (minus:QI (const_int 64) (match_dup 2)))))
11665 (clobber (reg:CC FLAGS_REG))]
11666 "TARGET_64BIT"
934f2a96 11667 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
28356f52
JB
11668 [(set_attr "type" "ishift")
11669 (set_attr "prefix_0f" "1")
11670 (set_attr "mode" "DI")
21efb4d4 11671 (set_attr "athlon_decode" "vector")
4f3f76e6 11672 (set_attr "amdfam10_decode" "vector")])
28356f52 11673
72ea2555 11674(define_expand "x86_64_shift_adj_1"
28356f52
JB
11675 [(set (reg:CCZ FLAGS_REG)
11676 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11677 (const_int 64))
11678 (const_int 0)))
11679 (set (match_operand:DI 0 "register_operand" "")
11680 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11681 (match_operand:DI 1 "register_operand" "")
11682 (match_dup 0)))
11683 (set (match_dup 1)
11684 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11685 (match_operand:DI 3 "register_operand" "r")
11686 (match_dup 1)))]
11687 "TARGET_64BIT"
11688 "")
11689
72ea2555
UB
11690(define_expand "x86_64_shift_adj_2"
11691 [(use (match_operand:DI 0 "register_operand" ""))
11692 (use (match_operand:DI 1 "register_operand" ""))
11693 (use (match_operand:QI 2 "register_operand" ""))]
11694 "TARGET_64BIT"
11695{
11696 rtx label = gen_label_rtx ();
11697 rtx tmp;
11698
11699 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11700
11701 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11702 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11703 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11704 gen_rtx_LABEL_REF (VOIDmode, label),
11705 pc_rtx);
11706 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11707 JUMP_LABEL (tmp) = label;
11708
11709 emit_move_insn (operands[0], operands[1]);
11710 ix86_expand_clear (operands[1]);
11711
11712 emit_label (label);
11713 LABEL_NUSES (label) = 1;
11714
11715 DONE;
11716})
11717
56c0e8fa 11718(define_expand "ashldi3"
93330ea1
RH
11719 [(set (match_operand:DI 0 "shiftdi_operand" "")
11720 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11721 (match_operand:QI 2 "nonmemory_operand" "")))]
56c0e8fa 11722 ""
93330ea1 11723 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
56c0e8fa 11724
371bc54b
JH
11725(define_insn "*ashldi3_1_rex64"
11726 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9a9286af 11727 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
7c17f553 11728 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
8bc527af 11729 (clobber (reg:CC FLAGS_REG))]
371bc54b 11730 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
371bc54b
JH
11731{
11732 switch (get_attr_type (insn))
11733 {
11734 case TYPE_ALU:
7637e42c
NS
11735 gcc_assert (operands[2] == const1_rtx);
11736 gcc_assert (rtx_equal_p (operands[0], operands[1]));
a23132e1 11737 return "add{q}\t%0, %0";
371bc54b
JH
11738
11739 case TYPE_LEA:
7656aee4 11740 gcc_assert (CONST_INT_P (operands[2]));
7637e42c 11741 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
371bc54b
JH
11742 operands[1] = gen_rtx_MULT (DImode, operands[1],
11743 GEN_INT (1 << INTVAL (operands[2])));
0f40f9f7 11744 return "lea{q}\t{%a1, %0|%0, %a1}";
371bc54b
JH
11745
11746 default:
11747 if (REG_P (operands[2]))
0f40f9f7 11748 return "sal{q}\t{%b2, %0|%0, %b2}";
b4e0dd8e 11749 else if (operands[2] == const1_rtx
3debdc1e 11750 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
0f40f9f7 11751 return "sal{q}\t%0";
371bc54b 11752 else
0f40f9f7 11753 return "sal{q}\t{%2, %0|%0, %2}";
371bc54b 11754 }
0f40f9f7 11755}
371bc54b
JH
11756 [(set (attr "type")
11757 (cond [(eq_attr "alternative" "1")
11758 (const_string "lea")
11759 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11760 (const_int 0))
11761 (match_operand 0 "register_operand" ""))
11762 (match_operand 2 "const1_operand" ""))
11763 (const_string "alu")
11764 ]
11765 (const_string "ishift")))
a952487c
JJ
11766 (set (attr "length_immediate")
11767 (if_then_else
11768 (ior (eq_attr "type" "alu")
11769 (and (eq_attr "type" "ishift")
11770 (and (match_operand 2 "const1_operand" "")
11771 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11772 (const_int 0)))))
11773 (const_string "0")
11774 (const_string "*")))
371bc54b
JH
11775 (set_attr "mode" "DI")])
11776
11777;; Convert lea to the lea pattern to avoid flags dependency.
11778(define_split
11779 [(set (match_operand:DI 0 "register_operand" "")
9a9286af 11780 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
371bc54b 11781 (match_operand:QI 2 "immediate_operand" "")))
8bc527af 11782 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 11783 "TARGET_64BIT && reload_completed
371bc54b
JH
11784 && true_regnum (operands[0]) != true_regnum (operands[1])"
11785 [(set (match_dup 0)
11786 (mult:DI (match_dup 1)
11787 (match_dup 2)))]
d8bf17f9 11788 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
371bc54b
JH
11789
11790;; This pattern can't accept a variable shift count, since shifts by
11791;; zero don't affect the flags. We assume that shifts by constant
11792;; zero are optimized away.
11793(define_insn "*ashldi3_cmp_rex64"
42fabf21 11794 [(set (reg FLAGS_REG)
371bc54b
JH
11795 (compare
11796 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
934f2a96 11797 (match_operand:QI 2 "const_1_to_63_operand" "J"))
371bc54b
JH
11798 (const_int 0)))
11799 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11800 (ashift:DI (match_dup 1) (match_dup 2)))]
d5d5d289 11801 "TARGET_64BIT
3debdc1e 11802 && (optimize_function_for_size_p (cfun)
995cc369
L
11803 || !TARGET_PARTIAL_FLAG_REG_STALL
11804 || (operands[2] == const1_rtx
11805 && (TARGET_SHIFT1
d5d5d289
L
11806 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11807 && ix86_match_ccmode (insn, CCGOCmode)
11808 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
371bc54b
JH
11809{
11810 switch (get_attr_type (insn))
11811 {
11812 case TYPE_ALU:
7637e42c 11813 gcc_assert (operands[2] == const1_rtx);
a23132e1 11814 return "add{q}\t%0, %0";
371bc54b
JH
11815
11816 default:
11817 if (REG_P (operands[2]))
0f40f9f7 11818 return "sal{q}\t{%b2, %0|%0, %b2}";
b4e0dd8e 11819 else if (operands[2] == const1_rtx
3debdc1e 11820 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
0f40f9f7 11821 return "sal{q}\t%0";
371bc54b 11822 else
0f40f9f7 11823 return "sal{q}\t{%2, %0|%0, %2}";
371bc54b 11824 }
0f40f9f7 11825}
371bc54b
JH
11826 [(set (attr "type")
11827 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11828 (const_int 0))
11829 (match_operand 0 "register_operand" ""))
11830 (match_operand 2 "const1_operand" ""))
11831 (const_string "alu")
11832 ]
11833 (const_string "ishift")))
a952487c
JJ
11834 (set (attr "length_immediate")
11835 (if_then_else
11836 (ior (eq_attr "type" "alu")
11837 (and (eq_attr "type" "ishift")
11838 (and (match_operand 2 "const1_operand" "")
11839 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11840 (const_int 0)))))
11841 (const_string "0")
11842 (const_string "*")))
371bc54b
JH
11843 (set_attr "mode" "DI")])
11844
f42684d5
UB
11845(define_insn "*ashldi3_cconly_rex64"
11846 [(set (reg FLAGS_REG)
11847 (compare
11848 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
934f2a96 11849 (match_operand:QI 2 "const_1_to_63_operand" "J"))
f42684d5
UB
11850 (const_int 0)))
11851 (clobber (match_scratch:DI 0 "=r"))]
d5d5d289 11852 "TARGET_64BIT
3debdc1e 11853 && (optimize_function_for_size_p (cfun)
995cc369
L
11854 || !TARGET_PARTIAL_FLAG_REG_STALL
11855 || (operands[2] == const1_rtx
11856 && (TARGET_SHIFT1
d5d5d289
L
11857 || TARGET_DOUBLE_WITH_ADD)))
11858 && ix86_match_ccmode (insn, CCGOCmode)
11859 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
f42684d5
UB
11860{
11861 switch (get_attr_type (insn))
11862 {
11863 case TYPE_ALU:
11864 gcc_assert (operands[2] == const1_rtx);
a23132e1 11865 return "add{q}\t%0, %0";
f42684d5
UB
11866
11867 default:
11868 if (REG_P (operands[2]))
11869 return "sal{q}\t{%b2, %0|%0, %b2}";
11870 else if (operands[2] == const1_rtx
3debdc1e 11871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
f42684d5
UB
11872 return "sal{q}\t%0";
11873 else
11874 return "sal{q}\t{%2, %0|%0, %2}";
11875 }
11876}
11877 [(set (attr "type")
11878 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11879 (const_int 0))
11880 (match_operand 0 "register_operand" ""))
11881 (match_operand 2 "const1_operand" ""))
11882 (const_string "alu")
11883 ]
11884 (const_string "ishift")))
a952487c
JJ
11885 (set (attr "length_immediate")
11886 (if_then_else
11887 (ior (eq_attr "type" "alu")
11888 (and (eq_attr "type" "ishift")
11889 (and (match_operand 2 "const1_operand" "")
11890 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11891 (const_int 0)))))
11892 (const_string "0")
11893 (const_string "*")))
f42684d5
UB
11894 (set_attr "mode" "DI")])
11895
93330ea1
RH
11896(define_insn "*ashldi3_1"
11897 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11898 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11899 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
8bc527af 11900 (clobber (reg:CC FLAGS_REG))]
371bc54b 11901 "!TARGET_64BIT"
e075ae69
RH
11902 "#"
11903 [(set_attr "type" "multi")])
886c62d1 11904
93330ea1
RH
11905;; By default we don't ask for a scratch register, because when DImode
11906;; values are manipulated, registers are already at a premium. But if
11907;; we have one handy, we won't turn it away.
11908(define_peephole2
11909 [(match_scratch:SI 3 "r")
11910 (parallel [(set (match_operand:DI 0 "register_operand" "")
11911 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11912 (match_operand:QI 2 "nonmemory_operand" "")))
11913 (clobber (reg:CC FLAGS_REG))])
11914 (match_dup 3)]
11915 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69 11916 [(const_int 0)]
28356f52 11917 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
47f59fd4 11918
e075ae69
RH
11919(define_split
11920 [(set (match_operand:DI 0 "register_operand" "")
93330ea1 11921 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
e075ae69 11922 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11923 (clobber (reg:CC FLAGS_REG))]
99523994 11924 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
6fb5fa3c 11925 ? epilogue_completed : reload_completed)"
e075ae69 11926 [(const_int 0)]
28356f52 11927 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
6ec6d558 11928
934f2a96
UB
11929(define_insn "x86_shld"
11930 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
e075ae69 11931 (ior:SI (ashift:SI (match_dup 0)
934f2a96
UB
11932 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11933 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
e075ae69 11934 (minus:QI (const_int 32) (match_dup 2)))))
8bc527af 11935 (clobber (reg:CC FLAGS_REG))]
6ec6d558 11936 ""
934f2a96 11937 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
e075ae69 11938 [(set_attr "type" "ishift")
6ef67412
JH
11939 (set_attr "prefix_0f" "1")
11940 (set_attr "mode" "SI")
e075ae69 11941 (set_attr "pent_pair" "np")
21efb4d4 11942 (set_attr "athlon_decode" "vector")
4f3f76e6 11943 (set_attr "amdfam10_decode" "vector")])
e075ae69
RH
11944
11945(define_expand "x86_shift_adj_1"
8bc527af 11946 [(set (reg:CCZ FLAGS_REG)
16189740
RH
11947 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11948 (const_int 32))
11949 (const_int 0)))
e075ae69 11950 (set (match_operand:SI 0 "register_operand" "")
8bc527af 11951 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
e075ae69
RH
11952 (match_operand:SI 1 "register_operand" "")
11953 (match_dup 0)))
11954 (set (match_dup 1)
8bc527af 11955 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
e075ae69
RH
11956 (match_operand:SI 3 "register_operand" "r")
11957 (match_dup 1)))]
11958 "TARGET_CMOVE"
6ec6d558
JH
11959 "")
11960
e075ae69
RH
11961(define_expand "x86_shift_adj_2"
11962 [(use (match_operand:SI 0 "register_operand" ""))
11963 (use (match_operand:SI 1 "register_operand" ""))
11964 (use (match_operand:QI 2 "register_operand" ""))]
886c62d1 11965 ""
e075ae69
RH
11966{
11967 rtx label = gen_label_rtx ();
11968 rtx tmp;
886c62d1 11969
16189740 11970 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
886c62d1 11971
16189740 11972 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
11973 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11974 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11975 gen_rtx_LABEL_REF (VOIDmode, label),
11976 pc_rtx);
11977 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11978 JUMP_LABEL (tmp) = label;
886c62d1 11979
e075ae69 11980 emit_move_insn (operands[0], operands[1]);
93330ea1 11981 ix86_expand_clear (operands[1]);
886c62d1 11982
e075ae69
RH
11983 emit_label (label);
11984 LABEL_NUSES (label) = 1;
56c0e8fa
JVA
11985
11986 DONE;
0f40f9f7 11987})
56c0e8fa 11988
d525dfdf
JH
11989(define_expand "ashlsi3"
11990 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11991 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
7ae14d31 11992 (match_operand:QI 2 "nonmemory_operand" "")))]
d525dfdf
JH
11993 ""
11994 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11995
11996(define_insn "*ashlsi3_1"
e075ae69 11997 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9a9286af 11998 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
e075ae69 11999 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8bc527af 12000 (clobber (reg:CC FLAGS_REG))]
d525dfdf 12001 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
2ae0f82c 12002{
e075ae69
RH
12003 switch (get_attr_type (insn))
12004 {
12005 case TYPE_ALU:
7637e42c
NS
12006 gcc_assert (operands[2] == const1_rtx);
12007 gcc_assert (rtx_equal_p (operands[0], operands[1]));
a23132e1 12008 return "add{l}\t%0, %0";
2ae0f82c 12009
e075ae69 12010 case TYPE_LEA:
0f40f9f7 12011 return "#";
2ae0f82c 12012
e075ae69
RH
12013 default:
12014 if (REG_P (operands[2]))
0f40f9f7 12015 return "sal{l}\t{%b2, %0|%0, %b2}";
b4e0dd8e 12016 else if (operands[2] == const1_rtx
3debdc1e 12017 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
0f40f9f7 12018 return "sal{l}\t%0";
e075ae69 12019 else
0f40f9f7 12020 return "sal{l}\t{%2, %0|%0, %2}";
e075ae69 12021 }
0f40f9f7 12022}
e075ae69
RH
12023 [(set (attr "type")
12024 (cond [(eq_attr "alternative" "1")
12025 (const_string "lea")
12026 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12027 (const_int 0))
12028 (match_operand 0 "register_operand" ""))
12029 (match_operand 2 "const1_operand" ""))
12030 (const_string "alu")
12031 ]
6ef67412 12032 (const_string "ishift")))
a952487c
JJ
12033 (set (attr "length_immediate")
12034 (if_then_else
12035 (ior (eq_attr "type" "alu")
12036 (and (eq_attr "type" "ishift")
12037 (and (match_operand 2 "const1_operand" "")
12038 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12039 (const_int 0)))))
12040 (const_string "0")
12041 (const_string "*")))
6ef67412 12042 (set_attr "mode" "SI")])
e075ae69 12043
1c27d4b2
JH
12044;; Convert lea to the lea pattern to avoid flags dependency.
12045(define_split
58787064 12046 [(set (match_operand 0 "register_operand" "")
7ec70495 12047 (ashift (match_operand 1 "index_register_operand" "")
ca4ae08d 12048 (match_operand:QI 2 "const_int_operand" "")))
8bc527af 12049 (clobber (reg:CC FLAGS_REG))]
abe24fb3 12050 "reload_completed
9a9286af
RH
12051 && true_regnum (operands[0]) != true_regnum (operands[1])
12052 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
58787064 12053 [(const_int 0)]
58787064
JH
12054{
12055 rtx pat;
9a9286af
RH
12056 enum machine_mode mode = GET_MODE (operands[0]);
12057
12058 if (GET_MODE_SIZE (mode) < 4)
12059 operands[0] = gen_lowpart (SImode, operands[0]);
12060 if (mode != Pmode)
12061 operands[1] = gen_lowpart (Pmode, operands[1]);
d8bf17f9 12062 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9a9286af 12063
58787064
JH
12064 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
12065 if (Pmode != SImode)
12066 pat = gen_rtx_SUBREG (SImode, pat, 0);
12067 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
12068 DONE;
0f40f9f7 12069})
1c27d4b2 12070
7ec70495
JH
12071;; Rare case of shifting RSP is handled by generating move and shift
12072(define_split
12073 [(set (match_operand 0 "register_operand" "")
12074 (ashift (match_operand 1 "register_operand" "")
12075 (match_operand:QI 2 "const_int_operand" "")))
8bc527af 12076 (clobber (reg:CC FLAGS_REG))]
7ec70495
JH
12077 "reload_completed
12078 && true_regnum (operands[0]) != true_regnum (operands[1])"
12079 [(const_int 0)]
12080{
12081 rtx pat, clob;
61da04bd 12082 emit_move_insn (operands[0], operands[1]);
7ec70495
JH
12083 pat = gen_rtx_SET (VOIDmode, operands[0],
12084 gen_rtx_ASHIFT (GET_MODE (operands[0]),
12085 operands[0], operands[2]));
12086 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
12087 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
12088 DONE;
12089})
12090
371bc54b
JH
12091(define_insn "*ashlsi3_1_zext"
12092 [(set (match_operand:DI 0 "register_operand" "=r,r")
9a9286af 12093 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
371bc54b 12094 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
8bc527af 12095 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 12096 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
371bc54b
JH
12097{
12098 switch (get_attr_type (insn))
12099 {
12100 case TYPE_ALU:
7637e42c 12101 gcc_assert (operands[2] == const1_rtx);
a23132e1 12102 return "add{l}\t%k0, %k0";
371bc54b
JH
12103
12104 case TYPE_LEA:
0f40f9f7 12105 return "#";
371bc54b
JH
12106
12107 default:
12108 if (REG_P (operands[2]))
0f40f9f7 12109 return "sal{l}\t{%b2, %k0|%k0, %b2}";
b4e0dd8e 12110 else if (operands[2] == const1_rtx
3debdc1e 12111 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
0f40f9f7 12112 return "sal{l}\t%k0";
371bc54b 12113 else
0f40f9f7 12114 return "sal{l}\t{%2, %k0|%k0, %2}";
371bc54b 12115 }
0f40f9f7 12116}
371bc54b
JH
12117 [(set (attr "type")
12118 (cond [(eq_attr "alternative" "1")
12119 (const_string "lea")
12120 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12121 (const_int 0))
12122 (match_operand 2 "const1_operand" ""))
12123 (const_string "alu")
12124 ]
12125 (const_string "ishift")))
a952487c
JJ
12126 (set (attr "length_immediate")
12127 (if_then_else
12128 (ior (eq_attr "type" "alu")
12129 (and (eq_attr "type" "ishift")
12130 (and (match_operand 2 "const1_operand" "")
12131 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12132 (const_int 0)))))
12133 (const_string "0")
12134 (const_string "*")))
371bc54b
JH
12135 (set_attr "mode" "SI")])
12136
12137;; Convert lea to the lea pattern to avoid flags dependency.
12138(define_split
12139 [(set (match_operand:DI 0 "register_operand" "")
12140 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
12141 (match_operand:QI 2 "const_int_operand" ""))))
8bc527af 12142 (clobber (reg:CC FLAGS_REG))]
bc8a6d63 12143 "TARGET_64BIT && reload_completed
371bc54b 12144 && true_regnum (operands[0]) != true_regnum (operands[1])"
bc8a6d63
RH
12145 [(set (match_dup 0) (zero_extend:DI
12146 (subreg:SI (mult:SI (match_dup 1)
12147 (match_dup 2)) 0)))]
371bc54b
JH
12148{
12149 operands[1] = gen_lowpart (Pmode, operands[1]);
d8bf17f9 12150 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
0f40f9f7 12151})
371bc54b 12152
28cefcd2
BS
12153;; This pattern can't accept a variable shift count, since shifts by
12154;; zero don't affect the flags. We assume that shifts by constant
12155;; zero are optimized away.
2c873473 12156(define_insn "*ashlsi3_cmp"
42fabf21 12157 [(set (reg FLAGS_REG)
16189740 12158 (compare
e075ae69 12159 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
ef719a44 12160 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69
RH
12161 (const_int 0)))
12162 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12163 (ashift:SI (match_dup 1) (match_dup 2)))]
3debdc1e 12164 "(optimize_function_for_size_p (cfun)
d5d5d289
L
12165 || !TARGET_PARTIAL_FLAG_REG_STALL
12166 || (operands[2] == const1_rtx
12167 && (TARGET_SHIFT1
12168 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12169 && ix86_match_ccmode (insn, CCGOCmode)
12170 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
886c62d1 12171{
e075ae69 12172 switch (get_attr_type (insn))
886c62d1 12173 {
e075ae69 12174 case TYPE_ALU:
7637e42c 12175 gcc_assert (operands[2] == const1_rtx);
a23132e1 12176 return "add{l}\t%0, %0";
886c62d1 12177
e075ae69
RH
12178 default:
12179 if (REG_P (operands[2]))
0f40f9f7 12180 return "sal{l}\t{%b2, %0|%0, %b2}";
b4e0dd8e 12181 else if (operands[2] == const1_rtx
3debdc1e 12182 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
0f40f9f7 12183 return "sal{l}\t%0";
e075ae69 12184 else
0f40f9f7 12185 return "sal{l}\t{%2, %0|%0, %2}";
56c0e8fa 12186 }
0f40f9f7 12187}
e075ae69
RH
12188 [(set (attr "type")
12189 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12190 (const_int 0))
12191 (match_operand 0 "register_operand" ""))
12192 (match_operand 2 "const1_operand" ""))
12193 (const_string "alu")
12194 ]
6ef67412 12195 (const_string "ishift")))
a952487c
JJ
12196 (set (attr "length_immediate")
12197 (if_then_else
12198 (ior (eq_attr "type" "alu")
12199 (and (eq_attr "type" "ishift")
12200 (and (match_operand 2 "const1_operand" "")
12201 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12202 (const_int 0)))))
12203 (const_string "0")
12204 (const_string "*")))
6ef67412 12205 (set_attr "mode" "SI")])
e075ae69 12206
f42684d5
UB
12207(define_insn "*ashlsi3_cconly"
12208 [(set (reg FLAGS_REG)
12209 (compare
12210 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12211 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12212 (const_int 0)))
12213 (clobber (match_scratch:SI 0 "=r"))]
3debdc1e 12214 "(optimize_function_for_size_p (cfun)
d5d5d289
L
12215 || !TARGET_PARTIAL_FLAG_REG_STALL
12216 || (operands[2] == const1_rtx
12217 && (TARGET_SHIFT1
12218 || TARGET_DOUBLE_WITH_ADD)))
12219 && ix86_match_ccmode (insn, CCGOCmode)
12220 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
f42684d5
UB
12221{
12222 switch (get_attr_type (insn))
12223 {
12224 case TYPE_ALU:
12225 gcc_assert (operands[2] == const1_rtx);
a23132e1 12226 return "add{l}\t%0, %0";
f42684d5
UB
12227
12228 default:
12229 if (REG_P (operands[2]))
12230 return "sal{l}\t{%b2, %0|%0, %b2}";
12231 else if (operands[2] == const1_rtx
3debdc1e 12232 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
f42684d5
UB
12233 return "sal{l}\t%0";
12234 else
12235 return "sal{l}\t{%2, %0|%0, %2}";
12236 }
12237}
12238 [(set (attr "type")
12239 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12240 (const_int 0))
12241 (match_operand 0 "register_operand" ""))
12242 (match_operand 2 "const1_operand" ""))
12243 (const_string "alu")
12244 ]
12245 (const_string "ishift")))
a952487c
JJ
12246 (set (attr "length_immediate")
12247 (if_then_else
12248 (ior (eq_attr "type" "alu")
12249 (and (eq_attr "type" "ishift")
12250 (and (match_operand 2 "const1_operand" "")
12251 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12252 (const_int 0)))))
12253 (const_string "0")
12254 (const_string "*")))
f42684d5
UB
12255 (set_attr "mode" "SI")])
12256
371bc54b 12257(define_insn "*ashlsi3_cmp_zext"
42fabf21 12258 [(set (reg FLAGS_REG)
371bc54b
JH
12259 (compare
12260 (ashift:SI (match_operand:SI 1 "register_operand" "0")
ef719a44 12261 (match_operand:QI 2 "const_1_to_31_operand" "I"))
371bc54b
JH
12262 (const_int 0)))
12263 (set (match_operand:DI 0 "register_operand" "=r")
12264 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
d5d5d289 12265 "TARGET_64BIT
3debdc1e 12266 && (optimize_function_for_size_p (cfun)
995cc369
L
12267 || !TARGET_PARTIAL_FLAG_REG_STALL
12268 || (operands[2] == const1_rtx
12269 && (TARGET_SHIFT1
d5d5d289
L
12270 || TARGET_DOUBLE_WITH_ADD)))
12271 && ix86_match_ccmode (insn, CCGOCmode)
12272 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
371bc54b
JH
12273{
12274 switch (get_attr_type (insn))
12275 {
12276 case TYPE_ALU:
7637e42c 12277 gcc_assert (operands[2] == const1_rtx);
a23132e1 12278 return "add{l}\t%k0, %k0";
371bc54b
JH
12279
12280 default:
12281 if (REG_P (operands[2]))
0f40f9f7 12282 return "sal{l}\t{%b2, %k0|%k0, %b2}";
b4e0dd8e 12283 else if (operands[2] == const1_rtx
3debdc1e 12284 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
0f40f9f7 12285 return "sal{l}\t%k0";
371bc54b 12286 else
0f40f9f7 12287 return "sal{l}\t{%2, %k0|%k0, %2}";
371bc54b 12288 }
0f40f9f7 12289}
371bc54b
JH
12290 [(set (attr "type")
12291 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12292 (const_int 0))
12293 (match_operand 2 "const1_operand" ""))
12294 (const_string "alu")
12295 ]
12296 (const_string "ishift")))
a952487c
JJ
12297 (set (attr "length_immediate")
12298 (if_then_else
12299 (ior (eq_attr "type" "alu")
12300 (and (eq_attr "type" "ishift")
12301 (and (match_operand 2 "const1_operand" "")
12302 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12303 (const_int 0)))))
12304 (const_string "0")
12305 (const_string "*")))
371bc54b
JH
12306 (set_attr "mode" "SI")])
12307
d525dfdf
JH
12308(define_expand "ashlhi3"
12309 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12310 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
7ae14d31 12311 (match_operand:QI 2 "nonmemory_operand" "")))]
d9f32422 12312 "TARGET_HIMODE_MATH"
d525dfdf
JH
12313 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
12314
58787064
JH
12315(define_insn "*ashlhi3_1_lea"
12316 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9a9286af 12317 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
58787064 12318 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8bc527af 12319 (clobber (reg:CC FLAGS_REG))]
58787064
JH
12320 "!TARGET_PARTIAL_REG_STALL
12321 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
58787064
JH
12322{
12323 switch (get_attr_type (insn))
12324 {
12325 case TYPE_LEA:
0f40f9f7 12326 return "#";
58787064 12327 case TYPE_ALU:
7637e42c 12328 gcc_assert (operands[2] == const1_rtx);
a23132e1 12329 return "add{w}\t%0, %0";
58787064
JH
12330
12331 default:
12332 if (REG_P (operands[2]))
0f40f9f7 12333 return "sal{w}\t{%b2, %0|%0, %b2}";
b4e0dd8e 12334 else if (operands[2] == const1_rtx
3debdc1e 12335 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
0f40f9f7 12336 return "sal{w}\t%0";
58787064 12337 else
0f40f9f7 12338 return "sal{w}\t{%2, %0|%0, %2}";
58787064 12339 }
0f40f9f7 12340}
58787064
JH
12341 [(set (attr "type")
12342 (cond [(eq_attr "alternative" "1")
12343 (const_string "lea")
12344 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12345 (const_int 0))
12346 (match_operand 0 "register_operand" ""))
12347 (match_operand 2 "const1_operand" ""))
12348 (const_string "alu")
12349 ]
12350 (const_string "ishift")))
a952487c
JJ
12351 (set (attr "length_immediate")
12352 (if_then_else
12353 (ior (eq_attr "type" "alu")
12354 (and (eq_attr "type" "ishift")
12355 (and (match_operand 2 "const1_operand" "")
12356 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12357 (const_int 0)))))
12358 (const_string "0")
12359 (const_string "*")))
58787064
JH
12360 (set_attr "mode" "HI,SI")])
12361
d525dfdf 12362(define_insn "*ashlhi3_1"
e075ae69
RH
12363 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12364 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12365 (match_operand:QI 2 "nonmemory_operand" "cI")))
8bc527af 12366 (clobber (reg:CC FLAGS_REG))]
58787064
JH
12367 "TARGET_PARTIAL_REG_STALL
12368 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
56c0e8fa 12369{
e075ae69
RH
12370 switch (get_attr_type (insn))
12371 {
12372 case TYPE_ALU:
7637e42c 12373 gcc_assert (operands[2] == const1_rtx);
a23132e1 12374 return "add{w}\t%0, %0";
886c62d1 12375
e075ae69
RH
12376 default:
12377 if (REG_P (operands[2]))
0f40f9f7 12378 return "sal{w}\t{%b2, %0|%0, %b2}";
b4e0dd8e 12379 else if (operands[2] == const1_rtx
3debdc1e 12380 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
0f40f9f7 12381 return "sal{w}\t%0";
e075ae69 12382 else
0f40f9f7 12383 return "sal{w}\t{%2, %0|%0, %2}";
e075ae69 12384 }
0f40f9f7 12385}
e075ae69
RH
12386 [(set (attr "type")
12387 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12388 (const_int 0))
12389 (match_operand 0 "register_operand" ""))
12390 (match_operand 2 "const1_operand" ""))
12391 (const_string "alu")
12392 ]
6ef67412 12393 (const_string "ishift")))
a952487c
JJ
12394 (set (attr "length_immediate")
12395 (if_then_else
12396 (ior (eq_attr "type" "alu")
12397 (and (eq_attr "type" "ishift")
12398 (and (match_operand 2 "const1_operand" "")
12399 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12400 (const_int 0)))))
12401 (const_string "0")
12402 (const_string "*")))
6ef67412 12403 (set_attr "mode" "HI")])
bb62e19a 12404
28cefcd2
BS
12405;; This pattern can't accept a variable shift count, since shifts by
12406;; zero don't affect the flags. We assume that shifts by constant
12407;; zero are optimized away.
2c873473 12408(define_insn "*ashlhi3_cmp"
42fabf21 12409 [(set (reg FLAGS_REG)
16189740 12410 (compare
e075ae69 12411 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
ef719a44 12412 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69
RH
12413 (const_int 0)))
12414 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12415 (ashift:HI (match_dup 1) (match_dup 2)))]
3debdc1e 12416 "(optimize_function_for_size_p (cfun)
d5d5d289
L
12417 || !TARGET_PARTIAL_FLAG_REG_STALL
12418 || (operands[2] == const1_rtx
12419 && (TARGET_SHIFT1
12420 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12421 && ix86_match_ccmode (insn, CCGOCmode)
12422 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
886c62d1 12423{
e075ae69
RH
12424 switch (get_attr_type (insn))
12425 {
12426 case TYPE_ALU:
7637e42c 12427 gcc_assert (operands[2] == const1_rtx);
a23132e1 12428 return "add{w}\t%0, %0";
886c62d1 12429
e075ae69
RH
12430 default:
12431 if (REG_P (operands[2]))
0f40f9f7 12432 return "sal{w}\t{%b2, %0|%0, %b2}";
b4e0dd8e 12433 else if (operands[2] == const1_rtx
3debdc1e 12434 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
0f40f9f7 12435 return "sal{w}\t%0";
e075ae69 12436 else
0f40f9f7 12437 return "sal{w}\t{%2, %0|%0, %2}";
e075ae69 12438 }
0f40f9f7 12439}
e075ae69
RH
12440 [(set (attr "type")
12441 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12442 (const_int 0))
12443 (match_operand 0 "register_operand" ""))
12444 (match_operand 2 "const1_operand" ""))
12445 (const_string "alu")
12446 ]
6ef67412 12447 (const_string "ishift")))
a952487c
JJ
12448 (set (attr "length_immediate")
12449 (if_then_else
12450 (ior (eq_attr "type" "alu")
12451 (and (eq_attr "type" "ishift")
12452 (and (match_operand 2 "const1_operand" "")
12453 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12454 (const_int 0)))))
12455 (const_string "0")
12456 (const_string "*")))
6ef67412 12457 (set_attr "mode" "HI")])
e075ae69 12458
f42684d5
UB
12459(define_insn "*ashlhi3_cconly"
12460 [(set (reg FLAGS_REG)
12461 (compare
12462 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12463 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12464 (const_int 0)))
12465 (clobber (match_scratch:HI 0 "=r"))]
3debdc1e 12466 "(optimize_function_for_size_p (cfun)
d5d5d289
L
12467 || !TARGET_PARTIAL_FLAG_REG_STALL
12468 || (operands[2] == const1_rtx
12469 && (TARGET_SHIFT1
12470 || TARGET_DOUBLE_WITH_ADD)))
12471 && ix86_match_ccmode (insn, CCGOCmode)
12472 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
f42684d5
UB
12473{
12474 switch (get_attr_type (insn))
12475 {
12476 case TYPE_ALU:
12477 gcc_assert (operands[2] == const1_rtx);
a23132e1 12478 return "add{w}\t%0, %0";
f42684d5
UB
12479
12480 default:
12481 if (REG_P (operands[2]))
12482 return "sal{w}\t{%b2, %0|%0, %b2}";
12483 else if (operands[2] == const1_rtx
3debdc1e 12484 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
f42684d5
UB
12485 return "sal{w}\t%0";
12486 else
12487 return "sal{w}\t{%2, %0|%0, %2}";
12488 }
12489}
12490 [(set (attr "type")
12491 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12492 (const_int 0))
12493 (match_operand 0 "register_operand" ""))
12494 (match_operand 2 "const1_operand" ""))
12495 (const_string "alu")
12496 ]
12497 (const_string "ishift")))
a952487c
JJ
12498 (set (attr "length_immediate")
12499 (if_then_else
12500 (ior (eq_attr "type" "alu")
12501 (and (eq_attr "type" "ishift")
12502 (and (match_operand 2 "const1_operand" "")
12503 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12504 (const_int 0)))))
12505 (const_string "0")
12506 (const_string "*")))
f42684d5
UB
12507 (set_attr "mode" "HI")])
12508
d525dfdf
JH
12509(define_expand "ashlqi3"
12510 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12511 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
7ae14d31 12512 (match_operand:QI 2 "nonmemory_operand" "")))]
d9f32422 12513 "TARGET_QIMODE_MATH"
d525dfdf
JH
12514 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
12515
e075ae69 12516;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
12517
12518(define_insn "*ashlqi3_1_lea"
12519 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9a9286af 12520 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
91f9a498 12521 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8bc527af 12522 (clobber (reg:CC FLAGS_REG))]
58787064
JH
12523 "!TARGET_PARTIAL_REG_STALL
12524 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
58787064
JH
12525{
12526 switch (get_attr_type (insn))
12527 {
12528 case TYPE_LEA:
0f40f9f7 12529 return "#";
58787064 12530 case TYPE_ALU:
7637e42c 12531 gcc_assert (operands[2] == const1_rtx);
1a06f5fe 12532 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
a23132e1 12533 return "add{l}\t%k0, %k0";
58787064 12534 else
a23132e1 12535 return "add{b}\t%0, %0";
58787064
JH
12536
12537 default:
12538 if (REG_P (operands[2]))
12539 {
12540 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 12541 return "sal{l}\t{%b2, %k0|%k0, %b2}";
58787064 12542 else
0f40f9f7 12543 return "sal{b}\t{%b2, %0|%0, %b2}";
58787064 12544 }
b4e0dd8e 12545 else if (operands[2] == const1_rtx
3debdc1e 12546 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
58787064
JH
12547 {
12548 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 12549 return "sal{l}\t%0";
58787064 12550 else
0f40f9f7 12551 return "sal{b}\t%0";
58787064
JH
12552 }
12553 else
12554 {
12555 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 12556 return "sal{l}\t{%2, %k0|%k0, %2}";
58787064 12557 else
0f40f9f7 12558 return "sal{b}\t{%2, %0|%0, %2}";
58787064
JH
12559 }
12560 }
0f40f9f7 12561}
58787064
JH
12562 [(set (attr "type")
12563 (cond [(eq_attr "alternative" "2")
12564 (const_string "lea")
12565 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12566 (const_int 0))
12567 (match_operand 0 "register_operand" ""))
12568 (match_operand 2 "const1_operand" ""))
12569 (const_string "alu")
12570 ]
12571 (const_string "ishift")))
a952487c
JJ
12572 (set (attr "length_immediate")
12573 (if_then_else
12574 (ior (eq_attr "type" "alu")
12575 (and (eq_attr "type" "ishift")
12576 (and (match_operand 2 "const1_operand" "")
12577 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12578 (const_int 0)))))
12579 (const_string "0")
12580 (const_string "*")))
58787064
JH
12581 (set_attr "mode" "QI,SI,SI")])
12582
d525dfdf
JH
12583(define_insn "*ashlqi3_1"
12584 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
e075ae69
RH
12585 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12586 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
8bc527af 12587 (clobber (reg:CC FLAGS_REG))]
58787064
JH
12588 "TARGET_PARTIAL_REG_STALL
12589 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
886c62d1 12590{
e075ae69
RH
12591 switch (get_attr_type (insn))
12592 {
12593 case TYPE_ALU:
7637e42c 12594 gcc_assert (operands[2] == const1_rtx);
1a06f5fe 12595 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
a23132e1 12596 return "add{l}\t%k0, %k0";
e075ae69 12597 else
a23132e1 12598 return "add{b}\t%0, %0";
886c62d1 12599
e075ae69
RH
12600 default:
12601 if (REG_P (operands[2]))
12602 {
1a06f5fe 12603 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 12604 return "sal{l}\t{%b2, %k0|%k0, %b2}";
e075ae69 12605 else
0f40f9f7 12606 return "sal{b}\t{%b2, %0|%0, %b2}";
e075ae69 12607 }
b4e0dd8e 12608 else if (operands[2] == const1_rtx
3debdc1e 12609 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8bad7136 12610 {
1a06f5fe 12611 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 12612 return "sal{l}\t%0";
8bad7136 12613 else
0f40f9f7 12614 return "sal{b}\t%0";
8bad7136 12615 }
e075ae69
RH
12616 else
12617 {
1a06f5fe 12618 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 12619 return "sal{l}\t{%2, %k0|%k0, %2}";
e075ae69 12620 else
0f40f9f7 12621 return "sal{b}\t{%2, %0|%0, %2}";
e075ae69
RH
12622 }
12623 }
0f40f9f7 12624}
e075ae69
RH
12625 [(set (attr "type")
12626 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12627 (const_int 0))
12628 (match_operand 0 "register_operand" ""))
12629 (match_operand 2 "const1_operand" ""))
12630 (const_string "alu")
12631 ]
6ef67412 12632 (const_string "ishift")))
a952487c
JJ
12633 (set (attr "length_immediate")
12634 (if_then_else
12635 (ior (eq_attr "type" "alu")
12636 (and (eq_attr "type" "ishift")
12637 (and (match_operand 2 "const1_operand" "")
12638 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12639 (const_int 0)))))
12640 (const_string "0")
12641 (const_string "*")))
6ef67412 12642 (set_attr "mode" "QI,SI")])
e075ae69 12643
28cefcd2
BS
12644;; This pattern can't accept a variable shift count, since shifts by
12645;; zero don't affect the flags. We assume that shifts by constant
12646;; zero are optimized away.
2c873473 12647(define_insn "*ashlqi3_cmp"
42fabf21 12648 [(set (reg FLAGS_REG)
16189740 12649 (compare
e075ae69 12650 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
ef719a44 12651 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69
RH
12652 (const_int 0)))
12653 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12654 (ashift:QI (match_dup 1) (match_dup 2)))]
3debdc1e 12655 "(optimize_function_for_size_p (cfun)
d5d5d289
L
12656 || !TARGET_PARTIAL_FLAG_REG_STALL
12657 || (operands[2] == const1_rtx
12658 && (TARGET_SHIFT1
12659 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12660 && ix86_match_ccmode (insn, CCGOCmode)
12661 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
886c62d1 12662{
e075ae69
RH
12663 switch (get_attr_type (insn))
12664 {
12665 case TYPE_ALU:
7637e42c 12666 gcc_assert (operands[2] == const1_rtx);
a23132e1 12667 return "add{b}\t%0, %0";
e075ae69
RH
12668
12669 default:
12670 if (REG_P (operands[2]))
0f40f9f7 12671 return "sal{b}\t{%b2, %0|%0, %b2}";
b4e0dd8e 12672 else if (operands[2] == const1_rtx
3debdc1e 12673 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
0f40f9f7 12674 return "sal{b}\t%0";
e075ae69 12675 else
0f40f9f7 12676 return "sal{b}\t{%2, %0|%0, %2}";
e075ae69 12677 }
0f40f9f7 12678}
e075ae69
RH
12679 [(set (attr "type")
12680 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12681 (const_int 0))
12682 (match_operand 0 "register_operand" ""))
12683 (match_operand 2 "const1_operand" ""))
12684 (const_string "alu")
12685 ]
6ef67412 12686 (const_string "ishift")))
a952487c
JJ
12687 (set (attr "length_immediate")
12688 (if_then_else
12689 (ior (eq_attr "type" "alu")
12690 (and (eq_attr "type" "ishift")
12691 (and (match_operand 2 "const1_operand" "")
12692 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12693 (const_int 0)))))
12694 (const_string "0")
12695 (const_string "*")))
6ef67412 12696 (set_attr "mode" "QI")])
886c62d1 12697
f42684d5
UB
12698(define_insn "*ashlqi3_cconly"
12699 [(set (reg FLAGS_REG)
12700 (compare
12701 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12702 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12703 (const_int 0)))
12704 (clobber (match_scratch:QI 0 "=q"))]
3debdc1e 12705 "(optimize_function_for_size_p (cfun)
d5d5d289
L
12706 || !TARGET_PARTIAL_FLAG_REG_STALL
12707 || (operands[2] == const1_rtx
12708 && (TARGET_SHIFT1
12709 || TARGET_DOUBLE_WITH_ADD)))
12710 && ix86_match_ccmode (insn, CCGOCmode)
12711 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
f42684d5
UB
12712{
12713 switch (get_attr_type (insn))
12714 {
12715 case TYPE_ALU:
12716 gcc_assert (operands[2] == const1_rtx);
a23132e1 12717 return "add{b}\t%0, %0";
f42684d5
UB
12718
12719 default:
12720 if (REG_P (operands[2]))
12721 return "sal{b}\t{%b2, %0|%0, %b2}";
12722 else if (operands[2] == const1_rtx
3debdc1e 12723 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
f42684d5
UB
12724 return "sal{b}\t%0";
12725 else
12726 return "sal{b}\t{%2, %0|%0, %2}";
12727 }
12728}
12729 [(set (attr "type")
12730 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12731 (const_int 0))
12732 (match_operand 0 "register_operand" ""))
12733 (match_operand 2 "const1_operand" ""))
12734 (const_string "alu")
12735 ]
12736 (const_string "ishift")))
a952487c
JJ
12737 (set (attr "length_immediate")
12738 (if_then_else
12739 (ior (eq_attr "type" "alu")
12740 (and (eq_attr "type" "ishift")
12741 (and (match_operand 2 "const1_operand" "")
12742 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12743 (const_int 0)))))
12744 (const_string "0")
12745 (const_string "*")))
f42684d5
UB
12746 (set_attr "mode" "QI")])
12747
886c62d1
JVA
12748;; See comment above `ashldi3' about how this works.
12749
28356f52 12750(define_expand "ashrti3"
934f2a96
UB
12751 [(set (match_operand:TI 0 "register_operand" "")
12752 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12753 (match_operand:QI 2 "nonmemory_operand" "")))]
28356f52 12754 "TARGET_64BIT"
934f2a96 12755 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
28356f52 12756
934f2a96 12757(define_insn "*ashrti3_1"
28356f52
JB
12758 [(set (match_operand:TI 0 "register_operand" "=r")
12759 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
934f2a96 12760 (match_operand:QI 2 "nonmemory_operand" "Oc")))
28356f52
JB
12761 (clobber (reg:CC FLAGS_REG))]
12762 "TARGET_64BIT"
12763 "#"
12764 [(set_attr "type" "multi")])
12765
934f2a96
UB
12766(define_peephole2
12767 [(match_scratch:DI 3 "r")
12768 (parallel [(set (match_operand:TI 0 "register_operand" "")
12769 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12770 (match_operand:QI 2 "nonmemory_operand" "")))
12771 (clobber (reg:CC FLAGS_REG))])
12772 (match_dup 3)]
28356f52 12773 "TARGET_64BIT"
28356f52
JB
12774 [(const_int 0)]
12775 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12776
12777(define_split
12778 [(set (match_operand:TI 0 "register_operand" "")
12779 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
934f2a96 12780 (match_operand:QI 2 "nonmemory_operand" "")))
28356f52 12781 (clobber (reg:CC FLAGS_REG))]
934f2a96
UB
12782 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12783 ? epilogue_completed : reload_completed)"
28356f52
JB
12784 [(const_int 0)]
12785 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12786
12787(define_insn "x86_64_shrd"
934f2a96 12788 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
28356f52 12789 (ior:DI (ashiftrt:DI (match_dup 0)
934f2a96
UB
12790 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12791 (ashift:DI (match_operand:DI 1 "register_operand" "r")
28356f52
JB
12792 (minus:QI (const_int 64) (match_dup 2)))))
12793 (clobber (reg:CC FLAGS_REG))]
12794 "TARGET_64BIT"
934f2a96 12795 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
28356f52
JB
12796 [(set_attr "type" "ishift")
12797 (set_attr "prefix_0f" "1")
12798 (set_attr "mode" "DI")
21efb4d4 12799 (set_attr "athlon_decode" "vector")
4f3f76e6 12800 (set_attr "amdfam10_decode" "vector")])
28356f52 12801
e075ae69 12802(define_expand "ashrdi3"
93330ea1
RH
12803 [(set (match_operand:DI 0 "shiftdi_operand" "")
12804 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12805 (match_operand:QI 2 "nonmemory_operand" "")))]
56c0e8fa 12806 ""
93330ea1 12807 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
2ae0f82c 12808
72ea2555
UB
12809(define_expand "x86_64_shift_adj_3"
12810 [(use (match_operand:DI 0 "register_operand" ""))
12811 (use (match_operand:DI 1 "register_operand" ""))
12812 (use (match_operand:QI 2 "register_operand" ""))]
12813 ""
12814{
12815 rtx label = gen_label_rtx ();
12816 rtx tmp;
12817
12818 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12819
12820 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12821 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12822 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12823 gen_rtx_LABEL_REF (VOIDmode, label),
12824 pc_rtx);
12825 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12826 JUMP_LABEL (tmp) = label;
12827
12828 emit_move_insn (operands[0], operands[1]);
12829 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12830
12831 emit_label (label);
12832 LABEL_NUSES (label) = 1;
12833
12834 DONE;
12835})
12836
12837(define_insn "ashrdi3_63_rex64"
371bc54b
JH
12838 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12839 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12840 (match_operand:DI 2 "const_int_operand" "i,i")))
8bc527af 12841 (clobber (reg:CC FLAGS_REG))]
93330ea1 12842 "TARGET_64BIT && INTVAL (operands[2]) == 63
3debdc1e 12843 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
371bc54b
JH
12844 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12845 "@
12846 {cqto|cqo}
0f40f9f7 12847 sar{q}\t{%2, %0|%0, %2}"
371bc54b
JH
12848 [(set_attr "type" "imovx,ishift")
12849 (set_attr "prefix_0f" "0,*")
12850 (set_attr "length_immediate" "0,*")
12851 (set_attr "modrm" "0,1")
12852 (set_attr "mode" "DI")])
12853
12854(define_insn "*ashrdi3_1_one_bit_rex64"
12855 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12856 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 12857 (match_operand:QI 2 "const1_operand" "")))
8bc527af 12858 (clobber (reg:CC FLAGS_REG))]
d5d5d289 12859 "TARGET_64BIT
3debdc1e 12860 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 12861 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
0f40f9f7 12862 "sar{q}\t%0"
371bc54b 12863 [(set_attr "type" "ishift")
a952487c
JJ
12864 (set_attr "length_immediate" "0")
12865 (set_attr "mode" "DI")])
371bc54b
JH
12866
12867(define_insn "*ashrdi3_1_rex64"
12868 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12869 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7c17f553 12870 (match_operand:QI 2 "nonmemory_operand" "J,c")))
8bc527af 12871 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
12872 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12873 "@
0f40f9f7
ZW
12874 sar{q}\t{%2, %0|%0, %2}
12875 sar{q}\t{%b2, %0|%0, %b2}"
371bc54b
JH
12876 [(set_attr "type" "ishift")
12877 (set_attr "mode" "DI")])
12878
12879;; This pattern can't accept a variable shift count, since shifts by
12880;; zero don't affect the flags. We assume that shifts by constant
12881;; zero are optimized away.
12882(define_insn "*ashrdi3_one_bit_cmp_rex64"
42fabf21 12883 [(set (reg FLAGS_REG)
371bc54b
JH
12884 (compare
12885 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 12886 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
12887 (const_int 0)))
12888 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12889 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
d5d5d289 12890 "TARGET_64BIT
3debdc1e 12891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 12892 && ix86_match_ccmode (insn, CCGOCmode)
371bc54b 12893 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
0f40f9f7 12894 "sar{q}\t%0"
371bc54b 12895 [(set_attr "type" "ishift")
a952487c
JJ
12896 (set_attr "length_immediate" "0")
12897 (set_attr "mode" "DI")])
371bc54b 12898
f42684d5
UB
12899(define_insn "*ashrdi3_one_bit_cconly_rex64"
12900 [(set (reg FLAGS_REG)
12901 (compare
12902 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12903 (match_operand:QI 2 "const1_operand" ""))
12904 (const_int 0)))
12905 (clobber (match_scratch:DI 0 "=r"))]
d5d5d289 12906 "TARGET_64BIT
3debdc1e 12907 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 12908 && ix86_match_ccmode (insn, CCGOCmode)
f42684d5
UB
12909 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12910 "sar{q}\t%0"
12911 [(set_attr "type" "ishift")
a952487c
JJ
12912 (set_attr "length_immediate" "0")
12913 (set_attr "mode" "DI")])
f42684d5 12914
371bc54b
JH
12915;; This pattern can't accept a variable shift count, since shifts by
12916;; zero don't affect the flags. We assume that shifts by constant
12917;; zero are optimized away.
12918(define_insn "*ashrdi3_cmp_rex64"
42fabf21 12919 [(set (reg FLAGS_REG)
371bc54b
JH
12920 (compare
12921 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
934f2a96 12922 (match_operand:QI 2 "const_1_to_63_operand" "J"))
371bc54b
JH
12923 (const_int 0)))
12924 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12925 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
d5d5d289 12926 "TARGET_64BIT
3debdc1e 12927 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
12928 && ix86_match_ccmode (insn, CCGOCmode)
12929 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
0f40f9f7 12930 "sar{q}\t{%2, %0|%0, %2}"
371bc54b
JH
12931 [(set_attr "type" "ishift")
12932 (set_attr "mode" "DI")])
12933
f42684d5
UB
12934(define_insn "*ashrdi3_cconly_rex64"
12935 [(set (reg FLAGS_REG)
12936 (compare
12937 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
934f2a96 12938 (match_operand:QI 2 "const_1_to_63_operand" "J"))
f42684d5
UB
12939 (const_int 0)))
12940 (clobber (match_scratch:DI 0 "=r"))]
d5d5d289 12941 "TARGET_64BIT
3debdc1e 12942 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
12943 && ix86_match_ccmode (insn, CCGOCmode)
12944 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
f42684d5
UB
12945 "sar{q}\t{%2, %0|%0, %2}"
12946 [(set_attr "type" "ishift")
12947 (set_attr "mode" "DI")])
12948
93330ea1 12949(define_insn "*ashrdi3_1"
e075ae69
RH
12950 [(set (match_operand:DI 0 "register_operand" "=r")
12951 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12952 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8bc527af 12953 (clobber (reg:CC FLAGS_REG))]
371bc54b 12954 "!TARGET_64BIT"
e075ae69
RH
12955 "#"
12956 [(set_attr "type" "multi")])
886c62d1 12957
93330ea1
RH
12958;; By default we don't ask for a scratch register, because when DImode
12959;; values are manipulated, registers are already at a premium. But if
12960;; we have one handy, we won't turn it away.
12961(define_peephole2
12962 [(match_scratch:SI 3 "r")
12963 (parallel [(set (match_operand:DI 0 "register_operand" "")
12964 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12965 (match_operand:QI 2 "nonmemory_operand" "")))
12966 (clobber (reg:CC FLAGS_REG))])
12967 (match_dup 3)]
12968 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69 12969 [(const_int 0)]
28356f52 12970 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
886c62d1 12971
e075ae69
RH
12972(define_split
12973 [(set (match_operand:DI 0 "register_operand" "")
12974 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12975 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 12976 (clobber (reg:CC FLAGS_REG))]
99523994 12977 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
6fb5fa3c 12978 ? epilogue_completed : reload_completed)"
e075ae69 12979 [(const_int 0)]
28356f52 12980 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
886c62d1 12981
934f2a96
UB
12982(define_insn "x86_shrd"
12983 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
e075ae69 12984 (ior:SI (ashiftrt:SI (match_dup 0)
934f2a96
UB
12985 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12986 (ashift:SI (match_operand:SI 1 "register_operand" "r")
e075ae69 12987 (minus:QI (const_int 32) (match_dup 2)))))
8bc527af 12988 (clobber (reg:CC FLAGS_REG))]
886c62d1 12989 ""
934f2a96 12990 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
e075ae69 12991 [(set_attr "type" "ishift")
6ef67412 12992 (set_attr "prefix_0f" "1")
e075ae69 12993 (set_attr "pent_pair" "np")
6ef67412 12994 (set_attr "mode" "SI")])
e075ae69
RH
12995
12996(define_expand "x86_shift_adj_3"
12997 [(use (match_operand:SI 0 "register_operand" ""))
12998 (use (match_operand:SI 1 "register_operand" ""))
12999 (use (match_operand:QI 2 "register_operand" ""))]
13000 ""
886c62d1 13001{
e075ae69
RH
13002 rtx label = gen_label_rtx ();
13003 rtx tmp;
13004
16189740 13005 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
e075ae69 13006
16189740 13007 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
13008 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13009 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13010 gen_rtx_LABEL_REF (VOIDmode, label),
13011 pc_rtx);
13012 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
13013 JUMP_LABEL (tmp) = label;
13014
13015 emit_move_insn (operands[0], operands[1]);
13016 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
13017
13018 emit_label (label);
13019 LABEL_NUSES (label) = 1;
13020
13021 DONE;
0f40f9f7 13022})
886c62d1 13023
3debdc1e
JH
13024(define_expand "ashrsi3_31"
13025 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13026 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13027 (match_operand:SI 2 "const_int_operand" "i,i")))
13028 (clobber (reg:CC FLAGS_REG))])]
13029 "")
13030
13031(define_insn "*ashrsi3_31"
e075ae69
RH
13032 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13033 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13034 (match_operand:SI 2 "const_int_operand" "i,i")))
8bc527af 13035 (clobber (reg:CC FLAGS_REG))]
3debdc1e
JH
13036 "INTVAL (operands[2]) == 31
13037 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
d525dfdf 13038 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
e075ae69
RH
13039 "@
13040 {cltd|cdq}
0f40f9f7 13041 sar{l}\t{%2, %0|%0, %2}"
6ef67412
JH
13042 [(set_attr "type" "imovx,ishift")
13043 (set_attr "prefix_0f" "0,*")
13044 (set_attr "length_immediate" "0,*")
13045 (set_attr "modrm" "0,1")
13046 (set_attr "mode" "SI")])
e075ae69 13047
371bc54b
JH
13048(define_insn "*ashrsi3_31_zext"
13049 [(set (match_operand:DI 0 "register_operand" "=*d,r")
13050 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
13051 (match_operand:SI 2 "const_int_operand" "i,i"))))
8bc527af 13052 (clobber (reg:CC FLAGS_REG))]
3debdc1e 13053 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
1b0c37d7
ZW
13054 && INTVAL (operands[2]) == 31
13055 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
371bc54b
JH
13056 "@
13057 {cltd|cdq}
0f40f9f7 13058 sar{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
13059 [(set_attr "type" "imovx,ishift")
13060 (set_attr "prefix_0f" "0,*")
13061 (set_attr "length_immediate" "0,*")
13062 (set_attr "modrm" "0,1")
13063 (set_attr "mode" "SI")])
13064
d525dfdf
JH
13065(define_expand "ashrsi3"
13066 [(set (match_operand:SI 0 "nonimmediate_operand" "")
155d8a47 13067 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
7ae14d31 13068 (match_operand:QI 2 "nonmemory_operand" "")))]
d525dfdf
JH
13069 ""
13070 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
13071
8bad7136
JL
13072(define_insn "*ashrsi3_1_one_bit"
13073 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13074 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 13075 (match_operand:QI 2 "const1_operand" "")))
8bc527af 13076 (clobber (reg:CC FLAGS_REG))]
3debdc1e 13077 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13078 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 13079 "sar{l}\t%0"
8bad7136 13080 [(set_attr "type" "ishift")
a952487c
JJ
13081 (set_attr "length_immediate" "0")
13082 (set_attr "mode" "SI")])
8bad7136 13083
371bc54b
JH
13084(define_insn "*ashrsi3_1_one_bit_zext"
13085 [(set (match_operand:DI 0 "register_operand" "=r")
13086 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
630eef90 13087 (match_operand:QI 2 "const1_operand" ""))))
8bc527af 13088 (clobber (reg:CC FLAGS_REG))]
d5d5d289 13089 "TARGET_64BIT
3debdc1e 13090 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13091 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 13092 "sar{l}\t%k0"
371bc54b 13093 [(set_attr "type" "ishift")
a952487c
JJ
13094 (set_attr "length_immediate" "0")
13095 (set_attr "mode" "SI")])
371bc54b 13096
d525dfdf 13097(define_insn "*ashrsi3_1"
e075ae69
RH
13098 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13099 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13100 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 13101 (clobber (reg:CC FLAGS_REG))]
d525dfdf 13102 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
e075ae69 13103 "@
0f40f9f7
ZW
13104 sar{l}\t{%2, %0|%0, %2}
13105 sar{l}\t{%b2, %0|%0, %b2}"
6ef67412
JH
13106 [(set_attr "type" "ishift")
13107 (set_attr "mode" "SI")])
886c62d1 13108
371bc54b
JH
13109(define_insn "*ashrsi3_1_zext"
13110 [(set (match_operand:DI 0 "register_operand" "=r,r")
13111 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
13112 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 13113 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
13114 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13115 "@
0f40f9f7
ZW
13116 sar{l}\t{%2, %k0|%k0, %2}
13117 sar{l}\t{%b2, %k0|%k0, %b2}"
371bc54b
JH
13118 [(set_attr "type" "ishift")
13119 (set_attr "mode" "SI")])
13120
8bad7136
JL
13121;; This pattern can't accept a variable shift count, since shifts by
13122;; zero don't affect the flags. We assume that shifts by constant
13123;; zero are optimized away.
2c873473 13124(define_insn "*ashrsi3_one_bit_cmp"
42fabf21 13125 [(set (reg FLAGS_REG)
8bad7136
JL
13126 (compare
13127 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 13128 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
13129 (const_int 0)))
13130 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13131 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
3debdc1e 13132 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13133 && ix86_match_ccmode (insn, CCGOCmode)
8bad7136 13134 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 13135 "sar{l}\t%0"
8bad7136 13136 [(set_attr "type" "ishift")
a952487c
JJ
13137 (set_attr "length_immediate" "0")
13138 (set_attr "mode" "SI")])
8bad7136 13139
f42684d5
UB
13140(define_insn "*ashrsi3_one_bit_cconly"
13141 [(set (reg FLAGS_REG)
13142 (compare
13143 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13144 (match_operand:QI 2 "const1_operand" ""))
13145 (const_int 0)))
13146 (clobber (match_scratch:SI 0 "=r"))]
3debdc1e 13147 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13148 && ix86_match_ccmode (insn, CCGOCmode)
f42684d5
UB
13149 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13150 "sar{l}\t%0"
13151 [(set_attr "type" "ishift")
a952487c
JJ
13152 (set_attr "length_immediate" "0")
13153 (set_attr "mode" "SI")])
f42684d5 13154
371bc54b 13155(define_insn "*ashrsi3_one_bit_cmp_zext"
42fabf21 13156 [(set (reg FLAGS_REG)
371bc54b
JH
13157 (compare
13158 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
630eef90 13159 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
13160 (const_int 0)))
13161 (set (match_operand:DI 0 "register_operand" "=r")
13162 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
d5d5d289 13163 "TARGET_64BIT
3debdc1e 13164 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13165 && ix86_match_ccmode (insn, CCmode)
371bc54b 13166 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 13167 "sar{l}\t%k0"
371bc54b 13168 [(set_attr "type" "ishift")
a952487c
JJ
13169 (set_attr "length_immediate" "0")
13170 (set_attr "mode" "SI")])
371bc54b 13171
28cefcd2
BS
13172;; This pattern can't accept a variable shift count, since shifts by
13173;; zero don't affect the flags. We assume that shifts by constant
13174;; zero are optimized away.
2c873473 13175(define_insn "*ashrsi3_cmp"
42fabf21 13176 [(set (reg FLAGS_REG)
16189740 13177 (compare
28cefcd2 13178 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
ef719a44 13179 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 13180 (const_int 0)))
28cefcd2 13181 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 13182 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
3debdc1e 13183 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13184 && ix86_match_ccmode (insn, CCGOCmode)
13185 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 13186 "sar{l}\t{%2, %0|%0, %2}"
6ef67412
JH
13187 [(set_attr "type" "ishift")
13188 (set_attr "mode" "SI")])
886c62d1 13189
f42684d5
UB
13190(define_insn "*ashrsi3_cconly"
13191 [(set (reg FLAGS_REG)
13192 (compare
13193 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13194 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13195 (const_int 0)))
13196 (clobber (match_scratch:SI 0 "=r"))]
3debdc1e 13197 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13198 && ix86_match_ccmode (insn, CCGOCmode)
13199 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
f42684d5
UB
13200 "sar{l}\t{%2, %0|%0, %2}"
13201 [(set_attr "type" "ishift")
13202 (set_attr "mode" "SI")])
13203
371bc54b 13204(define_insn "*ashrsi3_cmp_zext"
42fabf21 13205 [(set (reg FLAGS_REG)
371bc54b
JH
13206 (compare
13207 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
ef719a44 13208 (match_operand:QI 2 "const_1_to_31_operand" "I"))
371bc54b
JH
13209 (const_int 0)))
13210 (set (match_operand:DI 0 "register_operand" "=r")
13211 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
d5d5d289 13212 "TARGET_64BIT
3debdc1e 13213 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13214 && ix86_match_ccmode (insn, CCGOCmode)
13215 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 13216 "sar{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
13217 [(set_attr "type" "ishift")
13218 (set_attr "mode" "SI")])
13219
d525dfdf
JH
13220(define_expand "ashrhi3"
13221 [(set (match_operand:HI 0 "nonimmediate_operand" "")
155d8a47 13222 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
7ae14d31 13223 (match_operand:QI 2 "nonmemory_operand" "")))]
d9f32422 13224 "TARGET_HIMODE_MATH"
d525dfdf
JH
13225 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
13226
8bad7136
JL
13227(define_insn "*ashrhi3_1_one_bit"
13228 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13229 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 13230 (match_operand:QI 2 "const1_operand" "")))
8bc527af 13231 (clobber (reg:CC FLAGS_REG))]
3debdc1e 13232 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13233 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
0f40f9f7 13234 "sar{w}\t%0"
8bad7136 13235 [(set_attr "type" "ishift")
a952487c
JJ
13236 (set_attr "length_immediate" "0")
13237 (set_attr "mode" "HI")])
8bad7136 13238
d525dfdf 13239(define_insn "*ashrhi3_1"
e075ae69
RH
13240 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13241 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13242 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 13243 (clobber (reg:CC FLAGS_REG))]
d525dfdf 13244 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
e075ae69 13245 "@
0f40f9f7
ZW
13246 sar{w}\t{%2, %0|%0, %2}
13247 sar{w}\t{%b2, %0|%0, %b2}"
6ef67412
JH
13248 [(set_attr "type" "ishift")
13249 (set_attr "mode" "HI")])
886c62d1 13250
8bad7136
JL
13251;; This pattern can't accept a variable shift count, since shifts by
13252;; zero don't affect the flags. We assume that shifts by constant
13253;; zero are optimized away.
2c873473 13254(define_insn "*ashrhi3_one_bit_cmp"
42fabf21 13255 [(set (reg FLAGS_REG)
8bad7136
JL
13256 (compare
13257 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 13258 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
13259 (const_int 0)))
13260 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13261 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
3debdc1e 13262 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13263 && ix86_match_ccmode (insn, CCGOCmode)
8bad7136 13264 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
0f40f9f7 13265 "sar{w}\t%0"
8bad7136 13266 [(set_attr "type" "ishift")
a952487c
JJ
13267 (set_attr "length_immediate" "0")
13268 (set_attr "mode" "HI")])
8bad7136 13269
f42684d5
UB
13270(define_insn "*ashrhi3_one_bit_cconly"
13271 [(set (reg FLAGS_REG)
13272 (compare
13273 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13274 (match_operand:QI 2 "const1_operand" ""))
13275 (const_int 0)))
13276 (clobber (match_scratch:HI 0 "=r"))]
3debdc1e 13277 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13278 && ix86_match_ccmode (insn, CCGOCmode)
f42684d5
UB
13279 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13280 "sar{w}\t%0"
13281 [(set_attr "type" "ishift")
a952487c
JJ
13282 (set_attr "length_immediate" "0")
13283 (set_attr "mode" "HI")])
f42684d5 13284
28cefcd2
BS
13285;; This pattern can't accept a variable shift count, since shifts by
13286;; zero don't affect the flags. We assume that shifts by constant
13287;; zero are optimized away.
2c873473 13288(define_insn "*ashrhi3_cmp"
42fabf21 13289 [(set (reg FLAGS_REG)
16189740 13290 (compare
28cefcd2 13291 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
ef719a44 13292 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 13293 (const_int 0)))
28cefcd2 13294 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 13295 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
3debdc1e 13296 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13297 && ix86_match_ccmode (insn, CCGOCmode)
13298 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
0f40f9f7 13299 "sar{w}\t{%2, %0|%0, %2}"
6ef67412
JH
13300 [(set_attr "type" "ishift")
13301 (set_attr "mode" "HI")])
886c62d1 13302
f42684d5
UB
13303(define_insn "*ashrhi3_cconly"
13304 [(set (reg FLAGS_REG)
13305 (compare
13306 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13307 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13308 (const_int 0)))
13309 (clobber (match_scratch:HI 0 "=r"))]
3debdc1e 13310 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13311 && ix86_match_ccmode (insn, CCGOCmode)
13312 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
f42684d5
UB
13313 "sar{w}\t{%2, %0|%0, %2}"
13314 [(set_attr "type" "ishift")
13315 (set_attr "mode" "HI")])
13316
d525dfdf
JH
13317(define_expand "ashrqi3"
13318 [(set (match_operand:QI 0 "nonimmediate_operand" "")
155d8a47 13319 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
7ae14d31 13320 (match_operand:QI 2 "nonmemory_operand" "")))]
d9f32422 13321 "TARGET_QIMODE_MATH"
d525dfdf
JH
13322 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
13323
8bad7136
JL
13324(define_insn "*ashrqi3_1_one_bit"
13325 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13326 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 13327 (match_operand:QI 2 "const1_operand" "")))
8bc527af 13328 (clobber (reg:CC FLAGS_REG))]
3debdc1e 13329 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13330 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
0f40f9f7 13331 "sar{b}\t%0"
8bad7136 13332 [(set_attr "type" "ishift")
a952487c
JJ
13333 (set_attr "length_immediate" "0")
13334 (set_attr "mode" "QI")])
8bad7136 13335
2f41793e
JH
13336(define_insn "*ashrqi3_1_one_bit_slp"
13337 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 13338 (ashiftrt:QI (match_dup 0)
630eef90 13339 (match_operand:QI 1 "const1_operand" "")))
8bc527af 13340 (clobber (reg:CC FLAGS_REG))]
3debdc1e
JH
13341 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13343 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
2f41793e 13344 "sar{b}\t%0"
1b245ade 13345 [(set_attr "type" "ishift1")
a952487c
JJ
13346 (set_attr "length_immediate" "0")
13347 (set_attr "mode" "QI")])
2f41793e 13348
d525dfdf 13349(define_insn "*ashrqi3_1"
e075ae69
RH
13350 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13351 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13352 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 13353 (clobber (reg:CC FLAGS_REG))]
d525dfdf 13354 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
e075ae69 13355 "@
0f40f9f7
ZW
13356 sar{b}\t{%2, %0|%0, %2}
13357 sar{b}\t{%b2, %0|%0, %b2}"
6ef67412
JH
13358 [(set_attr "type" "ishift")
13359 (set_attr "mode" "QI")])
886c62d1 13360
2f41793e
JH
13361(define_insn "*ashrqi3_1_slp"
13362 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
13363 (ashiftrt:QI (match_dup 0)
13364 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 13365 (clobber (reg:CC FLAGS_REG))]
3debdc1e 13366 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 13367 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2f41793e 13368 "@
1b245ade
JH
13369 sar{b}\t{%1, %0|%0, %1}
13370 sar{b}\t{%b1, %0|%0, %b1}"
13371 [(set_attr "type" "ishift1")
2f41793e
JH
13372 (set_attr "mode" "QI")])
13373
8bad7136
JL
13374;; This pattern can't accept a variable shift count, since shifts by
13375;; zero don't affect the flags. We assume that shifts by constant
13376;; zero are optimized away.
2c873473 13377(define_insn "*ashrqi3_one_bit_cmp"
42fabf21 13378 [(set (reg FLAGS_REG)
8bad7136
JL
13379 (compare
13380 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 13381 (match_operand:QI 2 "const1_operand" "I"))
8bad7136 13382 (const_int 0)))
5f90a099 13383 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8bad7136 13384 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
3debdc1e 13385 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13386 && ix86_match_ccmode (insn, CCGOCmode)
8bad7136 13387 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
0f40f9f7 13388 "sar{b}\t%0"
8bad7136 13389 [(set_attr "type" "ishift")
a952487c
JJ
13390 (set_attr "length_immediate" "0")
13391 (set_attr "mode" "QI")])
8bad7136 13392
f42684d5
UB
13393(define_insn "*ashrqi3_one_bit_cconly"
13394 [(set (reg FLAGS_REG)
13395 (compare
13396 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
0edb82cb 13397 (match_operand:QI 2 "const1_operand" ""))
f42684d5
UB
13398 (const_int 0)))
13399 (clobber (match_scratch:QI 0 "=q"))]
3debdc1e 13400 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13401 && ix86_match_ccmode (insn, CCGOCmode)
f42684d5
UB
13402 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13403 "sar{b}\t%0"
13404 [(set_attr "type" "ishift")
a952487c
JJ
13405 (set_attr "length_immediate" "0")
13406 (set_attr "mode" "QI")])
f42684d5 13407
28cefcd2
BS
13408;; This pattern can't accept a variable shift count, since shifts by
13409;; zero don't affect the flags. We assume that shifts by constant
13410;; zero are optimized away.
2c873473 13411(define_insn "*ashrqi3_cmp"
42fabf21 13412 [(set (reg FLAGS_REG)
16189740 13413 (compare
28cefcd2 13414 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
ef719a44 13415 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 13416 (const_int 0)))
5f90a099 13417 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 13418 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
3debdc1e 13419 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13420 && ix86_match_ccmode (insn, CCGOCmode)
13421 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
0f40f9f7 13422 "sar{b}\t{%2, %0|%0, %2}"
6ef67412
JH
13423 [(set_attr "type" "ishift")
13424 (set_attr "mode" "QI")])
f42684d5
UB
13425
13426(define_insn "*ashrqi3_cconly"
13427 [(set (reg FLAGS_REG)
13428 (compare
13429 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13430 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13431 (const_int 0)))
13432 (clobber (match_scratch:QI 0 "=q"))]
3debdc1e 13433 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13434 && ix86_match_ccmode (insn, CCGOCmode)
13435 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
f42684d5
UB
13436 "sar{b}\t{%2, %0|%0, %2}"
13437 [(set_attr "type" "ishift")
13438 (set_attr "mode" "QI")])
13439
886c62d1 13440\f
e075ae69
RH
13441;; Logical shift instructions
13442
13443;; See comment above `ashldi3' about how this works.
13444
28356f52 13445(define_expand "lshrti3"
934f2a96
UB
13446 [(set (match_operand:TI 0 "register_operand" "")
13447 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13448 (match_operand:QI 2 "nonmemory_operand" "")))]
28356f52 13449 "TARGET_64BIT"
934f2a96 13450 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
28356f52 13451
934f2a96
UB
13452;; This pattern must be defined before *lshrti3_1 to prevent
13453;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
69c553ef 13454
95879c72
L
13455(define_insn "*avx_lshrti3"
13456 [(set (match_operand:TI 0 "register_operand" "=x")
13457 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
13458 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13459 "TARGET_AVX"
13460{
13461 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13462 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
13463}
13464 [(set_attr "type" "sseishft")
13465 (set_attr "prefix" "vex")
725fd454 13466 (set_attr "length_immediate" "1")
95879c72
L
13467 (set_attr "mode" "TI")])
13468
69c553ef
UB
13469(define_insn "sse2_lshrti3"
13470 [(set (match_operand:TI 0 "register_operand" "=x")
13471 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13472 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13473 "TARGET_SSE2"
13474{
13475 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13476 return "psrldq\t{%2, %0|%0, %2}";
13477}
13478 [(set_attr "type" "sseishft")
13479 (set_attr "prefix_data16" "1")
725fd454 13480 (set_attr "length_immediate" "1")
69c553ef
UB
13481 (set_attr "mode" "TI")])
13482
934f2a96 13483(define_insn "*lshrti3_1"
28356f52
JB
13484 [(set (match_operand:TI 0 "register_operand" "=r")
13485 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
934f2a96 13486 (match_operand:QI 2 "nonmemory_operand" "Oc")))
28356f52
JB
13487 (clobber (reg:CC FLAGS_REG))]
13488 "TARGET_64BIT"
13489 "#"
13490 [(set_attr "type" "multi")])
13491
934f2a96
UB
13492(define_peephole2
13493 [(match_scratch:DI 3 "r")
13494 (parallel [(set (match_operand:TI 0 "register_operand" "")
13495 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13496 (match_operand:QI 2 "nonmemory_operand" "")))
13497 (clobber (reg:CC FLAGS_REG))])
13498 (match_dup 3)]
13499 "TARGET_64BIT"
28356f52
JB
13500 [(const_int 0)]
13501 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
13502
6300f037 13503(define_split
28356f52
JB
13504 [(set (match_operand:TI 0 "register_operand" "")
13505 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
934f2a96 13506 (match_operand:QI 2 "nonmemory_operand" "")))
28356f52 13507 (clobber (reg:CC FLAGS_REG))]
7059ea88
UB
13508 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13509 ? epilogue_completed : reload_completed)"
28356f52
JB
13510 [(const_int 0)]
13511 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
13512
e075ae69 13513(define_expand "lshrdi3"
93330ea1
RH
13514 [(set (match_operand:DI 0 "shiftdi_operand" "")
13515 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
13516 (match_operand:QI 2 "nonmemory_operand" "")))]
886c62d1 13517 ""
93330ea1 13518 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
886c62d1 13519
371bc54b
JH
13520(define_insn "*lshrdi3_1_one_bit_rex64"
13521 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13522 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 13523 (match_operand:QI 2 "const1_operand" "")))
8bc527af 13524 (clobber (reg:CC FLAGS_REG))]
d5d5d289 13525 "TARGET_64BIT
3debdc1e 13526 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13527 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13528 "shr{q}\t%0"
371bc54b 13529 [(set_attr "type" "ishift")
a952487c
JJ
13530 (set_attr "length_immediate" "0")
13531 (set_attr "mode" "DI")])
371bc54b
JH
13532
13533(define_insn "*lshrdi3_1_rex64"
13534 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13535 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13536 (match_operand:QI 2 "nonmemory_operand" "J,c")))
8bc527af 13537 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
13538 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13539 "@
0f40f9f7
ZW
13540 shr{q}\t{%2, %0|%0, %2}
13541 shr{q}\t{%b2, %0|%0, %b2}"
371bc54b
JH
13542 [(set_attr "type" "ishift")
13543 (set_attr "mode" "DI")])
13544
13545;; This pattern can't accept a variable shift count, since shifts by
13546;; zero don't affect the flags. We assume that shifts by constant
13547;; zero are optimized away.
13548(define_insn "*lshrdi3_cmp_one_bit_rex64"
42fabf21 13549 [(set (reg FLAGS_REG)
371bc54b
JH
13550 (compare
13551 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 13552 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
13553 (const_int 0)))
13554 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13555 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
d5d5d289 13556 "TARGET_64BIT
3debdc1e 13557 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13558 && ix86_match_ccmode (insn, CCGOCmode)
371bc54b 13559 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13560 "shr{q}\t%0"
371bc54b 13561 [(set_attr "type" "ishift")
a952487c
JJ
13562 (set_attr "length_immediate" "0")
13563 (set_attr "mode" "DI")])
371bc54b 13564
f42684d5
UB
13565(define_insn "*lshrdi3_cconly_one_bit_rex64"
13566 [(set (reg FLAGS_REG)
13567 (compare
13568 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13569 (match_operand:QI 2 "const1_operand" ""))
13570 (const_int 0)))
13571 (clobber (match_scratch:DI 0 "=r"))]
d5d5d289 13572 "TARGET_64BIT
3debdc1e 13573 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13574 && ix86_match_ccmode (insn, CCGOCmode)
f42684d5
UB
13575 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13576 "shr{q}\t%0"
13577 [(set_attr "type" "ishift")
a952487c
JJ
13578 (set_attr "length_immediate" "0")
13579 (set_attr "mode" "DI")])
f42684d5 13580
371bc54b
JH
13581;; This pattern can't accept a variable shift count, since shifts by
13582;; zero don't affect the flags. We assume that shifts by constant
13583;; zero are optimized away.
13584(define_insn "*lshrdi3_cmp_rex64"
42fabf21 13585 [(set (reg FLAGS_REG)
371bc54b
JH
13586 (compare
13587 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
934f2a96 13588 (match_operand:QI 2 "const_1_to_63_operand" "J"))
371bc54b
JH
13589 (const_int 0)))
13590 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13591 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
d5d5d289 13592 "TARGET_64BIT
3debdc1e 13593 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13594 && ix86_match_ccmode (insn, CCGOCmode)
13595 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13596 "shr{q}\t{%2, %0|%0, %2}"
371bc54b
JH
13597 [(set_attr "type" "ishift")
13598 (set_attr "mode" "DI")])
13599
f42684d5
UB
13600(define_insn "*lshrdi3_cconly_rex64"
13601 [(set (reg FLAGS_REG)
13602 (compare
13603 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
934f2a96 13604 (match_operand:QI 2 "const_1_to_63_operand" "J"))
f42684d5
UB
13605 (const_int 0)))
13606 (clobber (match_scratch:DI 0 "=r"))]
d5d5d289 13607 "TARGET_64BIT
3debdc1e 13608 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13609 && ix86_match_ccmode (insn, CCGOCmode)
13610 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
f42684d5
UB
13611 "shr{q}\t{%2, %0|%0, %2}"
13612 [(set_attr "type" "ishift")
13613 (set_attr "mode" "DI")])
13614
93330ea1 13615(define_insn "*lshrdi3_1"
e075ae69
RH
13616 [(set (match_operand:DI 0 "register_operand" "=r")
13617 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13618 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8bc527af 13619 (clobber (reg:CC FLAGS_REG))]
1e07edd3 13620 "!TARGET_64BIT"
e075ae69
RH
13621 "#"
13622 [(set_attr "type" "multi")])
886c62d1 13623
93330ea1
RH
13624;; By default we don't ask for a scratch register, because when DImode
13625;; values are manipulated, registers are already at a premium. But if
13626;; we have one handy, we won't turn it away.
13627(define_peephole2
13628 [(match_scratch:SI 3 "r")
13629 (parallel [(set (match_operand:DI 0 "register_operand" "")
13630 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13631 (match_operand:QI 2 "nonmemory_operand" "")))
13632 (clobber (reg:CC FLAGS_REG))])
13633 (match_dup 3)]
13634 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69 13635 [(const_int 0)]
28356f52 13636 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
886c62d1 13637
6300f037 13638(define_split
e075ae69
RH
13639 [(set (match_operand:DI 0 "register_operand" "")
13640 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13641 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 13642 (clobber (reg:CC FLAGS_REG))]
99523994 13643 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
6fb5fa3c 13644 ? epilogue_completed : reload_completed)"
e075ae69 13645 [(const_int 0)]
28356f52 13646 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
886c62d1 13647
d525dfdf
JH
13648(define_expand "lshrsi3"
13649 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13650 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
7ae14d31 13651 (match_operand:QI 2 "nonmemory_operand" "")))]
d525dfdf
JH
13652 ""
13653 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13654
8bad7136
JL
13655(define_insn "*lshrsi3_1_one_bit"
13656 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13657 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 13658 (match_operand:QI 2 "const1_operand" "")))
8bc527af 13659 (clobber (reg:CC FLAGS_REG))]
3debdc1e 13660 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13661 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13662 "shr{l}\t%0"
8bad7136 13663 [(set_attr "type" "ishift")
a952487c
JJ
13664 (set_attr "length_immediate" "0")
13665 (set_attr "mode" "SI")])
8bad7136 13666
371bc54b
JH
13667(define_insn "*lshrsi3_1_one_bit_zext"
13668 [(set (match_operand:DI 0 "register_operand" "=r")
13669 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
630eef90 13670 (match_operand:QI 2 "const1_operand" "")))
8bc527af 13671 (clobber (reg:CC FLAGS_REG))]
d5d5d289 13672 "TARGET_64BIT
3debdc1e 13673 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13674 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13675 "shr{l}\t%k0"
371bc54b 13676 [(set_attr "type" "ishift")
a952487c
JJ
13677 (set_attr "length_immediate" "0")
13678 (set_attr "mode" "SI")])
371bc54b 13679
d525dfdf 13680(define_insn "*lshrsi3_1"
e075ae69
RH
13681 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13682 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13683 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 13684 (clobber (reg:CC FLAGS_REG))]
d525dfdf 13685 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
e075ae69 13686 "@
0f40f9f7
ZW
13687 shr{l}\t{%2, %0|%0, %2}
13688 shr{l}\t{%b2, %0|%0, %b2}"
6ef67412
JH
13689 [(set_attr "type" "ishift")
13690 (set_attr "mode" "SI")])
886c62d1 13691
371bc54b
JH
13692(define_insn "*lshrsi3_1_zext"
13693 [(set (match_operand:DI 0 "register_operand" "=r,r")
13694 (zero_extend:DI
13695 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13696 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 13697 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
13698 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13699 "@
0f40f9f7
ZW
13700 shr{l}\t{%2, %k0|%k0, %2}
13701 shr{l}\t{%b2, %k0|%k0, %b2}"
371bc54b
JH
13702 [(set_attr "type" "ishift")
13703 (set_attr "mode" "SI")])
13704
8bad7136
JL
13705;; This pattern can't accept a variable shift count, since shifts by
13706;; zero don't affect the flags. We assume that shifts by constant
13707;; zero are optimized away.
2c873473 13708(define_insn "*lshrsi3_one_bit_cmp"
42fabf21 13709 [(set (reg FLAGS_REG)
8bad7136
JL
13710 (compare
13711 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 13712 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
13713 (const_int 0)))
13714 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13715 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
3debdc1e 13716 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13717 && ix86_match_ccmode (insn, CCGOCmode)
8bad7136 13718 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13719 "shr{l}\t%0"
8bad7136 13720 [(set_attr "type" "ishift")
a952487c
JJ
13721 (set_attr "length_immediate" "0")
13722 (set_attr "mode" "SI")])
8bad7136 13723
f42684d5
UB
13724(define_insn "*lshrsi3_one_bit_cconly"
13725 [(set (reg FLAGS_REG)
13726 (compare
13727 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13728 (match_operand:QI 2 "const1_operand" ""))
13729 (const_int 0)))
13730 (clobber (match_scratch:SI 0 "=r"))]
3debdc1e 13731 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13732 && ix86_match_ccmode (insn, CCGOCmode)
f42684d5
UB
13733 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13734 "shr{l}\t%0"
13735 [(set_attr "type" "ishift")
a952487c
JJ
13736 (set_attr "length_immediate" "0")
13737 (set_attr "mode" "SI")])
f42684d5 13738
371bc54b 13739(define_insn "*lshrsi3_cmp_one_bit_zext"
42fabf21 13740 [(set (reg FLAGS_REG)
371bc54b
JH
13741 (compare
13742 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
630eef90 13743 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
13744 (const_int 0)))
13745 (set (match_operand:DI 0 "register_operand" "=r")
13746 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
d5d5d289 13747 "TARGET_64BIT
3debdc1e 13748 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13749 && ix86_match_ccmode (insn, CCGOCmode)
371bc54b 13750 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13751 "shr{l}\t%k0"
371bc54b 13752 [(set_attr "type" "ishift")
a952487c
JJ
13753 (set_attr "length_immediate" "0")
13754 (set_attr "mode" "SI")])
371bc54b 13755
28cefcd2
BS
13756;; This pattern can't accept a variable shift count, since shifts by
13757;; zero don't affect the flags. We assume that shifts by constant
13758;; zero are optimized away.
2c873473 13759(define_insn "*lshrsi3_cmp"
42fabf21 13760 [(set (reg FLAGS_REG)
16189740 13761 (compare
28cefcd2 13762 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
ef719a44 13763 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 13764 (const_int 0)))
28cefcd2 13765 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 13766 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
3debdc1e 13767 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13768 && ix86_match_ccmode (insn, CCGOCmode)
13769 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13770 "shr{l}\t{%2, %0|%0, %2}"
6ef67412
JH
13771 [(set_attr "type" "ishift")
13772 (set_attr "mode" "SI")])
886c62d1 13773
f42684d5
UB
13774(define_insn "*lshrsi3_cconly"
13775 [(set (reg FLAGS_REG)
13776 (compare
13777 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13778 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13779 (const_int 0)))
13780 (clobber (match_scratch:SI 0 "=r"))]
3debdc1e 13781 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13782 && ix86_match_ccmode (insn, CCGOCmode)
13783 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
f42684d5
UB
13784 "shr{l}\t{%2, %0|%0, %2}"
13785 [(set_attr "type" "ishift")
13786 (set_attr "mode" "SI")])
13787
371bc54b 13788(define_insn "*lshrsi3_cmp_zext"
42fabf21 13789 [(set (reg FLAGS_REG)
371bc54b
JH
13790 (compare
13791 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
ef719a44 13792 (match_operand:QI 2 "const_1_to_31_operand" "I"))
371bc54b
JH
13793 (const_int 0)))
13794 (set (match_operand:DI 0 "register_operand" "=r")
13795 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
d5d5d289 13796 "TARGET_64BIT
3debdc1e 13797 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13798 && ix86_match_ccmode (insn, CCGOCmode)
13799 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13800 "shr{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
13801 [(set_attr "type" "ishift")
13802 (set_attr "mode" "SI")])
13803
d525dfdf
JH
13804(define_expand "lshrhi3"
13805 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13806 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
7ae14d31 13807 (match_operand:QI 2 "nonmemory_operand" "")))]
d9f32422 13808 "TARGET_HIMODE_MATH"
d525dfdf
JH
13809 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13810
8bad7136
JL
13811(define_insn "*lshrhi3_1_one_bit"
13812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13813 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 13814 (match_operand:QI 2 "const1_operand" "")))
8bc527af 13815 (clobber (reg:CC FLAGS_REG))]
3debdc1e 13816 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13817 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13818 "shr{w}\t%0"
8bad7136 13819 [(set_attr "type" "ishift")
a952487c
JJ
13820 (set_attr "length_immediate" "0")
13821 (set_attr "mode" "HI")])
8bad7136 13822
d525dfdf 13823(define_insn "*lshrhi3_1"
e075ae69
RH
13824 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13825 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13826 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 13827 (clobber (reg:CC FLAGS_REG))]
d525dfdf 13828 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
e075ae69 13829 "@
0f40f9f7
ZW
13830 shr{w}\t{%2, %0|%0, %2}
13831 shr{w}\t{%b2, %0|%0, %b2}"
6ef67412
JH
13832 [(set_attr "type" "ishift")
13833 (set_attr "mode" "HI")])
886c62d1 13834
8bad7136
JL
13835;; This pattern can't accept a variable shift count, since shifts by
13836;; zero don't affect the flags. We assume that shifts by constant
13837;; zero are optimized away.
2c873473 13838(define_insn "*lshrhi3_one_bit_cmp"
42fabf21 13839 [(set (reg FLAGS_REG)
8bad7136
JL
13840 (compare
13841 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 13842 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
13843 (const_int 0)))
13844 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13845 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
3debdc1e 13846 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13847 && ix86_match_ccmode (insn, CCGOCmode)
8bad7136 13848 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13849 "shr{w}\t%0"
8bad7136 13850 [(set_attr "type" "ishift")
a952487c
JJ
13851 (set_attr "length_immediate" "0")
13852 (set_attr "mode" "HI")])
8bad7136 13853
f42684d5
UB
13854(define_insn "*lshrhi3_one_bit_cconly"
13855 [(set (reg FLAGS_REG)
13856 (compare
13857 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13858 (match_operand:QI 2 "const1_operand" ""))
13859 (const_int 0)))
13860 (clobber (match_scratch:HI 0 "=r"))]
3debdc1e 13861 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13862 && ix86_match_ccmode (insn, CCGOCmode)
f42684d5
UB
13863 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13864 "shr{w}\t%0"
13865 [(set_attr "type" "ishift")
a952487c
JJ
13866 (set_attr "length_immediate" "0")
13867 (set_attr "mode" "HI")])
f42684d5 13868
28cefcd2
BS
13869;; This pattern can't accept a variable shift count, since shifts by
13870;; zero don't affect the flags. We assume that shifts by constant
13871;; zero are optimized away.
2c873473 13872(define_insn "*lshrhi3_cmp"
42fabf21 13873 [(set (reg FLAGS_REG)
16189740 13874 (compare
28cefcd2 13875 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
ef719a44 13876 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 13877 (const_int 0)))
28cefcd2 13878 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 13879 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
3debdc1e 13880 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13881 && ix86_match_ccmode (insn, CCGOCmode)
13882 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 13883 "shr{w}\t{%2, %0|%0, %2}"
6ef67412
JH
13884 [(set_attr "type" "ishift")
13885 (set_attr "mode" "HI")])
886c62d1 13886
f42684d5
UB
13887(define_insn "*lshrhi3_cconly"
13888 [(set (reg FLAGS_REG)
13889 (compare
13890 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13891 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13892 (const_int 0)))
13893 (clobber (match_scratch:HI 0 "=r"))]
3debdc1e 13894 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
13895 && ix86_match_ccmode (insn, CCGOCmode)
13896 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
f42684d5
UB
13897 "shr{w}\t{%2, %0|%0, %2}"
13898 [(set_attr "type" "ishift")
13899 (set_attr "mode" "HI")])
13900
d525dfdf
JH
13901(define_expand "lshrqi3"
13902 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13903 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
7ae14d31 13904 (match_operand:QI 2 "nonmemory_operand" "")))]
d9f32422 13905 "TARGET_QIMODE_MATH"
d525dfdf
JH
13906 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13907
8bad7136
JL
13908(define_insn "*lshrqi3_1_one_bit"
13909 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13910 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 13911 (match_operand:QI 2 "const1_operand" "")))
8bc527af 13912 (clobber (reg:CC FLAGS_REG))]
3debdc1e 13913 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13914 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
0f40f9f7 13915 "shr{b}\t%0"
8bad7136 13916 [(set_attr "type" "ishift")
a952487c
JJ
13917 (set_attr "length_immediate" "0")
13918 (set_attr "mode" "QI")])
8bad7136 13919
2f41793e
JH
13920(define_insn "*lshrqi3_1_one_bit_slp"
13921 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 13922 (lshiftrt:QI (match_dup 0)
630eef90 13923 (match_operand:QI 1 "const1_operand" "")))
8bc527af 13924 (clobber (reg:CC FLAGS_REG))]
3debdc1e
JH
13925 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13926 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
2f41793e 13927 "shr{b}\t%0"
1b245ade 13928 [(set_attr "type" "ishift1")
a952487c
JJ
13929 (set_attr "length_immediate" "0")
13930 (set_attr "mode" "QI")])
2f41793e 13931
d525dfdf 13932(define_insn "*lshrqi3_1"
e075ae69
RH
13933 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13934 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13935 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 13936 (clobber (reg:CC FLAGS_REG))]
d525dfdf 13937 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
e075ae69 13938 "@
0f40f9f7
ZW
13939 shr{b}\t{%2, %0|%0, %2}
13940 shr{b}\t{%b2, %0|%0, %b2}"
6ef67412
JH
13941 [(set_attr "type" "ishift")
13942 (set_attr "mode" "QI")])
886c62d1 13943
2f41793e
JH
13944(define_insn "*lshrqi3_1_slp"
13945 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
13946 (lshiftrt:QI (match_dup 0)
13947 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 13948 (clobber (reg:CC FLAGS_REG))]
3debdc1e 13949 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 13950 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2f41793e 13951 "@
1b245ade
JH
13952 shr{b}\t{%1, %0|%0, %1}
13953 shr{b}\t{%b1, %0|%0, %b1}"
13954 [(set_attr "type" "ishift1")
2f41793e
JH
13955 (set_attr "mode" "QI")])
13956
8bad7136
JL
13957;; This pattern can't accept a variable shift count, since shifts by
13958;; zero don't affect the flags. We assume that shifts by constant
13959;; zero are optimized away.
2c873473 13960(define_insn "*lshrqi2_one_bit_cmp"
42fabf21 13961 [(set (reg FLAGS_REG)
8bad7136
JL
13962 (compare
13963 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 13964 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
13965 (const_int 0)))
13966 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13967 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
3debdc1e 13968 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13969 && ix86_match_ccmode (insn, CCGOCmode)
8bad7136 13970 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
0f40f9f7 13971 "shr{b}\t%0"
8bad7136 13972 [(set_attr "type" "ishift")
a952487c
JJ
13973 (set_attr "length_immediate" "0")
13974 (set_attr "mode" "QI")])
8bad7136 13975
f42684d5
UB
13976(define_insn "*lshrqi2_one_bit_cconly"
13977 [(set (reg FLAGS_REG)
13978 (compare
13979 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13980 (match_operand:QI 2 "const1_operand" ""))
13981 (const_int 0)))
13982 (clobber (match_scratch:QI 0 "=q"))]
3debdc1e 13983 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 13984 && ix86_match_ccmode (insn, CCGOCmode)
f42684d5
UB
13985 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13986 "shr{b}\t%0"
13987 [(set_attr "type" "ishift")
a952487c
JJ
13988 (set_attr "length_immediate" "0")
13989 (set_attr "mode" "QI")])
f42684d5 13990
28cefcd2
BS
13991;; This pattern can't accept a variable shift count, since shifts by
13992;; zero don't affect the flags. We assume that shifts by constant
13993;; zero are optimized away.
2c873473 13994(define_insn "*lshrqi2_cmp"
42fabf21 13995 [(set (reg FLAGS_REG)
16189740 13996 (compare
28cefcd2 13997 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
ef719a44 13998 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 13999 (const_int 0)))
122ddbf9 14000 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 14001 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
3debdc1e 14002 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
14003 && ix86_match_ccmode (insn, CCGOCmode)
14004 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
0f40f9f7 14005 "shr{b}\t{%2, %0|%0, %2}"
6ef67412
JH
14006 [(set_attr "type" "ishift")
14007 (set_attr "mode" "QI")])
f42684d5
UB
14008
14009(define_insn "*lshrqi2_cconly"
14010 [(set (reg FLAGS_REG)
14011 (compare
14012 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14013 (match_operand:QI 2 "const_1_to_31_operand" "I"))
14014 (const_int 0)))
14015 (clobber (match_scratch:QI 0 "=q"))]
3debdc1e 14016 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
d5d5d289
L
14017 && ix86_match_ccmode (insn, CCGOCmode)
14018 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
f42684d5
UB
14019 "shr{b}\t{%2, %0|%0, %2}"
14020 [(set_attr "type" "ishift")
14021 (set_attr "mode" "QI")])
886c62d1 14022\f
e075ae69 14023;; Rotate instructions
886c62d1 14024
371bc54b 14025(define_expand "rotldi3"
0f8594ee
MM
14026 [(set (match_operand:DI 0 "shiftdi_operand" "")
14027 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
7ae14d31 14028 (match_operand:QI 2 "nonmemory_operand" "")))]
0f8594ee
MM
14029 ""
14030{
14031 if (TARGET_64BIT)
14032 {
14033 ix86_expand_binary_operator (ROTATE, DImode, operands);
14034 DONE;
14035 }
14036 if (!const_1_to_31_operand (operands[2], VOIDmode))
14037 FAIL;
14038 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
14039 DONE;
14040})
371bc54b 14041
0f8594ee 14042;; Implement rotation using two double-precision shift instructions
6300f037 14043;; and a scratch register.
0f8594ee
MM
14044(define_insn_and_split "ix86_rotldi3"
14045 [(set (match_operand:DI 0 "register_operand" "=r")
14046 (rotate:DI (match_operand:DI 1 "register_operand" "0")
14047 (match_operand:QI 2 "const_1_to_31_operand" "I")))
14048 (clobber (reg:CC FLAGS_REG))
14049 (clobber (match_scratch:SI 3 "=&r"))]
14050 "!TARGET_64BIT"
6300f037 14051 ""
0f8594ee
MM
14052 "&& reload_completed"
14053 [(set (match_dup 3) (match_dup 4))
14054 (parallel
14055 [(set (match_dup 4)
14056 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
14057 (lshiftrt:SI (match_dup 5)
14058 (minus:QI (const_int 32) (match_dup 2)))))
14059 (clobber (reg:CC FLAGS_REG))])
14060 (parallel
14061 [(set (match_dup 5)
14062 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
14063 (lshiftrt:SI (match_dup 3)
14064 (minus:QI (const_int 32) (match_dup 2)))))
14065 (clobber (reg:CC FLAGS_REG))])]
c2b814b9 14066 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
6300f037 14067
371bc54b
JH
14068(define_insn "*rotlsi3_1_one_bit_rex64"
14069 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14070 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 14071 (match_operand:QI 2 "const1_operand" "")))
8bc527af 14072 (clobber (reg:CC FLAGS_REG))]
d5d5d289 14073 "TARGET_64BIT
3debdc1e 14074 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 14075 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
0f40f9f7 14076 "rol{q}\t%0"
890d52e8 14077 [(set_attr "type" "rotate")
a952487c
JJ
14078 (set_attr "length_immediate" "0")
14079 (set_attr "mode" "DI")])
371bc54b
JH
14080
14081(define_insn "*rotldi3_1_rex64"
14082 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14083 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14084 (match_operand:QI 2 "nonmemory_operand" "e,c")))
8bc527af 14085 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
14086 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14087 "@
0f40f9f7
ZW
14088 rol{q}\t{%2, %0|%0, %2}
14089 rol{q}\t{%b2, %0|%0, %b2}"
890d52e8 14090 [(set_attr "type" "rotate")
371bc54b
JH
14091 (set_attr "mode" "DI")])
14092
d525dfdf
JH
14093(define_expand "rotlsi3"
14094 [(set (match_operand:SI 0 "nonimmediate_operand" "")
14095 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
7ae14d31 14096 (match_operand:QI 2 "nonmemory_operand" "")))]
d525dfdf
JH
14097 ""
14098 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
14099
8bad7136
JL
14100(define_insn "*rotlsi3_1_one_bit"
14101 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14102 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 14103 (match_operand:QI 2 "const1_operand" "")))
8bc527af 14104 (clobber (reg:CC FLAGS_REG))]
3debdc1e 14105 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 14106 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
0f40f9f7 14107 "rol{l}\t%0"
890d52e8 14108 [(set_attr "type" "rotate")
a952487c
JJ
14109 (set_attr "length_immediate" "0")
14110 (set_attr "mode" "SI")])
8bad7136 14111
371bc54b
JH
14112(define_insn "*rotlsi3_1_one_bit_zext"
14113 [(set (match_operand:DI 0 "register_operand" "=r")
14114 (zero_extend:DI
14115 (rotate:SI (match_operand:SI 1 "register_operand" "0")
630eef90 14116 (match_operand:QI 2 "const1_operand" ""))))
8bc527af 14117 (clobber (reg:CC FLAGS_REG))]
d5d5d289 14118 "TARGET_64BIT
3debdc1e 14119 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 14120 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
0f40f9f7 14121 "rol{l}\t%k0"
890d52e8 14122 [(set_attr "type" "rotate")
a952487c
JJ
14123 (set_attr "length_immediate" "0")
14124 (set_attr "mode" "SI")])
371bc54b 14125
d525dfdf 14126(define_insn "*rotlsi3_1"
e075ae69
RH
14127 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14128 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14129 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 14130 (clobber (reg:CC FLAGS_REG))]
d525dfdf 14131 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
e075ae69 14132 "@
0f40f9f7
ZW
14133 rol{l}\t{%2, %0|%0, %2}
14134 rol{l}\t{%b2, %0|%0, %b2}"
890d52e8 14135 [(set_attr "type" "rotate")
6ef67412 14136 (set_attr "mode" "SI")])
b4ac57ab 14137
371bc54b
JH
14138(define_insn "*rotlsi3_1_zext"
14139 [(set (match_operand:DI 0 "register_operand" "=r,r")
14140 (zero_extend:DI
14141 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
14142 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 14143 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
14144 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14145 "@
0f40f9f7
ZW
14146 rol{l}\t{%2, %k0|%k0, %2}
14147 rol{l}\t{%b2, %k0|%k0, %b2}"
890d52e8 14148 [(set_attr "type" "rotate")
371bc54b
JH
14149 (set_attr "mode" "SI")])
14150
d525dfdf
JH
14151(define_expand "rotlhi3"
14152 [(set (match_operand:HI 0 "nonimmediate_operand" "")
14153 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
7ae14d31 14154 (match_operand:QI 2 "nonmemory_operand" "")))]
d9f32422 14155 "TARGET_HIMODE_MATH"
d525dfdf
JH
14156 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
14157
8bad7136
JL
14158(define_insn "*rotlhi3_1_one_bit"
14159 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14160 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 14161 (match_operand:QI 2 "const1_operand" "")))
8bc527af 14162 (clobber (reg:CC FLAGS_REG))]
3debdc1e 14163 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 14164 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
0f40f9f7 14165 "rol{w}\t%0"
890d52e8 14166 [(set_attr "type" "rotate")
a952487c
JJ
14167 (set_attr "length_immediate" "0")
14168 (set_attr "mode" "HI")])
8bad7136 14169
d525dfdf 14170(define_insn "*rotlhi3_1"
e075ae69
RH
14171 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14172 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14173 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 14174 (clobber (reg:CC FLAGS_REG))]
d525dfdf 14175 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
e075ae69 14176 "@
0f40f9f7
ZW
14177 rol{w}\t{%2, %0|%0, %2}
14178 rol{w}\t{%b2, %0|%0, %b2}"
890d52e8 14179 [(set_attr "type" "rotate")
6ef67412 14180 (set_attr "mode" "HI")])
47af5d50 14181
fa681e39
UB
14182(define_split
14183 [(set (match_operand:HI 0 "register_operand" "")
14184 (rotate:HI (match_dup 0) (const_int 8)))
14185 (clobber (reg:CC FLAGS_REG))]
14186 "reload_completed"
14187 [(parallel [(set (strict_low_part (match_dup 0))
14188 (bswap:HI (match_dup 0)))
14189 (clobber (reg:CC FLAGS_REG))])]
14190 "")
14191
d525dfdf
JH
14192(define_expand "rotlqi3"
14193 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14194 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
7ae14d31 14195 (match_operand:QI 2 "nonmemory_operand" "")))]
d9f32422 14196 "TARGET_QIMODE_MATH"
d525dfdf
JH
14197 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
14198
2f41793e
JH
14199(define_insn "*rotlqi3_1_one_bit_slp"
14200 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 14201 (rotate:QI (match_dup 0)
630eef90 14202 (match_operand:QI 1 "const1_operand" "")))
8bc527af 14203 (clobber (reg:CC FLAGS_REG))]
3debdc1e
JH
14204 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14205 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
2f41793e 14206 "rol{b}\t%0"
1b245ade 14207 [(set_attr "type" "rotate1")
a952487c
JJ
14208 (set_attr "length_immediate" "0")
14209 (set_attr "mode" "QI")])
2f41793e 14210
8bad7136
JL
14211(define_insn "*rotlqi3_1_one_bit"
14212 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14213 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 14214 (match_operand:QI 2 "const1_operand" "")))
8bc527af 14215 (clobber (reg:CC FLAGS_REG))]
3debdc1e 14216 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 14217 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
0f40f9f7 14218 "rol{b}\t%0"
890d52e8 14219 [(set_attr "type" "rotate")
a952487c
JJ
14220 (set_attr "length_immediate" "0")
14221 (set_attr "mode" "QI")])
8bad7136 14222
2f41793e
JH
14223(define_insn "*rotlqi3_1_slp"
14224 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
14225 (rotate:QI (match_dup 0)
14226 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 14227 (clobber (reg:CC FLAGS_REG))]
3debdc1e 14228 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 14229 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2f41793e 14230 "@
1b245ade
JH
14231 rol{b}\t{%1, %0|%0, %1}
14232 rol{b}\t{%b1, %0|%0, %b1}"
14233 [(set_attr "type" "rotate1")
2f41793e
JH
14234 (set_attr "mode" "QI")])
14235
d525dfdf 14236(define_insn "*rotlqi3_1"
e075ae69
RH
14237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14238 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14239 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 14240 (clobber (reg:CC FLAGS_REG))]
d525dfdf 14241 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
e075ae69 14242 "@
0f40f9f7
ZW
14243 rol{b}\t{%2, %0|%0, %2}
14244 rol{b}\t{%b2, %0|%0, %b2}"
890d52e8 14245 [(set_attr "type" "rotate")
6ef67412 14246 (set_attr "mode" "QI")])
47af5d50 14247
371bc54b 14248(define_expand "rotrdi3"
0f8594ee
MM
14249 [(set (match_operand:DI 0 "shiftdi_operand" "")
14250 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
7ae14d31 14251 (match_operand:QI 2 "nonmemory_operand" "")))]
0f8594ee
MM
14252 ""
14253{
14254 if (TARGET_64BIT)
14255 {
14256 ix86_expand_binary_operator (ROTATERT, DImode, operands);
14257 DONE;
14258 }
14259 if (!const_1_to_31_operand (operands[2], VOIDmode))
14260 FAIL;
14261 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
14262 DONE;
14263})
6300f037 14264
0f8594ee 14265;; Implement rotation using two double-precision shift instructions
6300f037 14266;; and a scratch register.
0f8594ee
MM
14267(define_insn_and_split "ix86_rotrdi3"
14268 [(set (match_operand:DI 0 "register_operand" "=r")
14269 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
14270 (match_operand:QI 2 "const_1_to_31_operand" "I")))
14271 (clobber (reg:CC FLAGS_REG))
14272 (clobber (match_scratch:SI 3 "=&r"))]
14273 "!TARGET_64BIT"
14274 ""
14275 "&& reload_completed"
14276 [(set (match_dup 3) (match_dup 4))
14277 (parallel
14278 [(set (match_dup 4)
14279 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
14280 (ashift:SI (match_dup 5)
14281 (minus:QI (const_int 32) (match_dup 2)))))
14282 (clobber (reg:CC FLAGS_REG))])
14283 (parallel
14284 [(set (match_dup 5)
14285 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
14286 (ashift:SI (match_dup 3)
14287 (minus:QI (const_int 32) (match_dup 2)))))
14288 (clobber (reg:CC FLAGS_REG))])]
c2b814b9 14289 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
371bc54b
JH
14290
14291(define_insn "*rotrdi3_1_one_bit_rex64"
14292 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14293 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 14294 (match_operand:QI 2 "const1_operand" "")))
8bc527af 14295 (clobber (reg:CC FLAGS_REG))]
d5d5d289 14296 "TARGET_64BIT
3debdc1e 14297 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 14298 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
0f40f9f7 14299 "ror{q}\t%0"
890d52e8 14300 [(set_attr "type" "rotate")
a952487c
JJ
14301 (set_attr "length_immediate" "0")
14302 (set_attr "mode" "DI")])
371bc54b
JH
14303
14304(define_insn "*rotrdi3_1_rex64"
14305 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14306 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14307 (match_operand:QI 2 "nonmemory_operand" "J,c")))
8bc527af 14308 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
14309 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14310 "@
0f40f9f7
ZW
14311 ror{q}\t{%2, %0|%0, %2}
14312 ror{q}\t{%b2, %0|%0, %b2}"
890d52e8 14313 [(set_attr "type" "rotate")
371bc54b
JH
14314 (set_attr "mode" "DI")])
14315
d525dfdf
JH
14316(define_expand "rotrsi3"
14317 [(set (match_operand:SI 0 "nonimmediate_operand" "")
14318 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
7ae14d31 14319 (match_operand:QI 2 "nonmemory_operand" "")))]
d525dfdf
JH
14320 ""
14321 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
14322
8bad7136
JL
14323(define_insn "*rotrsi3_1_one_bit"
14324 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14325 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 14326 (match_operand:QI 2 "const1_operand" "")))
8bc527af 14327 (clobber (reg:CC FLAGS_REG))]
3debdc1e 14328 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 14329 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
0f40f9f7 14330 "ror{l}\t%0"
890d52e8 14331 [(set_attr "type" "rotate")
a952487c
JJ
14332 (set_attr "length_immediate" "0")
14333 (set_attr "mode" "SI")])
8bad7136 14334
371bc54b
JH
14335(define_insn "*rotrsi3_1_one_bit_zext"
14336 [(set (match_operand:DI 0 "register_operand" "=r")
14337 (zero_extend:DI
14338 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
630eef90 14339 (match_operand:QI 2 "const1_operand" ""))))
8bc527af 14340 (clobber (reg:CC FLAGS_REG))]
d5d5d289 14341 "TARGET_64BIT
3debdc1e 14342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 14343 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
0f40f9f7 14344 "ror{l}\t%k0"
890d52e8 14345 [(set_attr "type" "rotate")
a952487c
JJ
14346 (set_attr "length_immediate" "0")
14347 (set_attr "mode" "SI")])
371bc54b 14348
d525dfdf 14349(define_insn "*rotrsi3_1"
e075ae69
RH
14350 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14351 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14352 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 14353 (clobber (reg:CC FLAGS_REG))]
d525dfdf 14354 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
e075ae69 14355 "@
0f40f9f7
ZW
14356 ror{l}\t{%2, %0|%0, %2}
14357 ror{l}\t{%b2, %0|%0, %b2}"
890d52e8 14358 [(set_attr "type" "rotate")
6ef67412 14359 (set_attr "mode" "SI")])
47af5d50 14360
371bc54b
JH
14361(define_insn "*rotrsi3_1_zext"
14362 [(set (match_operand:DI 0 "register_operand" "=r,r")
14363 (zero_extend:DI
14364 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
14365 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 14366 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
14367 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14368 "@
0f40f9f7
ZW
14369 ror{l}\t{%2, %k0|%k0, %2}
14370 ror{l}\t{%b2, %k0|%k0, %b2}"
890d52e8 14371 [(set_attr "type" "rotate")
371bc54b
JH
14372 (set_attr "mode" "SI")])
14373
d525dfdf
JH
14374(define_expand "rotrhi3"
14375 [(set (match_operand:HI 0 "nonimmediate_operand" "")
14376 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
7ae14d31 14377 (match_operand:QI 2 "nonmemory_operand" "")))]
d9f32422 14378 "TARGET_HIMODE_MATH"
d525dfdf
JH
14379 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
14380
8bad7136
JL
14381(define_insn "*rotrhi3_one_bit"
14382 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14383 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 14384 (match_operand:QI 2 "const1_operand" "")))
8bc527af 14385 (clobber (reg:CC FLAGS_REG))]
3debdc1e 14386 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 14387 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
0f40f9f7 14388 "ror{w}\t%0"
890d52e8 14389 [(set_attr "type" "rotate")
a952487c
JJ
14390 (set_attr "length_immediate" "0")
14391 (set_attr "mode" "HI")])
8bad7136 14392
fa681e39 14393(define_insn "*rotrhi3_1"
e075ae69
RH
14394 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14395 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14396 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 14397 (clobber (reg:CC FLAGS_REG))]
d525dfdf 14398 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
e075ae69 14399 "@
0f40f9f7
ZW
14400 ror{w}\t{%2, %0|%0, %2}
14401 ror{w}\t{%b2, %0|%0, %b2}"
890d52e8 14402 [(set_attr "type" "rotate")
6ef67412 14403 (set_attr "mode" "HI")])
a199fdd6 14404
fa681e39
UB
14405(define_split
14406 [(set (match_operand:HI 0 "register_operand" "")
14407 (rotatert:HI (match_dup 0) (const_int 8)))
14408 (clobber (reg:CC FLAGS_REG))]
14409 "reload_completed"
14410 [(parallel [(set (strict_low_part (match_dup 0))
14411 (bswap:HI (match_dup 0)))
14412 (clobber (reg:CC FLAGS_REG))])]
14413 "")
14414
d525dfdf
JH
14415(define_expand "rotrqi3"
14416 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14417 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
7ae14d31 14418 (match_operand:QI 2 "nonmemory_operand" "")))]
d9f32422 14419 "TARGET_QIMODE_MATH"
d525dfdf
JH
14420 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
14421
8bad7136
JL
14422(define_insn "*rotrqi3_1_one_bit"
14423 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14424 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 14425 (match_operand:QI 2 "const1_operand" "")))
8bc527af 14426 (clobber (reg:CC FLAGS_REG))]
3debdc1e 14427 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
d5d5d289 14428 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
0f40f9f7 14429 "ror{b}\t%0"
890d52e8 14430 [(set_attr "type" "rotate")
a952487c
JJ
14431 (set_attr "length_immediate" "0")
14432 (set_attr "mode" "QI")])
8bad7136 14433
2f41793e
JH
14434(define_insn "*rotrqi3_1_one_bit_slp"
14435 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 14436 (rotatert:QI (match_dup 0)
630eef90 14437 (match_operand:QI 1 "const1_operand" "")))
8bc527af 14438 (clobber (reg:CC FLAGS_REG))]
3debdc1e
JH
14439 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
2f41793e 14441 "ror{b}\t%0"
1b245ade 14442 [(set_attr "type" "rotate1")
a952487c
JJ
14443 (set_attr "length_immediate" "0")
14444 (set_attr "mode" "QI")])
2f41793e 14445
d525dfdf 14446(define_insn "*rotrqi3_1"
e075ae69
RH
14447 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14448 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14449 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 14450 (clobber (reg:CC FLAGS_REG))]
d525dfdf 14451 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
e075ae69 14452 "@
0f40f9f7
ZW
14453 ror{b}\t{%2, %0|%0, %2}
14454 ror{b}\t{%b2, %0|%0, %b2}"
890d52e8 14455 [(set_attr "type" "rotate")
6ef67412 14456 (set_attr "mode" "QI")])
2f41793e
JH
14457
14458(define_insn "*rotrqi3_1_slp"
14459 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
14460 (rotatert:QI (match_dup 0)
14461 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 14462 (clobber (reg:CC FLAGS_REG))]
3debdc1e 14463 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7656aee4 14464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2f41793e 14465 "@
1b245ade
JH
14466 ror{b}\t{%1, %0|%0, %1}
14467 ror{b}\t{%b1, %0|%0, %b1}"
14468 [(set_attr "type" "rotate1")
2f41793e 14469 (set_attr "mode" "QI")])
e075ae69
RH
14470\f
14471;; Bit set / bit test instructions
a199fdd6 14472
e075ae69
RH
14473(define_expand "extv"
14474 [(set (match_operand:SI 0 "register_operand" "")
14475 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
f7acbf4c
RS
14476 (match_operand:SI 2 "const8_operand" "")
14477 (match_operand:SI 3 "const8_operand" "")))]
e075ae69 14478 ""
e075ae69
RH
14479{
14480 /* Handle extractions from %ah et al. */
14481 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14482 FAIL;
a199fdd6 14483
e075ae69
RH
14484 /* From mips.md: extract_bit_field doesn't verify that our source
14485 matches the predicate, so check it again here. */
6e62a38d 14486 if (! ext_register_operand (operands[1], VOIDmode))
e075ae69 14487 FAIL;
0f40f9f7 14488})
a199fdd6 14489
e075ae69
RH
14490(define_expand "extzv"
14491 [(set (match_operand:SI 0 "register_operand" "")
14492 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
f7acbf4c
RS
14493 (match_operand:SI 2 "const8_operand" "")
14494 (match_operand:SI 3 "const8_operand" "")))]
e075ae69 14495 ""
e075ae69
RH
14496{
14497 /* Handle extractions from %ah et al. */
14498 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14499 FAIL;
a199fdd6 14500
e075ae69
RH
14501 /* From mips.md: extract_bit_field doesn't verify that our source
14502 matches the predicate, so check it again here. */
6e62a38d 14503 if (! ext_register_operand (operands[1], VOIDmode))
e075ae69 14504 FAIL;
0f40f9f7 14505})
a199fdd6 14506
e075ae69 14507(define_expand "insv"
044b3892 14508 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
f7acbf4c
RS
14509 (match_operand 1 "const8_operand" "")
14510 (match_operand 2 "const8_operand" ""))
044b3892 14511 (match_operand 3 "register_operand" ""))]
e075ae69 14512 ""
e075ae69 14513{
f7acbf4c 14514 /* Handle insertions to %ah et al. */
e075ae69
RH
14515 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
14516 FAIL;
a199fdd6 14517
e075ae69
RH
14518 /* From mips.md: insert_bit_field doesn't verify that our source
14519 matches the predicate, so check it again here. */
6e62a38d 14520 if (! ext_register_operand (operands[0], VOIDmode))
e075ae69 14521 FAIL;
044b3892
L
14522
14523 if (TARGET_64BIT)
14524 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
14525 else
14526 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
14527
14528 DONE;
0f40f9f7 14529})
e075ae69
RH
14530
14531;; %%% bts, btr, btc, bt.
7cacf53e
RH
14532;; In general these instructions are *slow* when applied to memory,
14533;; since they enforce atomic operation. When applied to registers,
14534;; it depends on the cpu implementation. They're never faster than
14535;; the corresponding and/ior/xor operations, so with 32-bit there's
14536;; no point. But in 64-bit, we can't hold the relevant immediates
14537;; within the instruction itself, so operating on bits in the high
14538;; 32-bits of a register becomes easier.
14539;;
14540;; These are slow on Nocona, but fast on Athlon64. We do require the use
14541;; of btrq and btcq for corner cases of post-reload expansion of absdf and
14542;; negdf respectively, so they can never be disabled entirely.
14543
14544(define_insn "*btsq"
ad4f9e7e 14545 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
7cacf53e 14546 (const_int 1)
ad4f9e7e 14547 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
14548 (const_int 1))
14549 (clobber (reg:CC FLAGS_REG))]
14550 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
33ee5810 14551 "bts{q}\t{%1, %0|%0, %1}"
a952487c 14552 [(set_attr "type" "alu1")
725fd454
JJ
14553 (set_attr "prefix_0f" "1")
14554 (set_attr "mode" "DI")])
7cacf53e
RH
14555
14556(define_insn "*btrq"
ad4f9e7e 14557 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
7cacf53e 14558 (const_int 1)
ad4f9e7e 14559 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
14560 (const_int 0))
14561 (clobber (reg:CC FLAGS_REG))]
14562 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
33ee5810 14563 "btr{q}\t{%1, %0|%0, %1}"
a952487c 14564 [(set_attr "type" "alu1")
725fd454
JJ
14565 (set_attr "prefix_0f" "1")
14566 (set_attr "mode" "DI")])
7cacf53e
RH
14567
14568(define_insn "*btcq"
ad4f9e7e 14569 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
7cacf53e 14570 (const_int 1)
ad4f9e7e 14571 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
14572 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
14573 (clobber (reg:CC FLAGS_REG))]
14574 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
33ee5810 14575 "btc{q}\t{%1, %0|%0, %1}"
a952487c 14576 [(set_attr "type" "alu1")
725fd454
JJ
14577 (set_attr "prefix_0f" "1")
14578 (set_attr "mode" "DI")])
7cacf53e
RH
14579
14580;; Allow Nocona to avoid these instructions if a register is available.
14581
14582(define_peephole2
14583 [(match_scratch:DI 2 "r")
14584 (parallel [(set (zero_extract:DI
ad4f9e7e 14585 (match_operand:DI 0 "register_operand" "")
7cacf53e 14586 (const_int 1)
ad4f9e7e 14587 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
14588 (const_int 1))
14589 (clobber (reg:CC FLAGS_REG))])]
14590 "TARGET_64BIT && !TARGET_USE_BT"
14591 [(const_int 0)]
14592{
14593 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14594 rtx op1;
14595
14596 if (HOST_BITS_PER_WIDE_INT >= 64)
14597 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14598 else if (i < HOST_BITS_PER_WIDE_INT)
14599 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14600 else
14601 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14602
14603 op1 = immed_double_const (lo, hi, DImode);
14604 if (i >= 31)
14605 {
14606 emit_move_insn (operands[2], op1);
14607 op1 = operands[2];
14608 }
14609
14610 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14611 DONE;
14612})
14613
14614(define_peephole2
14615 [(match_scratch:DI 2 "r")
14616 (parallel [(set (zero_extract:DI
ad4f9e7e 14617 (match_operand:DI 0 "register_operand" "")
7cacf53e 14618 (const_int 1)
ad4f9e7e 14619 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
14620 (const_int 0))
14621 (clobber (reg:CC FLAGS_REG))])]
14622 "TARGET_64BIT && !TARGET_USE_BT"
14623 [(const_int 0)]
14624{
14625 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14626 rtx op1;
14627
14628 if (HOST_BITS_PER_WIDE_INT >= 64)
14629 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14630 else if (i < HOST_BITS_PER_WIDE_INT)
14631 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14632 else
14633 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14634
14635 op1 = immed_double_const (~lo, ~hi, DImode);
14636 if (i >= 32)
14637 {
14638 emit_move_insn (operands[2], op1);
14639 op1 = operands[2];
14640 }
14641
14642 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14643 DONE;
14644})
14645
14646(define_peephole2
14647 [(match_scratch:DI 2 "r")
14648 (parallel [(set (zero_extract:DI
ad4f9e7e 14649 (match_operand:DI 0 "register_operand" "")
7cacf53e 14650 (const_int 1)
ad4f9e7e 14651 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
14652 (not:DI (zero_extract:DI
14653 (match_dup 0) (const_int 1) (match_dup 1))))
14654 (clobber (reg:CC FLAGS_REG))])]
14655 "TARGET_64BIT && !TARGET_USE_BT"
14656 [(const_int 0)]
14657{
14658 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14659 rtx op1;
14660
14661 if (HOST_BITS_PER_WIDE_INT >= 64)
14662 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14663 else if (i < HOST_BITS_PER_WIDE_INT)
14664 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14665 else
14666 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14667
14668 op1 = immed_double_const (lo, hi, DImode);
14669 if (i >= 31)
14670 {
14671 emit_move_insn (operands[2], op1);
14672 op1 = operands[2];
14673 }
14674
14675 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14676 DONE;
14677})
33ee5810
UB
14678
14679(define_insn "*btdi_rex64"
14680 [(set (reg:CCC FLAGS_REG)
14681 (compare:CCC
14682 (zero_extract:DI
14683 (match_operand:DI 0 "register_operand" "r")
14684 (const_int 1)
88b9490b 14685 (match_operand:DI 1 "nonmemory_operand" "rN"))
33ee5810 14686 (const_int 0)))]
3debdc1e 14687 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
33ee5810 14688 "bt{q}\t{%1, %0|%0, %1}"
a952487c 14689 [(set_attr "type" "alu1")
725fd454
JJ
14690 (set_attr "prefix_0f" "1")
14691 (set_attr "mode" "DI")])
33ee5810
UB
14692
14693(define_insn "*btsi"
14694 [(set (reg:CCC FLAGS_REG)
14695 (compare:CCC
14696 (zero_extract:SI
14697 (match_operand:SI 0 "register_operand" "r")
14698 (const_int 1)
88b9490b 14699 (match_operand:SI 1 "nonmemory_operand" "rN"))
33ee5810 14700 (const_int 0)))]
3debdc1e 14701 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
33ee5810 14702 "bt{l}\t{%1, %0|%0, %1}"
a952487c 14703 [(set_attr "type" "alu1")
725fd454
JJ
14704 (set_attr "prefix_0f" "1")
14705 (set_attr "mode" "SI")])
886c62d1
JVA
14706\f
14707;; Store-flag instructions.
14708
c572e5ba
JVA
14709;; For all sCOND expanders, also expand the compare or test insn that
14710;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14711
e075ae69
RH
14712;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14713;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14714;; way, which can later delete the movzx if only QImode is needed.
14715
e075ae69 14716(define_insn "*setcc_1"
a269a03c 14717 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9076b9c1 14718 (match_operator:QI 1 "ix86_comparison_operator"
42fabf21 14719 [(reg FLAGS_REG) (const_int 0)]))]
e075ae69 14720 ""
0f40f9f7 14721 "set%C1\t%0"
6ef67412
JH
14722 [(set_attr "type" "setcc")
14723 (set_attr "mode" "QI")])
a269a03c 14724
93330ea1 14725(define_insn "*setcc_2"
e075ae69 14726 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9076b9c1 14727 (match_operator:QI 1 "ix86_comparison_operator"
42fabf21 14728 [(reg FLAGS_REG) (const_int 0)]))]
e075ae69 14729 ""
0f40f9f7 14730 "set%C1\t%0"
6ef67412
JH
14731 [(set_attr "type" "setcc")
14732 (set_attr "mode" "QI")])
e075ae69 14733
10978207 14734;; In general it is not safe to assume too much about CCmode registers,
6300f037 14735;; so simplify-rtx stops when it sees a second one. Under certain
10978207
RH
14736;; conditions this is safe on x86, so help combine not create
14737;;
14738;; seta %al
14739;; testb %al, %al
14740;; sete %al
14741
6300f037 14742(define_split
10978207
RH
14743 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14744 (ne:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 14745 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
14746 (const_int 0)))]
14747 ""
14748 [(set (match_dup 0) (match_dup 1))]
14749{
14750 PUT_MODE (operands[1], QImode);
14751})
14752
6300f037 14753(define_split
10978207
RH
14754 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14755 (ne:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 14756 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
14757 (const_int 0)))]
14758 ""
14759 [(set (match_dup 0) (match_dup 1))]
14760{
14761 PUT_MODE (operands[1], QImode);
14762})
14763
6300f037 14764(define_split
10978207
RH
14765 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14766 (eq:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 14767 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
14768 (const_int 0)))]
14769 ""
14770 [(set (match_dup 0) (match_dup 1))]
14771{
14772 rtx new_op1 = copy_rtx (operands[1]);
14773 operands[1] = new_op1;
14774 PUT_MODE (new_op1, QImode);
3c5cb3e4
KH
14775 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14776 GET_MODE (XEXP (new_op1, 0))));
10978207
RH
14777
14778 /* Make sure that (a) the CCmode we have for the flags is strong
14779 enough for the reversed compare or (b) we have a valid FP compare. */
14780 if (! ix86_comparison_operator (new_op1, VOIDmode))
14781 FAIL;
14782})
14783
6300f037 14784(define_split
10978207
RH
14785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14786 (eq:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 14787 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
14788 (const_int 0)))]
14789 ""
14790 [(set (match_dup 0) (match_dup 1))]
14791{
14792 rtx new_op1 = copy_rtx (operands[1]);
14793 operands[1] = new_op1;
14794 PUT_MODE (new_op1, QImode);
3c5cb3e4
KH
14795 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14796 GET_MODE (XEXP (new_op1, 0))));
10978207
RH
14797
14798 /* Make sure that (a) the CCmode we have for the flags is strong
14799 enough for the reversed compare or (b) we have a valid FP compare. */
14800 if (! ix86_comparison_operator (new_op1, VOIDmode))
14801 FAIL;
14802})
14803
a46d1d38
JH
14804;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14805;; subsequent logical operations are used to imitate conditional moves.
14806;; 0xffffffff is NaN, but not in normalized form, so we can't represent
ab8efbd8 14807;; it directly.
a46d1d38 14808
95879c72
L
14809(define_insn "*avx_setcc<mode>"
14810 [(set (match_operand:MODEF 0 "register_operand" "=x")
14811 (match_operator:MODEF 1 "avx_comparison_float_operator"
14812 [(match_operand:MODEF 2 "register_operand" "x")
14813 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14814 "TARGET_AVX"
14815 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14816 [(set_attr "type" "ssecmp")
14817 (set_attr "prefix" "vex")
725fd454 14818 (set_attr "length_immediate" "1")
95879c72
L
14819 (set_attr "mode" "<MODE>")])
14820
d6023b50
UB
14821(define_insn "*sse_setcc<mode>"
14822 [(set (match_operand:MODEF 0 "register_operand" "=x")
14823 (match_operator:MODEF 1 "sse_comparison_operator"
14824 [(match_operand:MODEF 2 "register_operand" "0")
14825 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14826 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14827 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
3d34cd91 14828 [(set_attr "type" "ssecmp")
725fd454 14829 (set_attr "length_immediate" "1")
d6023b50 14830 (set_attr "mode" "<MODE>")])
04e1d06b
MM
14831
14832(define_insn "*sse5_setcc<mode>"
14833 [(set (match_operand:MODEF 0 "register_operand" "=x")
14834 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14835 [(match_operand:MODEF 2 "register_operand" "x")
14836 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14837 "TARGET_SSE5"
d51fba8e 14838 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
04e1d06b 14839 [(set_attr "type" "sse4arg")
725fd454 14840 (set_attr "length_immediate" "1")
04e1d06b
MM
14841 (set_attr "mode" "<MODE>")])
14842
886c62d1
JVA
14843\f
14844;; Basic conditional jump instructions.
14845;; We ignore the overflow flag for signed branch instructions.
14846
e075ae69
RH
14847(define_insn "*jcc_1"
14848 [(set (pc)
9076b9c1 14849 (if_then_else (match_operator 1 "ix86_comparison_operator"
42fabf21 14850 [(reg FLAGS_REG) (const_int 0)])
6ef67412 14851 (label_ref (match_operand 0 "" ""))
e075ae69
RH
14852 (pc)))]
14853 ""
0f40f9f7 14854 "%+j%C1\t%l0"
e075ae69 14855 [(set_attr "type" "ibr")
c7375e61 14856 (set_attr "modrm" "0")
efcc7037 14857 (set (attr "length")
6ef67412 14858 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 14859 (const_int -126))
6ef67412 14860 (lt (minus (match_dup 0) (pc))
db1077d3 14861 (const_int 128)))
efcc7037
JH
14862 (const_int 2)
14863 (const_int 6)))])
e075ae69
RH
14864
14865(define_insn "*jcc_2"
14866 [(set (pc)
9076b9c1 14867 (if_then_else (match_operator 1 "ix86_comparison_operator"
42fabf21 14868 [(reg FLAGS_REG) (const_int 0)])
e075ae69 14869 (pc)
6ef67412 14870 (label_ref (match_operand 0 "" ""))))]
e075ae69 14871 ""
0f40f9f7 14872 "%+j%c1\t%l0"
e075ae69 14873 [(set_attr "type" "ibr")
c7375e61 14874 (set_attr "modrm" "0")
efcc7037 14875 (set (attr "length")
6ef67412 14876 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 14877 (const_int -126))
6ef67412 14878 (lt (minus (match_dup 0) (pc))
db1077d3 14879 (const_int 128)))
efcc7037
JH
14880 (const_int 2)
14881 (const_int 6)))])
e075ae69 14882
592188a5 14883;; In general it is not safe to assume too much about CCmode registers,
6300f037 14884;; so simplify-rtx stops when it sees a second one. Under certain
592188a5
RH
14885;; conditions this is safe on x86, so help combine not create
14886;;
14887;; seta %al
14888;; testb %al, %al
14889;; je Lfoo
14890
6300f037 14891(define_split
592188a5
RH
14892 [(set (pc)
14893 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
42fabf21 14894 [(reg FLAGS_REG) (const_int 0)])
592188a5
RH
14895 (const_int 0))
14896 (label_ref (match_operand 1 "" ""))
14897 (pc)))]
14898 ""
14899 [(set (pc)
14900 (if_then_else (match_dup 0)
14901 (label_ref (match_dup 1))
14902 (pc)))]
14903{
14904 PUT_MODE (operands[0], VOIDmode);
14905})
6300f037
EC
14906
14907(define_split
592188a5
RH
14908 [(set (pc)
14909 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
42fabf21 14910 [(reg FLAGS_REG) (const_int 0)])
592188a5
RH
14911 (const_int 0))
14912 (label_ref (match_operand 1 "" ""))
14913 (pc)))]
14914 ""
14915 [(set (pc)
14916 (if_then_else (match_dup 0)
14917 (label_ref (match_dup 1))
14918 (pc)))]
14919{
14920 rtx new_op0 = copy_rtx (operands[0]);
14921 operands[0] = new_op0;
14922 PUT_MODE (new_op0, VOIDmode);
3c5cb3e4
KH
14923 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14924 GET_MODE (XEXP (new_op0, 0))));
592188a5
RH
14925
14926 /* Make sure that (a) the CCmode we have for the flags is strong
14927 enough for the reversed compare or (b) we have a valid FP compare. */
14928 if (! ix86_comparison_operator (new_op0, VOIDmode))
14929 FAIL;
14930})
14931
33ee5810
UB
14932;; zero_extend in SImode is correct, since this is what combine pass
14933;; generates from shift insn with QImode operand. Actually, the mode of
14934;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14935;; appropriate modulo of the bit offset value.
14936
14937(define_insn_and_split "*jcc_btdi_rex64"
14938 [(set (pc)
14939 (if_then_else (match_operator 0 "bt_comparison_operator"
14940 [(zero_extract:DI
14941 (match_operand:DI 1 "register_operand" "r")
14942 (const_int 1)
14943 (zero_extend:SI
14944 (match_operand:QI 2 "register_operand" "r")))
14945 (const_int 0)])
14946 (label_ref (match_operand 3 "" ""))
b7f58d5d
UB
14947 (pc)))
14948 (clobber (reg:CC FLAGS_REG))]
3debdc1e 14949 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
33ee5810
UB
14950 "#"
14951 "&& 1"
14952 [(set (reg:CCC FLAGS_REG)
14953 (compare:CCC
14954 (zero_extract:DI
14955 (match_dup 1)
14956 (const_int 1)
14957 (match_dup 2))
14958 (const_int 0)))
14959 (set (pc)
14960 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14961 (label_ref (match_dup 3))
14962 (pc)))]
14963{
14964 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14965
14966 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14967})
14968
88b9490b
UB
14969;; avoid useless masking of bit offset operand
14970(define_insn_and_split "*jcc_btdi_mask_rex64"
14971 [(set (pc)
14972 (if_then_else (match_operator 0 "bt_comparison_operator"
14973 [(zero_extract:DI
14974 (match_operand:DI 1 "register_operand" "r")
14975 (const_int 1)
14976 (and:SI
14977 (match_operand:SI 2 "register_operand" "r")
14978 (match_operand:SI 3 "const_int_operand" "n")))])
14979 (label_ref (match_operand 4 "" ""))
b7f58d5d
UB
14980 (pc)))
14981 (clobber (reg:CC FLAGS_REG))]
3debdc1e 14982 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
88b9490b
UB
14983 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14984 "#"
14985 "&& 1"
14986 [(set (reg:CCC FLAGS_REG)
14987 (compare:CCC
14988 (zero_extract:DI
14989 (match_dup 1)
14990 (const_int 1)
14991 (match_dup 2))
14992 (const_int 0)))
14993 (set (pc)
14994 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14995 (label_ref (match_dup 4))
14996 (pc)))]
14997{
14998 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14999
15000 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15001})
15002
33ee5810
UB
15003(define_insn_and_split "*jcc_btsi"
15004 [(set (pc)
15005 (if_then_else (match_operator 0 "bt_comparison_operator"
15006 [(zero_extract:SI
15007 (match_operand:SI 1 "register_operand" "r")
15008 (const_int 1)
15009 (zero_extend:SI
15010 (match_operand:QI 2 "register_operand" "r")))
15011 (const_int 0)])
15012 (label_ref (match_operand 3 "" ""))
b7f58d5d
UB
15013 (pc)))
15014 (clobber (reg:CC FLAGS_REG))]
3debdc1e 15015 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
33ee5810
UB
15016 "#"
15017 "&& 1"
15018 [(set (reg:CCC FLAGS_REG)
15019 (compare:CCC
15020 (zero_extract:SI
15021 (match_dup 1)
15022 (const_int 1)
15023 (match_dup 2))
15024 (const_int 0)))
15025 (set (pc)
15026 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15027 (label_ref (match_dup 3))
15028 (pc)))]
15029{
15030 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15031
15032 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15033})
15034
88b9490b
UB
15035;; avoid useless masking of bit offset operand
15036(define_insn_and_split "*jcc_btsi_mask"
15037 [(set (pc)
15038 (if_then_else (match_operator 0 "bt_comparison_operator"
15039 [(zero_extract:SI
15040 (match_operand:SI 1 "register_operand" "r")
15041 (const_int 1)
15042 (and:SI
15043 (match_operand:SI 2 "register_operand" "r")
15044 (match_operand:SI 3 "const_int_operand" "n")))])
15045 (label_ref (match_operand 4 "" ""))
b7f58d5d
UB
15046 (pc)))
15047 (clobber (reg:CC FLAGS_REG))]
3debdc1e 15048 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
88b9490b
UB
15049 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15050 "#"
15051 "&& 1"
15052 [(set (reg:CCC FLAGS_REG)
15053 (compare:CCC
15054 (zero_extract:SI
15055 (match_dup 1)
15056 (const_int 1)
15057 (match_dup 2))
15058 (const_int 0)))
15059 (set (pc)
15060 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15061 (label_ref (match_dup 4))
15062 (pc)))]
15063 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15064
33ee5810
UB
15065(define_insn_and_split "*jcc_btsi_1"
15066 [(set (pc)
15067 (if_then_else (match_operator 0 "bt_comparison_operator"
15068 [(and:SI
15069 (lshiftrt:SI
15070 (match_operand:SI 1 "register_operand" "r")
15071 (match_operand:QI 2 "register_operand" "r"))
15072 (const_int 1))
15073 (const_int 0)])
15074 (label_ref (match_operand 3 "" ""))
b7f58d5d
UB
15075 (pc)))
15076 (clobber (reg:CC FLAGS_REG))]
3debdc1e 15077 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
33ee5810
UB
15078 "#"
15079 "&& 1"
15080 [(set (reg:CCC FLAGS_REG)
15081 (compare:CCC
15082 (zero_extract:SI
15083 (match_dup 1)
15084 (const_int 1)
15085 (match_dup 2))
15086 (const_int 0)))
15087 (set (pc)
15088 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15089 (label_ref (match_dup 3))
15090 (pc)))]
15091{
15092 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15093
15094 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15095})
15096
88b9490b
UB
15097;; avoid useless masking of bit offset operand
15098(define_insn_and_split "*jcc_btsi_mask_1"
15099 [(set (pc)
15100 (if_then_else
15101 (match_operator 0 "bt_comparison_operator"
15102 [(and:SI
15103 (lshiftrt:SI
15104 (match_operand:SI 1 "register_operand" "r")
15105 (subreg:QI
15106 (and:SI
15107 (match_operand:SI 2 "register_operand" "r")
15108 (match_operand:SI 3 "const_int_operand" "n")) 0))
15109 (const_int 1))
15110 (const_int 0)])
15111 (label_ref (match_operand 4 "" ""))
b7f58d5d
UB
15112 (pc)))
15113 (clobber (reg:CC FLAGS_REG))]
3debdc1e 15114 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
88b9490b
UB
15115 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15116 "#"
15117 "&& 1"
15118 [(set (reg:CCC FLAGS_REG)
15119 (compare:CCC
15120 (zero_extract:SI
15121 (match_dup 1)
15122 (const_int 1)
15123 (match_dup 2))
15124 (const_int 0)))
15125 (set (pc)
15126 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15127 (label_ref (match_dup 4))
15128 (pc)))]
15129 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15130
3a3677ff
RH
15131;; Define combination compare-and-branch fp compare instructions to use
15132;; during early optimization. Splitting the operation apart early makes
15133;; for bad code when we want to reverse the operation.
15134
eaa49b49 15135(define_insn "*fp_jcc_1_mixed"
3a3677ff
RH
15136 [(set (pc)
15137 (if_then_else (match_operator 0 "comparison_operator"
b5c82fa1
PB
15138 [(match_operand 1 "register_operand" "f,x")
15139 (match_operand 2 "nonimmediate_operand" "f,xm")])
3a3677ff
RH
15140 (label_ref (match_operand 3 "" ""))
15141 (pc)))
8bc527af
SB
15142 (clobber (reg:CCFP FPSR_REG))
15143 (clobber (reg:CCFP FLAGS_REG))]
eaa49b49
RH
15144 "TARGET_MIX_SSE_I387
15145 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
15146 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15147 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
15148 "#")
15149
0644b628
JH
15150(define_insn "*fp_jcc_1_sse"
15151 [(set (pc)
15152 (if_then_else (match_operator 0 "comparison_operator"
eaa49b49
RH
15153 [(match_operand 1 "register_operand" "x")
15154 (match_operand 2 "nonimmediate_operand" "xm")])
0644b628
JH
15155 (label_ref (match_operand 3 "" ""))
15156 (pc)))
8bc527af
SB
15157 (clobber (reg:CCFP FPSR_REG))
15158 (clobber (reg:CCFP FLAGS_REG))]
eaa49b49 15159 "TARGET_SSE_MATH
0644b628 15160 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
15161 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15162 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
15163 "#")
15164
eaa49b49 15165(define_insn "*fp_jcc_1_387"
0644b628
JH
15166 [(set (pc)
15167 (if_then_else (match_operator 0 "comparison_operator"
eaa49b49
RH
15168 [(match_operand 1 "register_operand" "f")
15169 (match_operand 2 "register_operand" "f")])
0644b628
JH
15170 (label_ref (match_operand 3 "" ""))
15171 (pc)))
8bc527af
SB
15172 (clobber (reg:CCFP FPSR_REG))
15173 (clobber (reg:CCFP FLAGS_REG))]
27ac40e2
UB
15174 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15175 && TARGET_CMOVE
03598dea
JH
15176 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15177 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
15178 "#")
15179
eaa49b49 15180(define_insn "*fp_jcc_2_mixed"
3a3677ff
RH
15181 [(set (pc)
15182 (if_then_else (match_operator 0 "comparison_operator"
b5c82fa1
PB
15183 [(match_operand 1 "register_operand" "f,x")
15184 (match_operand 2 "nonimmediate_operand" "f,xm")])
3a3677ff
RH
15185 (pc)
15186 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
15187 (clobber (reg:CCFP FPSR_REG))
15188 (clobber (reg:CCFP FLAGS_REG))]
eaa49b49
RH
15189 "TARGET_MIX_SSE_I387
15190 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
15191 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15192 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
15193 "#")
15194
0644b628
JH
15195(define_insn "*fp_jcc_2_sse"
15196 [(set (pc)
15197 (if_then_else (match_operator 0 "comparison_operator"
eaa49b49
RH
15198 [(match_operand 1 "register_operand" "x")
15199 (match_operand 2 "nonimmediate_operand" "xm")])
0644b628
JH
15200 (pc)
15201 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
15202 (clobber (reg:CCFP FPSR_REG))
15203 (clobber (reg:CCFP FLAGS_REG))]
eaa49b49 15204 "TARGET_SSE_MATH
0644b628 15205 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
15206 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15207 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
15208 "#")
15209
eaa49b49 15210(define_insn "*fp_jcc_2_387"
0644b628
JH
15211 [(set (pc)
15212 (if_then_else (match_operator 0 "comparison_operator"
eaa49b49
RH
15213 [(match_operand 1 "register_operand" "f")
15214 (match_operand 2 "register_operand" "f")])
0644b628
JH
15215 (pc)
15216 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
15217 (clobber (reg:CCFP FPSR_REG))
15218 (clobber (reg:CCFP FLAGS_REG))]
27ac40e2
UB
15219 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15220 && TARGET_CMOVE
03598dea
JH
15221 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15222 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
15223 "#")
15224
eaa49b49 15225(define_insn "*fp_jcc_3_387"
3a3677ff 15226 [(set (pc)
b1cdafbb 15227 (if_then_else (match_operator 0 "comparison_operator"
3a3677ff
RH
15228 [(match_operand 1 "register_operand" "f")
15229 (match_operand 2 "nonimmediate_operand" "fm")])
15230 (label_ref (match_operand 3 "" ""))
15231 (pc)))
8bc527af
SB
15232 (clobber (reg:CCFP FPSR_REG))
15233 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
15234 (clobber (match_scratch:HI 4 "=a"))]
15235 "TARGET_80387
15236 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 15237 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb
JH
15238 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
15239 && SELECT_CC_MODE (GET_CODE (operands[0]),
03598dea
JH
15240 operands[1], operands[2]) == CCFPmode
15241 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
15242 "#")
15243
eaa49b49 15244(define_insn "*fp_jcc_4_387"
3a3677ff 15245 [(set (pc)
b1cdafbb 15246 (if_then_else (match_operator 0 "comparison_operator"
3a3677ff
RH
15247 [(match_operand 1 "register_operand" "f")
15248 (match_operand 2 "nonimmediate_operand" "fm")])
15249 (pc)
15250 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
15251 (clobber (reg:CCFP FPSR_REG))
15252 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
15253 (clobber (match_scratch:HI 4 "=a"))]
15254 "TARGET_80387
15255 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 15256 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb
JH
15257 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
15258 && SELECT_CC_MODE (GET_CODE (operands[0]),
03598dea
JH
15259 operands[1], operands[2]) == CCFPmode
15260 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
15261 "#")
15262
eaa49b49 15263(define_insn "*fp_jcc_5_387"
3a3677ff
RH
15264 [(set (pc)
15265 (if_then_else (match_operator 0 "comparison_operator"
15266 [(match_operand 1 "register_operand" "f")
15267 (match_operand 2 "register_operand" "f")])
15268 (label_ref (match_operand 3 "" ""))
15269 (pc)))
8bc527af
SB
15270 (clobber (reg:CCFP FPSR_REG))
15271 (clobber (reg:CCFP FLAGS_REG))
3a3677ff 15272 (clobber (match_scratch:HI 4 "=a"))]
27ac40e2 15273 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
15274 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15275 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
15276 "#")
15277
eaa49b49 15278(define_insn "*fp_jcc_6_387"
3a3677ff
RH
15279 [(set (pc)
15280 (if_then_else (match_operator 0 "comparison_operator"
15281 [(match_operand 1 "register_operand" "f")
15282 (match_operand 2 "register_operand" "f")])
15283 (pc)
15284 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
15285 (clobber (reg:CCFP FPSR_REG))
15286 (clobber (reg:CCFP FLAGS_REG))
3a3677ff 15287 (clobber (match_scratch:HI 4 "=a"))]
27ac40e2 15288 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
15289 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15290 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
15291 "#")
15292
eaa49b49 15293(define_insn "*fp_jcc_7_387"
45c8c47f
UB
15294 [(set (pc)
15295 (if_then_else (match_operator 0 "comparison_operator"
15296 [(match_operand 1 "register_operand" "f")
0edb82cb 15297 (match_operand 2 "const0_operand" "")])
45c8c47f
UB
15298 (label_ref (match_operand 3 "" ""))
15299 (pc)))
15300 (clobber (reg:CCFP FPSR_REG))
15301 (clobber (reg:CCFP FLAGS_REG))
15302 (clobber (match_scratch:HI 4 "=a"))]
27ac40e2 15303 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
17153653 15304 && GET_MODE (operands[1]) == GET_MODE (operands[2])
45c8c47f
UB
15305 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
15306 && SELECT_CC_MODE (GET_CODE (operands[0]),
15307 operands[1], operands[2]) == CCFPmode
15308 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15309 "#")
15310
0e8c2b0d 15311;; The order of operands in *fp_jcc_8_387 is forced by combine in
7c82106f
UB
15312;; simplify_comparison () function. Float operator is treated as RTX_OBJ
15313;; with a precedence over other operators and is always put in the first
15314;; place. Swap condition and operands to match ficom instruction.
15315
0e8c2b0d 15316(define_insn "*fp_jcc_8<mode>_387"
7c82106f
UB
15317 [(set (pc)
15318 (if_then_else (match_operator 0 "comparison_operator"
15319 [(match_operator 1 "float_operator"
0e8c2b0d 15320 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
7c82106f
UB
15321 (match_operand 3 "register_operand" "f,f")])
15322 (label_ref (match_operand 4 "" ""))
15323 (pc)))
15324 (clobber (reg:CCFP FPSR_REG))
15325 (clobber (reg:CCFP FLAGS_REG))
15326 (clobber (match_scratch:HI 5 "=a,a"))]
27ac40e2 15327 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
3debdc1e 15328 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
7c82106f
UB
15329 && GET_MODE (operands[1]) == GET_MODE (operands[3])
15330 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
15331 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
15332 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
15333 "#")
15334
3a3677ff
RH
15335(define_split
15336 [(set (pc)
15337 (if_then_else (match_operator 0 "comparison_operator"
15338 [(match_operand 1 "register_operand" "")
15339 (match_operand 2 "nonimmediate_operand" "")])
15340 (match_operand 3 "" "")
15341 (match_operand 4 "" "")))
8bc527af
SB
15342 (clobber (reg:CCFP FPSR_REG))
15343 (clobber (reg:CCFP FLAGS_REG))]
3a3677ff 15344 "reload_completed"
9e7adcb3 15345 [(const_int 0)]
3a3677ff 15346{
03598dea 15347 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
7c82106f 15348 operands[3], operands[4], NULL_RTX, NULL_RTX);
9e7adcb3 15349 DONE;
0f40f9f7 15350})
3a3677ff
RH
15351
15352(define_split
15353 [(set (pc)
15354 (if_then_else (match_operator 0 "comparison_operator"
15355 [(match_operand 1 "register_operand" "")
45c8c47f 15356 (match_operand 2 "general_operand" "")])
3a3677ff
RH
15357 (match_operand 3 "" "")
15358 (match_operand 4 "" "")))
8bc527af
SB
15359 (clobber (reg:CCFP FPSR_REG))
15360 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
15361 (clobber (match_scratch:HI 5 "=a"))]
15362 "reload_completed"
45c8c47f 15363 [(const_int 0)]
3a3677ff 15364{
03598dea 15365 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
7c82106f
UB
15366 operands[3], operands[4], operands[5], NULL_RTX);
15367 DONE;
15368})
15369
15370(define_split
15371 [(set (pc)
15372 (if_then_else (match_operator 0 "comparison_operator"
15373 [(match_operator 1 "float_operator"
0e8c2b0d 15374 [(match_operand:X87MODEI12 2 "memory_operand" "")])
7c82106f
UB
15375 (match_operand 3 "register_operand" "")])
15376 (match_operand 4 "" "")
15377 (match_operand 5 "" "")))
15378 (clobber (reg:CCFP FPSR_REG))
15379 (clobber (reg:CCFP FLAGS_REG))
15380 (clobber (match_scratch:HI 6 "=a"))]
15381 "reload_completed"
15382 [(const_int 0)]
15383{
15384 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
15385 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15386 operands[3], operands[7],
15387 operands[4], operands[5], operands[6], NULL_RTX);
15388 DONE;
15389})
15390
15391;; %%% Kill this when reload knows how to do it.
15392(define_split
15393 [(set (pc)
15394 (if_then_else (match_operator 0 "comparison_operator"
15395 [(match_operator 1 "float_operator"
0e8c2b0d 15396 [(match_operand:X87MODEI12 2 "register_operand" "")])
7c82106f
UB
15397 (match_operand 3 "register_operand" "")])
15398 (match_operand 4 "" "")
15399 (match_operand 5 "" "")))
15400 (clobber (reg:CCFP FPSR_REG))
15401 (clobber (reg:CCFP FLAGS_REG))
15402 (clobber (match_scratch:HI 6 "=a"))]
15403 "reload_completed"
15404 [(const_int 0)]
15405{
15406 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15407 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
15408 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15409 operands[3], operands[7],
15410 operands[4], operands[5], operands[6], operands[2]);
9e7adcb3 15411 DONE;
0f40f9f7 15412})
886c62d1
JVA
15413\f
15414;; Unconditional and other jump instructions
15415
15416(define_insn "jump"
15417 [(set (pc)
15418 (label_ref (match_operand 0 "" "")))]
15419 ""
0f40f9f7 15420 "jmp\t%l0"
c7375e61 15421 [(set_attr "type" "ibr")
efcc7037
JH
15422 (set (attr "length")
15423 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 15424 (const_int -126))
efcc7037 15425 (lt (minus (match_dup 0) (pc))
db1077d3 15426 (const_int 128)))
efcc7037
JH
15427 (const_int 2)
15428 (const_int 5)))
c7375e61 15429 (set_attr "modrm" "0")])
886c62d1 15430
14f73b5a 15431(define_expand "indirect_jump"
00188daa 15432 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
886c62d1 15433 ""
14f73b5a
JH
15434 "")
15435
15436(define_insn "*indirect_jump"
c4fe74e0
UB
15437 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
15438 ""
0f40f9f7 15439 "jmp\t%A0"
6ef67412
JH
15440 [(set_attr "type" "ibr")
15441 (set_attr "length_immediate" "0")])
4801403e 15442
90675921 15443(define_expand "tablejump"
00188daa 15444 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
90675921
RH
15445 (use (label_ref (match_operand 1 "" "")))])]
15446 ""
15447{
66edd3b4
RH
15448 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
15449 relative. Convert the relative address to an absolute address. */
90675921
RH
15450 if (flag_pic)
15451 {
66edd3b4
RH
15452 rtx op0, op1;
15453 enum rtx_code code;
15454
170bdaba
RS
15455 /* We can't use @GOTOFF for text labels on VxWorks;
15456 see gotoff_operand. */
15457 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
66edd3b4
RH
15458 {
15459 code = PLUS;
15460 op0 = operands[0];
15461 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
15462 }
b069de3b 15463 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
f88c65f7 15464 {
66edd3b4
RH
15465 code = PLUS;
15466 op0 = operands[0];
15467 op1 = pic_offset_table_rtx;
f88c65f7 15468 }
6eb791fc
JH
15469 else
15470 {
66edd3b4
RH
15471 code = MINUS;
15472 op0 = pic_offset_table_rtx;
15473 op1 = operands[0];
6eb791fc 15474 }
66edd3b4 15475
c16576e6 15476 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
66edd3b4 15477 OPTAB_DIRECT);
90675921 15478 }
0f40f9f7 15479})
2bb7a0f5 15480
90675921 15481(define_insn "*tablejump_1"
c4fe74e0 15482 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14f73b5a 15483 (use (label_ref (match_operand 1 "" "")))]
c4fe74e0 15484 ""
0f40f9f7 15485 "jmp\t%A0"
6ef67412
JH
15486 [(set_attr "type" "ibr")
15487 (set_attr "length_immediate" "0")])
e075ae69 15488\f
c50e5bc0
RH
15489;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
15490
15491(define_peephole2
42fabf21 15492 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
c50e5bc0
RH
15493 (set (match_operand:QI 1 "register_operand" "")
15494 (match_operator:QI 2 "ix86_comparison_operator"
42fabf21 15495 [(reg FLAGS_REG) (const_int 0)]))
c50e5bc0
RH
15496 (set (match_operand 3 "q_regs_operand" "")
15497 (zero_extend (match_dup 1)))]
646ded90
RH
15498 "(peep2_reg_dead_p (3, operands[1])
15499 || operands_match_p (operands[1], operands[3]))
c50e5bc0 15500 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
646ded90
RH
15501 [(set (match_dup 4) (match_dup 0))
15502 (set (strict_low_part (match_dup 5))
15503 (match_dup 2))]
15504{
ff680eb1 15505 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
1e2115dc 15506 operands[5] = gen_lowpart (QImode, operands[3]);
a8bac9ab 15507 ix86_expand_clear (operands[3]);
646ded90
RH
15508})
15509
15510;; Similar, but match zero_extendhisi2_and, which adds a clobber.
15511
15512(define_peephole2
42fabf21 15513 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
646ded90
RH
15514 (set (match_operand:QI 1 "register_operand" "")
15515 (match_operator:QI 2 "ix86_comparison_operator"
42fabf21 15516 [(reg FLAGS_REG) (const_int 0)]))
646ded90
RH
15517 (parallel [(set (match_operand 3 "q_regs_operand" "")
15518 (zero_extend (match_dup 1)))
8bc527af 15519 (clobber (reg:CC FLAGS_REG))])]
646ded90
RH
15520 "(peep2_reg_dead_p (3, operands[1])
15521 || operands_match_p (operands[1], operands[3]))
15522 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15523 [(set (match_dup 4) (match_dup 0))
c50e5bc0
RH
15524 (set (strict_low_part (match_dup 5))
15525 (match_dup 2))]
646ded90 15526{
ff680eb1 15527 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
1e2115dc 15528 operands[5] = gen_lowpart (QImode, operands[3]);
a8bac9ab 15529 ix86_expand_clear (operands[3]);
646ded90 15530})
e075ae69
RH
15531\f
15532;; Call instructions.
2bb7a0f5 15533
cbbf65e0
RH
15534;; The predicates normally associated with named expanders are not properly
15535;; checked for calls. This is a bug in the generic code, but it isn't that
15536;; easy to fix. Ignore it for now and be prepared to fix things up.
2bb7a0f5 15537
886c62d1
JVA
15538;; Call subroutine returning no value.
15539
2bb7a0f5 15540(define_expand "call_pop"
cbbf65e0
RH
15541 [(parallel [(call (match_operand:QI 0 "" "")
15542 (match_operand:SI 1 "" ""))
8bc527af
SB
15543 (set (reg:SI SP_REG)
15544 (plus:SI (reg:SI SP_REG)
cbbf65e0 15545 (match_operand:SI 3 "" "")))])]
1e07edd3 15546 "!TARGET_64BIT"
2bb7a0f5 15547{
4977bab6 15548 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
0e07aff3 15549 DONE;
0f40f9f7 15550})
2bb7a0f5 15551
94bb5d0c 15552(define_insn "*call_pop_0"
e1ff012c 15553 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
94bb5d0c 15554 (match_operand:SI 1 "" ""))
8bc527af 15555 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 15556 (match_operand:SI 2 "immediate_operand" "")))]
1e07edd3 15557 "!TARGET_64BIT"
94bb5d0c
RH
15558{
15559 if (SIBLING_CALL_P (insn))
0f40f9f7 15560 return "jmp\t%P0";
94bb5d0c 15561 else
0f40f9f7
ZW
15562 return "call\t%P0";
15563}
94bb5d0c 15564 [(set_attr "type" "call")])
6300f037 15565
cbbf65e0 15566(define_insn "*call_pop_1"
e1ff012c 15567 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
94bb5d0c 15568 (match_operand:SI 1 "" ""))
8bc527af 15569 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 15570 (match_operand:SI 2 "immediate_operand" "i")))]
1e07edd3 15571 "!TARGET_64BIT"
886c62d1 15572{
e1ff012c 15573 if (constant_call_address_operand (operands[0], Pmode))
94bb5d0c
RH
15574 {
15575 if (SIBLING_CALL_P (insn))
0f40f9f7 15576 return "jmp\t%P0";
94bb5d0c 15577 else
0f40f9f7 15578 return "call\t%P0";
94bb5d0c 15579 }
94bb5d0c 15580 if (SIBLING_CALL_P (insn))
0f40f9f7 15581 return "jmp\t%A0";
94bb5d0c 15582 else
0f40f9f7
ZW
15583 return "call\t%A0";
15584}
e075ae69 15585 [(set_attr "type" "call")])
886c62d1 15586
2bb7a0f5 15587(define_expand "call"
cbbf65e0 15588 [(call (match_operand:QI 0 "" "")
39d04363
JH
15589 (match_operand 1 "" ""))
15590 (use (match_operand 2 "" ""))]
2bb7a0f5 15591 ""
2bb7a0f5 15592{
4977bab6
ZW
15593 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15594 DONE;
15595})
15596
15597(define_expand "sibcall"
15598 [(call (match_operand:QI 0 "" "")
15599 (match_operand 1 "" ""))
15600 (use (match_operand 2 "" ""))]
15601 ""
15602{
15603 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
0e07aff3 15604 DONE;
0f40f9f7 15605})
2bb7a0f5 15606
94bb5d0c 15607(define_insn "*call_0"
32ee7d1d
JH
15608 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15609 (match_operand 1 "" ""))]
94bb5d0c 15610 ""
94bb5d0c
RH
15611{
15612 if (SIBLING_CALL_P (insn))
0f40f9f7 15613 return "jmp\t%P0";
94bb5d0c 15614 else
0f40f9f7
ZW
15615 return "call\t%P0";
15616}
94bb5d0c
RH
15617 [(set_attr "type" "call")])
15618
cbbf65e0 15619(define_insn "*call_1"
e1ff012c 15620 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
32ee7d1d 15621 (match_operand 1 "" ""))]
4977bab6 15622 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
32ee7d1d 15623{
e427abbf 15624 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
15625 return "call\t%P0";
15626 return "call\t%A0";
15627}
15628 [(set_attr "type" "call")])
15629
15630(define_insn "*sibcall_1"
15631 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15632 (match_operand 1 "" ""))]
15633 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15634{
e427abbf 15635 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
15636 return "jmp\t%P0";
15637 return "jmp\t%A0";
0f40f9f7 15638}
32ee7d1d
JH
15639 [(set_attr "type" "call")])
15640
15641(define_insn "*call_1_rex64"
15642 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15643 (match_operand 1 "" ""))]
dc4d7240
JH
15644 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15645 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
886c62d1 15646{
e427abbf 15647 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
15648 return "call\t%P0";
15649 return "call\t%A0";
0f40f9f7 15650}
e075ae69 15651 [(set_attr "type" "call")])
886c62d1 15652
924eabec
JH
15653(define_insn "*call_1_rex64_ms_sysv"
15654 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15655 (match_operand 1 "" ""))
15656 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
78168632
UB
15657 (clobber (reg:TI XMM6_REG))
15658 (clobber (reg:TI XMM7_REG))
15659 (clobber (reg:TI XMM8_REG))
15660 (clobber (reg:TI XMM9_REG))
15661 (clobber (reg:TI XMM10_REG))
15662 (clobber (reg:TI XMM11_REG))
15663 (clobber (reg:TI XMM12_REG))
15664 (clobber (reg:TI XMM13_REG))
15665 (clobber (reg:TI XMM14_REG))
15666 (clobber (reg:TI XMM15_REG))
924eabec
JH
15667 (clobber (reg:DI SI_REG))
15668 (clobber (reg:DI DI_REG))]
15669 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15670{
15671 if (constant_call_address_operand (operands[0], Pmode))
15672 return "call\t%P0";
15673 return "call\t%A0";
15674}
15675 [(set_attr "type" "call")])
15676
dc4d7240
JH
15677(define_insn "*call_1_rex64_large"
15678 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15679 (match_operand 1 "" ""))]
15680 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15681 "call\t%A0"
15682 [(set_attr "type" "call")])
15683
4977bab6
ZW
15684(define_insn "*sibcall_1_rex64"
15685 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15686 (match_operand 1 "" ""))]
15687 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15688 "jmp\t%P0"
15689 [(set_attr "type" "call")])
15690
15691(define_insn "*sibcall_1_rex64_v"
03c259ad 15692 [(call (mem:QI (reg:DI R11_REG))
4977bab6
ZW
15693 (match_operand 0 "" ""))]
15694 "SIBLING_CALL_P (insn) && TARGET_64BIT"
9ad5e54f 15695 "jmp\t{*%%}r11"
4977bab6
ZW
15696 [(set_attr "type" "call")])
15697
15698
886c62d1 15699;; Call subroutine, returning value in operand 0
886c62d1 15700
2bb7a0f5
RS
15701(define_expand "call_value_pop"
15702 [(parallel [(set (match_operand 0 "" "")
cbbf65e0
RH
15703 (call (match_operand:QI 1 "" "")
15704 (match_operand:SI 2 "" "")))
8bc527af
SB
15705 (set (reg:SI SP_REG)
15706 (plus:SI (reg:SI SP_REG)
cbbf65e0 15707 (match_operand:SI 4 "" "")))])]
1e07edd3 15708 "!TARGET_64BIT"
2bb7a0f5 15709{
0e07aff3 15710 ix86_expand_call (operands[0], operands[1], operands[2],
4977bab6 15711 operands[3], operands[4], 0);
0e07aff3 15712 DONE;
0f40f9f7 15713})
2bb7a0f5 15714
2bb7a0f5
RS
15715(define_expand "call_value"
15716 [(set (match_operand 0 "" "")
cbbf65e0 15717 (call (match_operand:QI 1 "" "")
39d04363
JH
15718 (match_operand:SI 2 "" "")))
15719 (use (match_operand:SI 3 "" ""))]
2bb7a0f5
RS
15720 ;; Operand 2 not used on the i386.
15721 ""
2bb7a0f5 15722{
4977bab6
ZW
15723 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15724 DONE;
15725})
15726
15727(define_expand "sibcall_value"
15728 [(set (match_operand 0 "" "")
15729 (call (match_operand:QI 1 "" "")
15730 (match_operand:SI 2 "" "")))
15731 (use (match_operand:SI 3 "" ""))]
15732 ;; Operand 2 not used on the i386.
15733 ""
15734{
15735 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
39d04363 15736 DONE;
0f40f9f7 15737})
2bb7a0f5 15738
b840bfb0
MM
15739;; Call subroutine returning any type.
15740
576182a3 15741(define_expand "untyped_call"
b840bfb0 15742 [(parallel [(call (match_operand 0 "" "")
576182a3 15743 (const_int 0))
b840bfb0 15744 (match_operand 1 "" "")
576182a3
TW
15745 (match_operand 2 "" "")])]
15746 ""
576182a3 15747{
b840bfb0 15748 int i;
576182a3 15749
d8b679b9
RK
15750 /* In order to give reg-stack an easier job in validating two
15751 coprocessor registers as containing a possible return value,
15752 simply pretend the untyped call returns a complex long double
435a61d3
L
15753 value.
15754
15755 We can't use SSE_REGPARM_MAX here since callee is unprototyped
15756 and should have the default ABI. */
74775c7a 15757
0e07aff3
RH
15758 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15759 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
7c800926 15760 operands[0], const0_rtx,
435a61d3 15761 GEN_INT ((TARGET_64BIT
51212b32 15762 ? (ix86_abi == SYSV_ABI
435a61d3
L
15763 ? X86_64_SSE_REGPARM_MAX
15764 : X64_SSE_REGPARM_MAX)
15765 : X86_32_SSE_REGPARM_MAX)
7c800926 15766 - 1),
4977bab6 15767 NULL, 0);
576182a3 15768
b840bfb0 15769 for (i = 0; i < XVECLEN (operands[2], 0); i++)
576182a3 15770 {
b840bfb0
MM
15771 rtx set = XVECEXP (operands[2], 0, i);
15772 emit_move_insn (SET_DEST (set), SET_SRC (set));
576182a3 15773 }
576182a3 15774
b840bfb0
MM
15775 /* The optimizer does not know that the call sets the function value
15776 registers we stored in the result block. We avoid problems by
15777 claiming that all hard registers are used and clobbered at this
15778 point. */
6fb5fa3c 15779 emit_insn (gen_blockage ());
576182a3
TW
15780
15781 DONE;
0f40f9f7 15782})
e075ae69
RH
15783\f
15784;; Prologue and epilogue instructions
576182a3 15785
b840bfb0
MM
15786;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15787;; all of memory. This blocks insns from being moved across this point.
15788
15789(define_insn "blockage"
6fb5fa3c
DB
15790 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15791 ""
15792 ""
15793 [(set_attr "length" "0")])
15794
b058b753
UB
15795;; Do not schedule instructions accessing memory across this point.
15796
15797(define_expand "memory_blockage"
15798 [(set (match_dup 0)
15799 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15800 ""
15801{
15802 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15803 MEM_VOLATILE_P (operands[0]) = 1;
15804})
15805
15806(define_insn "*memory_blockage"
15807 [(set (match_operand:BLK 0 "" "")
15808 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15809 ""
15810 ""
15811 [(set_attr "length" "0")])
15812
6fb5fa3c
DB
15813;; As USE insns aren't meaningful after reload, this is used instead
15814;; to prevent deleting instructions setting registers for PIC code
15815(define_insn "prologue_use"
15816 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
576182a3 15817 ""
90aec2cf 15818 ""
e075ae69 15819 [(set_attr "length" "0")])
576182a3 15820
886c62d1
JVA
15821;; Insn emitted into the body of a function to return from a function.
15822;; This is only done if the function's epilogue is known to be simple.
182a4620 15823;; See comments for ix86_can_use_return_insn_p in i386.c.
886c62d1 15824
5f3d14e3 15825(define_expand "return"
886c62d1 15826 [(return)]
5f3d14e3 15827 "ix86_can_use_return_insn_p ()"
9a7372d6 15828{
38173d38 15829 if (crtl->args.pops_args)
9a7372d6 15830 {
38173d38 15831 rtx popc = GEN_INT (crtl->args.pops_args);
9a7372d6
RH
15832 emit_jump_insn (gen_return_pop_internal (popc));
15833 DONE;
15834 }
0f40f9f7 15835})
5f3d14e3
SC
15836
15837(define_insn "return_internal"
15838 [(return)]
15839 "reload_completed"
90aec2cf 15840 "ret"
6ef67412 15841 [(set_attr "length" "1")
b6837b94 15842 (set_attr "atom_unit" "jeu")
6ef67412
JH
15843 (set_attr "length_immediate" "0")
15844 (set_attr "modrm" "0")])
5f3d14e3 15845
253c7a00
JH
15846;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15847;; instruction Athlon and K8 have.
15848
15849(define_insn "return_internal_long"
15850 [(return)
15851 (unspec [(const_int 0)] UNSPEC_REP)]
15852 "reload_completed"
9ad5e54f 15853 "rep\;ret"
a952487c 15854 [(set_attr "length" "2")
b6837b94 15855 (set_attr "atom_unit" "jeu")
253c7a00
JH
15856 (set_attr "length_immediate" "0")
15857 (set_attr "prefix_rep" "1")
15858 (set_attr "modrm" "0")])
15859
6cd96118
SC
15860(define_insn "return_pop_internal"
15861 [(return)
15862 (use (match_operand:SI 0 "const_int_operand" ""))]
15863 "reload_completed"
0f40f9f7 15864 "ret\t%0"
6ef67412 15865 [(set_attr "length" "3")
b6837b94 15866 (set_attr "atom_unit" "jeu")
6ef67412
JH
15867 (set_attr "length_immediate" "2")
15868 (set_attr "modrm" "0")])
6cd96118 15869
11837777
RH
15870(define_insn "return_indirect_internal"
15871 [(return)
15872 (use (match_operand:SI 0 "register_operand" "r"))]
15873 "reload_completed"
0f40f9f7 15874 "jmp\t%A0"
11837777
RH
15875 [(set_attr "type" "ibr")
15876 (set_attr "length_immediate" "0")])
15877
5f3d14e3
SC
15878(define_insn "nop"
15879 [(const_int 0)]
15880 ""
90aec2cf 15881 "nop"
e075ae69 15882 [(set_attr "length" "1")
6ef67412 15883 (set_attr "length_immediate" "0")
56bab446 15884 (set_attr "modrm" "0")])
5f3d14e3 15885
6a90d232 15886;; Pad to 16-byte boundary, max skip in op0. Used to avoid
9ccf9681
RH
15887;; branch prediction penalty for the third jump in a 16-byte
15888;; block on K8.
d2c49530 15889
6a90d232 15890(define_insn "pad"
d2c49530
JH
15891 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15892 ""
15893{
6a90d232
L
15894#ifdef ASM_OUTPUT_MAX_SKIP_PAD
15895 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
9ccf9681 15896#else
6262f66a
JH
15897 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15898 The align insn is used to avoid 3 jump instructions in the row to improve
6fc0bb99 15899 branch prediction and the benefits hardly outweigh the cost of extra 8
6262f66a 15900 nops on the average inserted by full alignment pseudo operation. */
d2c49530 15901#endif
9ccf9681 15902 return "";
d2c49530
JH
15903}
15904 [(set_attr "length" "16")])
15905
5f3d14e3 15906(define_expand "prologue"
00188daa 15907 [(const_int 0)]
5f3d14e3 15908 ""
e075ae69 15909 "ix86_expand_prologue (); DONE;")
5f3d14e3 15910
bd09bdeb 15911(define_insn "set_got"
69404d6f 15912 [(set (match_operand:SI 0 "register_operand" "=r")
c8c03509 15913 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
8bc527af 15914 (clobber (reg:CC FLAGS_REG))]
1e07edd3 15915 "!TARGET_64BIT"
7d072037
SH
15916 { return output_set_got (operands[0], NULL_RTX); }
15917 [(set_attr "type" "multi")
15918 (set_attr "length" "12")])
15919
15920(define_insn "set_got_labelled"
15921 [(set (match_operand:SI 0 "register_operand" "=r")
15922 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15923 UNSPEC_SET_GOT))
15924 (clobber (reg:CC FLAGS_REG))]
15925 "!TARGET_64BIT"
15926 { return output_set_got (operands[0], operands[1]); }
c8c03509
RH
15927 [(set_attr "type" "multi")
15928 (set_attr "length" "12")])
5f3d14e3 15929
7dcbf659
JH
15930(define_insn "set_got_rex64"
15931 [(set (match_operand:DI 0 "register_operand" "=r")
15932 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15933 "TARGET_64BIT"
9ad5e54f 15934 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
7dcbf659 15935 [(set_attr "type" "lea")
725fd454
JJ
15936 (set_attr "length_address" "4")
15937 (set_attr "mode" "DI")])
7dcbf659 15938
dc4d7240
JH
15939(define_insn "set_rip_rex64"
15940 [(set (match_operand:DI 0 "register_operand" "=r")
bef3c57b 15941 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
dc4d7240 15942 "TARGET_64BIT"
9ad5e54f 15943 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
dc4d7240 15944 [(set_attr "type" "lea")
725fd454
JJ
15945 (set_attr "length_address" "4")
15946 (set_attr "mode" "DI")])
dc4d7240
JH
15947
15948(define_insn "set_got_offset_rex64"
15949 [(set (match_operand:DI 0 "register_operand" "=r")
bef3c57b
UB
15950 (unspec:DI
15951 [(label_ref (match_operand 1 "" ""))]
15952 UNSPEC_SET_GOT_OFFSET))]
dc4d7240 15953 "TARGET_64BIT"
9ad5e54f 15954 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
dc4d7240 15955 [(set_attr "type" "imov")
725fd454
JJ
15956 (set_attr "length_immediate" "0")
15957 (set_attr "length_address" "8")
15958 (set_attr "mode" "DI")])
dc4d7240 15959
e075ae69 15960(define_expand "epilogue"
00188daa 15961 [(const_int 0)]
e075ae69 15962 ""
cbbf65e0
RH
15963 "ix86_expand_epilogue (1); DONE;")
15964
15965(define_expand "sibcall_epilogue"
00188daa 15966 [(const_int 0)]
cbbf65e0
RH
15967 ""
15968 "ix86_expand_epilogue (0); DONE;")
e075ae69 15969
1020a5ab 15970(define_expand "eh_return"
34dc173c 15971 [(use (match_operand 0 "register_operand" ""))]
1020a5ab 15972 ""
1020a5ab 15973{
34dc173c 15974 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
1020a5ab
RH
15975
15976 /* Tricky bit: we write the address of the handler to which we will
15977 be returning into someone else's stack frame, one word below the
15978 stack address we wish to restore. */
15979 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15980 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15981 tmp = gen_rtx_MEM (Pmode, tmp);
15982 emit_move_insn (tmp, ra);
15983
cd9c1ca8 15984 emit_jump_insn (gen_eh_return_internal ());
1020a5ab
RH
15985 emit_barrier ();
15986 DONE;
0f40f9f7 15987})
1020a5ab 15988
cd9c1ca8
RH
15989(define_insn_and_split "eh_return_internal"
15990 [(eh_return)]
c4fe74e0 15991 ""
1020a5ab 15992 "#"
cd9c1ca8 15993 "epilogue_completed"
00188daa 15994 [(const_int 0)]
1020a5ab
RH
15995 "ix86_expand_epilogue (2); DONE;")
15996
e075ae69 15997(define_insn "leave"
8bc527af
SB
15998 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15999 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
f2042df3 16000 (clobber (mem:BLK (scratch)))]
1e07edd3 16001 "!TARGET_64BIT"
e075ae69 16002 "leave"
4977bab6 16003 [(set_attr "type" "leave")])
8362f420
JH
16004
16005(define_insn "leave_rex64"
8bc527af
SB
16006 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
16007 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
f2042df3 16008 (clobber (mem:BLK (scratch)))]
8362f420
JH
16009 "TARGET_64BIT"
16010 "leave"
4977bab6 16011 [(set_attr "type" "leave")])
e075ae69
RH
16012\f
16013(define_expand "ffssi2"
8acfdd43 16014 [(parallel
6300f037 16015 [(set (match_operand:SI 0 "register_operand" "")
8acfdd43
RH
16016 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
16017 (clobber (match_scratch:SI 2 ""))
8bc527af 16018 (clobber (reg:CC FLAGS_REG))])]
e075ae69 16019 ""
08024fb5
UB
16020{
16021 if (TARGET_CMOVE)
16022 {
16023 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
16024 DONE;
16025 }
16026})
e075ae69 16027
08024fb5 16028(define_expand "ffs_cmove"
8acfdd43 16029 [(set (match_dup 2) (const_int -1))
08024fb5 16030 (parallel [(set (reg:CCZ FLAGS_REG)
3cdf0c62 16031 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
08024fb5 16032 (const_int 0)))
3cdf0c62 16033 (set (match_operand:SI 0 "register_operand" "")
08024fb5 16034 (ctz:SI (match_dup 1)))])
8acfdd43 16035 (set (match_dup 0) (if_then_else:SI
8bc527af 16036 (eq (reg:CCZ FLAGS_REG) (const_int 0))
8acfdd43
RH
16037 (match_dup 2)
16038 (match_dup 0)))
16039 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8bc527af 16040 (clobber (reg:CC FLAGS_REG))])]
08024fb5
UB
16041 "TARGET_CMOVE"
16042 "operands[2] = gen_reg_rtx (SImode);")
e0dc26ff 16043
8acfdd43 16044(define_insn_and_split "*ffs_no_cmove"
3cdf0c62 16045 [(set (match_operand:SI 0 "register_operand" "=r")
8acfdd43 16046 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
fa543fdd 16047 (clobber (match_scratch:SI 2 "=&q"))
8bc527af 16048 (clobber (reg:CC FLAGS_REG))]
08024fb5 16049 "!TARGET_CMOVE"
8acfdd43 16050 "#"
08024fb5
UB
16051 "&& reload_completed"
16052 [(parallel [(set (reg:CCZ FLAGS_REG)
16053 (compare:CCZ (match_dup 1) (const_int 0)))
8acfdd43
RH
16054 (set (match_dup 0) (ctz:SI (match_dup 1)))])
16055 (set (strict_low_part (match_dup 3))
8bc527af 16056 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
8acfdd43 16057 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
8bc527af 16058 (clobber (reg:CC FLAGS_REG))])
8acfdd43 16059 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
8bc527af 16060 (clobber (reg:CC FLAGS_REG))])
8acfdd43 16061 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8bc527af 16062 (clobber (reg:CC FLAGS_REG))])]
8acfdd43
RH
16063{
16064 operands[3] = gen_lowpart (QImode, operands[2]);
707e58b1 16065 ix86_expand_clear (operands[2]);
0f40f9f7 16066})
886c62d1 16067
8acfdd43 16068(define_insn "*ffssi_1"
8bc527af 16069 [(set (reg:CCZ FLAGS_REG)
8acfdd43 16070 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
16189740 16071 (const_int 0)))
e075ae69 16072 (set (match_operand:SI 0 "register_operand" "=r")
8acfdd43
RH
16073 (ctz:SI (match_dup 1)))]
16074 ""
16075 "bsf{l}\t{%1, %0|%0, %1}"
725fd454
JJ
16076 [(set_attr "type" "alu1")
16077 (set_attr "prefix_0f" "1")
16078 (set_attr "mode" "SI")])
8acfdd43 16079
d413e3cc 16080(define_expand "ffsdi2"
d413e3cc 16081 [(set (match_dup 2) (const_int -1))
42fabf21 16082 (parallel [(set (reg:CCZ FLAGS_REG)
3cdf0c62 16083 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
08024fb5 16084 (const_int 0)))
3cdf0c62 16085 (set (match_operand:DI 0 "register_operand" "")
08024fb5 16086 (ctz:DI (match_dup 1)))])
d413e3cc 16087 (set (match_dup 0) (if_then_else:DI
42fabf21 16088 (eq (reg:CCZ FLAGS_REG) (const_int 0))
d413e3cc
JJ
16089 (match_dup 2)
16090 (match_dup 0)))
16091 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
42fabf21 16092 (clobber (reg:CC FLAGS_REG))])]
08024fb5
UB
16093 "TARGET_64BIT"
16094 "operands[2] = gen_reg_rtx (DImode);")
d413e3cc
JJ
16095
16096(define_insn "*ffsdi_1"
42fabf21 16097 [(set (reg:CCZ FLAGS_REG)
d413e3cc
JJ
16098 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
16099 (const_int 0)))
16100 (set (match_operand:DI 0 "register_operand" "=r")
16101 (ctz:DI (match_dup 1)))]
16102 "TARGET_64BIT"
16103 "bsf{q}\t{%1, %0|%0, %1}"
725fd454
JJ
16104 [(set_attr "type" "alu1")
16105 (set_attr "prefix_0f" "1")
16106 (set_attr "mode" "DI")])
d413e3cc 16107
8acfdd43
RH
16108(define_insn "ctzsi2"
16109 [(set (match_operand:SI 0 "register_operand" "=r")
16110 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
8bc527af 16111 (clobber (reg:CC FLAGS_REG))]
e075ae69 16112 ""
0f40f9f7 16113 "bsf{l}\t{%1, %0|%0, %1}"
725fd454
JJ
16114 [(set_attr "type" "alu1")
16115 (set_attr "prefix_0f" "1")
16116 (set_attr "mode" "SI")])
e075ae69 16117
d413e3cc
JJ
16118(define_insn "ctzdi2"
16119 [(set (match_operand:DI 0 "register_operand" "=r")
16120 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
42fabf21 16121 (clobber (reg:CC FLAGS_REG))]
d413e3cc
JJ
16122 "TARGET_64BIT"
16123 "bsf{q}\t{%1, %0|%0, %1}"
725fd454
JJ
16124 [(set_attr "type" "alu1")
16125 (set_attr "prefix_0f" "1")
16126 (set_attr "mode" "DI")])
d413e3cc 16127
8acfdd43
RH
16128(define_expand "clzsi2"
16129 [(parallel
16130 [(set (match_operand:SI 0 "register_operand" "")
16131 (minus:SI (const_int 31)
16132 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
8bc527af 16133 (clobber (reg:CC FLAGS_REG))])
8acfdd43
RH
16134 (parallel
16135 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
8bc527af 16136 (clobber (reg:CC FLAGS_REG))])]
8acfdd43 16137 ""
21efb4d4
HJ
16138{
16139 if (TARGET_ABM)
16140 {
16141 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
16142 DONE;
16143 }
16144})
16145
16146(define_insn "clzsi2_abm"
16147 [(set (match_operand:SI 0 "register_operand" "=r")
a3d4a22b 16148 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
21efb4d4
HJ
16149 (clobber (reg:CC FLAGS_REG))]
16150 "TARGET_ABM"
16151 "lzcnt{l}\t{%1, %0|%0, %1}"
16152 [(set_attr "prefix_rep" "1")
16153 (set_attr "type" "bitmanip")
16154 (set_attr "mode" "SI")])
8acfdd43
RH
16155
16156(define_insn "*bsr"
16157 [(set (match_operand:SI 0 "register_operand" "=r")
16158 (minus:SI (const_int 31)
16159 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
8bc527af 16160 (clobber (reg:CC FLAGS_REG))]
8acfdd43
RH
16161 ""
16162 "bsr{l}\t{%1, %0|%0, %1}"
725fd454
JJ
16163 [(set_attr "type" "alu1")
16164 (set_attr "prefix_0f" "1")
21efb4d4
HJ
16165 (set_attr "mode" "SI")])
16166
a00ce5fe
UB
16167(define_insn "popcount<mode>2"
16168 [(set (match_operand:SWI248 0 "register_operand" "=r")
16169 (popcount:SWI248
16170 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
21efb4d4
HJ
16171 (clobber (reg:CC FLAGS_REG))]
16172 "TARGET_POPCNT"
a00ce5fe
UB
16173{
16174#if TARGET_MACHO
16175 return "popcnt\t{%1, %0|%0, %1}";
16176#else
16177 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16178#endif
16179}
21efb4d4
HJ
16180 [(set_attr "prefix_rep" "1")
16181 (set_attr "type" "bitmanip")
a00ce5fe 16182 (set_attr "mode" "<MODE>")])
21efb4d4 16183
a00ce5fe 16184(define_insn "*popcount<mode>2_cmp"
21efb4d4
HJ
16185 [(set (reg FLAGS_REG)
16186 (compare
a00ce5fe
UB
16187 (popcount:SWI248
16188 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
21efb4d4 16189 (const_int 0)))
a00ce5fe
UB
16190 (set (match_operand:SWI248 0 "register_operand" "=r")
16191 (popcount:SWI248 (match_dup 1)))]
21efb4d4 16192 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
a00ce5fe
UB
16193{
16194#if TARGET_MACHO
16195 return "popcnt\t{%1, %0|%0, %1}";
16196#else
16197 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16198#endif
16199}
21efb4d4
HJ
16200 [(set_attr "prefix_rep" "1")
16201 (set_attr "type" "bitmanip")
a00ce5fe 16202 (set_attr "mode" "<MODE>")])
21efb4d4
HJ
16203
16204(define_insn "*popcountsi2_cmp_zext"
16205 [(set (reg FLAGS_REG)
16206 (compare
16207 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
16208 (const_int 0)))
16209 (set (match_operand:DI 0 "register_operand" "=r")
16210 (zero_extend:DI(popcount:SI (match_dup 1))))]
16211 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
a00ce5fe
UB
16212{
16213#if TARGET_MACHO
16214 return "popcnt\t{%1, %0|%0, %1}";
16215#else
16216 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16217#endif
16218}
21efb4d4
HJ
16219 [(set_attr "prefix_rep" "1")
16220 (set_attr "type" "bitmanip")
16221 (set_attr "mode" "SI")])
d413e3cc 16222
2e6834d3
RH
16223(define_expand "bswapsi2"
16224 [(set (match_operand:SI 0 "register_operand" "")
16225 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
16226 ""
16227{
cabf85c3 16228 if (!(TARGET_BSWAP || TARGET_MOVBE))
2e6834d3
RH
16229 {
16230 rtx x = operands[0];
16231
16232 emit_move_insn (x, operands[1]);
16233 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16234 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
16235 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16236 DONE;
16237 }
16238})
16239
cabf85c3
L
16240(define_insn "*bswapsi_movbe"
16241 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
16242 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
16243 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16244 "@
16245 bswap\t%0
16246 movbe\t{%1, %0|%0, %1}
16247 movbe\t{%1, %0|%0, %1}"
16248 [(set_attr "type" "*,imov,imov")
16249 (set_attr "modrm" "*,1,1")
16250 (set_attr "prefix_0f" "1")
16251 (set_attr "prefix_extra" "*,1,1")
16252 (set_attr "length" "2,*,*")
16253 (set_attr "mode" "SI")])
16254
2e6834d3 16255(define_insn "*bswapsi_1"
6300f037 16256 [(set (match_operand:SI 0 "register_operand" "=r")
2e6834d3 16257 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
6300f037 16258 "TARGET_BSWAP"
2e6834d3 16259 "bswap\t%0"
6300f037
EC
16260 [(set_attr "prefix_0f" "1")
16261 (set_attr "length" "2")])
16262
fa681e39
UB
16263(define_insn "*bswaphi_lowpart_1"
16264 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
16265 (bswap:HI (match_dup 0)))
16266 (clobber (reg:CC FLAGS_REG))]
3debdc1e 16267 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
fa681e39
UB
16268 "@
16269 xchg{b}\t{%h0, %b0|%b0, %h0}
16270 rol{w}\t{$8, %0|%0, 8}"
16271 [(set_attr "length" "2,4")
16272 (set_attr "mode" "QI,HI")])
16273
2e6834d3 16274(define_insn "bswaphi_lowpart"
fa681e39
UB
16275 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
16276 (bswap:HI (match_dup 0)))
16277 (clobber (reg:CC FLAGS_REG))]
2e6834d3 16278 ""
fa681e39
UB
16279 "rol{w}\t{$8, %0|%0, 8}"
16280 [(set_attr "length" "4")
16281 (set_attr "mode" "HI")])
2e6834d3 16282
cabf85c3
L
16283(define_expand "bswapdi2"
16284 [(set (match_operand:DI 0 "register_operand" "")
16285 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
16286 "TARGET_64BIT"
16287 "")
16288
16289(define_insn "*bswapdi_movbe"
16290 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
16291 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
16292 "TARGET_64BIT && TARGET_MOVBE
16293 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16294 "@
16295 bswap\t%0
16296 movbe\t{%1, %0|%0, %1}
16297 movbe\t{%1, %0|%0, %1}"
16298 [(set_attr "type" "*,imov,imov")
16299 (set_attr "modrm" "*,1,1")
16300 (set_attr "prefix_0f" "1")
16301 (set_attr "prefix_extra" "*,1,1")
16302 (set_attr "length" "3,*,*")
16303 (set_attr "mode" "DI")])
16304
16305(define_insn "*bswapdi_1"
6300f037 16306 [(set (match_operand:DI 0 "register_operand" "=r")
2e6834d3
RH
16307 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
16308 "TARGET_64BIT"
6300f037
EC
16309 "bswap\t%0"
16310 [(set_attr "prefix_0f" "1")
16311 (set_attr "length" "3")])
16312
d413e3cc
JJ
16313(define_expand "clzdi2"
16314 [(parallel
16315 [(set (match_operand:DI 0 "register_operand" "")
16316 (minus:DI (const_int 63)
16317 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
42fabf21 16318 (clobber (reg:CC FLAGS_REG))])
d413e3cc
JJ
16319 (parallel
16320 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
42fabf21 16321 (clobber (reg:CC FLAGS_REG))])]
d413e3cc 16322 "TARGET_64BIT"
21efb4d4
HJ
16323{
16324 if (TARGET_ABM)
16325 {
16326 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
16327 DONE;
16328 }
16329})
16330
16331(define_insn "clzdi2_abm"
16332 [(set (match_operand:DI 0 "register_operand" "=r")
a3d4a22b 16333 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
21efb4d4
HJ
16334 (clobber (reg:CC FLAGS_REG))]
16335 "TARGET_64BIT && TARGET_ABM"
16336 "lzcnt{q}\t{%1, %0|%0, %1}"
16337 [(set_attr "prefix_rep" "1")
16338 (set_attr "type" "bitmanip")
16339 (set_attr "mode" "DI")])
d413e3cc
JJ
16340
16341(define_insn "*bsr_rex64"
16342 [(set (match_operand:DI 0 "register_operand" "=r")
16343 (minus:DI (const_int 63)
16344 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
42fabf21 16345 (clobber (reg:CC FLAGS_REG))]
d413e3cc
JJ
16346 "TARGET_64BIT"
16347 "bsr{q}\t{%1, %0|%0, %1}"
725fd454
JJ
16348 [(set_attr "type" "alu1")
16349 (set_attr "prefix_0f" "1")
21efb4d4
HJ
16350 (set_attr "mode" "DI")])
16351
21efb4d4
HJ
16352(define_expand "clzhi2"
16353 [(parallel
16354 [(set (match_operand:HI 0 "register_operand" "")
16355 (minus:HI (const_int 15)
16356 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
16357 (clobber (reg:CC FLAGS_REG))])
16358 (parallel
16359 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
16360 (clobber (reg:CC FLAGS_REG))])]
16361 ""
16362{
16363 if (TARGET_ABM)
16364 {
16365 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
16366 DONE;
16367 }
16368})
16369
16370(define_insn "clzhi2_abm"
16371 [(set (match_operand:HI 0 "register_operand" "=r")
a3d4a22b 16372 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
21efb4d4
HJ
16373 (clobber (reg:CC FLAGS_REG))]
16374 "TARGET_ABM"
16375 "lzcnt{w}\t{%1, %0|%0, %1}"
16376 [(set_attr "prefix_rep" "1")
16377 (set_attr "type" "bitmanip")
16378 (set_attr "mode" "HI")])
16379
16380(define_insn "*bsrhi"
16381 [(set (match_operand:HI 0 "register_operand" "=r")
16382 (minus:HI (const_int 15)
16383 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
16384 (clobber (reg:CC FLAGS_REG))]
16385 ""
16386 "bsr{w}\t{%1, %0|%0, %1}"
725fd454
JJ
16387 [(set_attr "type" "alu1")
16388 (set_attr "prefix_0f" "1")
21efb4d4
HJ
16389 (set_attr "mode" "HI")])
16390
0f7b6776
UB
16391(define_expand "paritydi2"
16392 [(set (match_operand:DI 0 "register_operand" "")
40cca4f9 16393 (parity:DI (match_operand:DI 1 "register_operand" "")))]
0f7b6776
UB
16394 "! TARGET_POPCNT"
16395{
16396 rtx scratch = gen_reg_rtx (QImode);
16397 rtx cond;
16398
16399 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
16400 NULL_RTX, operands[1]));
16401
16402 cond = gen_rtx_fmt_ee (ORDERED, QImode,
16403 gen_rtx_REG (CCmode, FLAGS_REG),
16404 const0_rtx);
16405 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16406
16407 if (TARGET_64BIT)
16408 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
16409 else
16410 {
16411 rtx tmp = gen_reg_rtx (SImode);
16412
16413 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
16414 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
16415 }
16416 DONE;
16417})
16418
16419(define_insn_and_split "paritydi2_cmp"
16420 [(set (reg:CC FLAGS_REG)
40cca4f9
UB
16421 (parity:CC (match_operand:DI 3 "register_operand" "0")))
16422 (clobber (match_scratch:DI 0 "=r"))
16423 (clobber (match_scratch:SI 1 "=&r"))
16424 (clobber (match_scratch:HI 2 "=Q"))]
0f7b6776
UB
16425 "! TARGET_POPCNT"
16426 "#"
16427 "&& reload_completed"
16428 [(parallel
16429 [(set (match_dup 1)
16430 (xor:SI (match_dup 1) (match_dup 4)))
16431 (clobber (reg:CC FLAGS_REG))])
16432 (parallel
16433 [(set (reg:CC FLAGS_REG)
16434 (parity:CC (match_dup 1)))
16435 (clobber (match_dup 1))
16436 (clobber (match_dup 2))])]
16437{
16438 operands[4] = gen_lowpart (SImode, operands[3]);
16439
40cca4f9 16440 if (TARGET_64BIT)
0f7b6776
UB
16441 {
16442 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
16443 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
16444 }
40cca4f9
UB
16445 else
16446 operands[1] = gen_highpart (SImode, operands[3]);
0f7b6776
UB
16447})
16448
16449(define_expand "paritysi2"
16450 [(set (match_operand:SI 0 "register_operand" "")
40cca4f9 16451 (parity:SI (match_operand:SI 1 "register_operand" "")))]
0f7b6776
UB
16452 "! TARGET_POPCNT"
16453{
16454 rtx scratch = gen_reg_rtx (QImode);
16455 rtx cond;
16456
16457 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
16458
16459 cond = gen_rtx_fmt_ee (ORDERED, QImode,
16460 gen_rtx_REG (CCmode, FLAGS_REG),
16461 const0_rtx);
16462 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16463
16464 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16465 DONE;
16466})
16467
16468(define_insn_and_split "paritysi2_cmp"
16469 [(set (reg:CC FLAGS_REG)
40cca4f9
UB
16470 (parity:CC (match_operand:SI 2 "register_operand" "0")))
16471 (clobber (match_scratch:SI 0 "=r"))
16472 (clobber (match_scratch:HI 1 "=&Q"))]
0f7b6776
UB
16473 "! TARGET_POPCNT"
16474 "#"
16475 "&& reload_completed"
16476 [(parallel
16477 [(set (match_dup 1)
16478 (xor:HI (match_dup 1) (match_dup 3)))
16479 (clobber (reg:CC FLAGS_REG))])
16480 (parallel
16481 [(set (reg:CC FLAGS_REG)
16482 (parity:CC (match_dup 1)))
16483 (clobber (match_dup 1))])]
16484{
16485 operands[3] = gen_lowpart (HImode, operands[2]);
16486
40cca4f9
UB
16487 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
16488 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
0f7b6776
UB
16489})
16490
16491(define_insn "*parityhi2_cmp"
16492 [(set (reg:CC FLAGS_REG)
16493 (parity:CC (match_operand:HI 1 "register_operand" "0")))
16494 (clobber (match_scratch:HI 0 "=Q"))]
16495 "! TARGET_POPCNT"
16496 "xor{b}\t{%h0, %b0|%b0, %h0}"
16497 [(set_attr "length" "2")
16498 (set_attr "mode" "HI")])
16499
16500(define_insn "*parityqi2_cmp"
16501 [(set (reg:CC FLAGS_REG)
16502 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
16503 "! TARGET_POPCNT"
16504 "test{b}\t%0, %0"
16505 [(set_attr "length" "2")
16506 (set_attr "mode" "QI")])
e075ae69 16507\f
f996902d
RH
16508;; Thread-local storage patterns for ELF.
16509;;
16510;; Note that these code sequences must appear exactly as shown
16511;; in order to allow linker relaxation.
16512
75d38379 16513(define_insn "*tls_global_dynamic_32_gnu"
f996902d
RH
16514 [(set (match_operand:SI 0 "register_operand" "=a")
16515 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16516 (match_operand:SI 2 "tls_symbolic_operand" "")
16517 (match_operand:SI 3 "call_insn_operand" "")]
16518 UNSPEC_TLS_GD))
16519 (clobber (match_scratch:SI 4 "=d"))
16520 (clobber (match_scratch:SI 5 "=c"))
8bc527af 16521 (clobber (reg:CC FLAGS_REG))]
75d38379 16522 "!TARGET_64BIT && TARGET_GNU_TLS"
f996902d
RH
16523 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
16524 [(set_attr "type" "multi")
16525 (set_attr "length" "12")])
16526
75d38379 16527(define_insn "*tls_global_dynamic_32_sun"
f996902d
RH
16528 [(set (match_operand:SI 0 "register_operand" "=a")
16529 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16530 (match_operand:SI 2 "tls_symbolic_operand" "")
16531 (match_operand:SI 3 "call_insn_operand" "")]
16532 UNSPEC_TLS_GD))
16533 (clobber (match_scratch:SI 4 "=d"))
16534 (clobber (match_scratch:SI 5 "=c"))
8bc527af 16535 (clobber (reg:CC FLAGS_REG))]
75d38379 16536 "!TARGET_64BIT && TARGET_SUN_TLS"
f996902d
RH
16537 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
16538 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
16539 [(set_attr "type" "multi")
16540 (set_attr "length" "14")])
16541
75d38379 16542(define_expand "tls_global_dynamic_32"
f996902d
RH
16543 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16544 (unspec:SI
16545 [(match_dup 2)
16546 (match_operand:SI 1 "tls_symbolic_operand" "")
16547 (match_dup 3)]
16548 UNSPEC_TLS_GD))
16549 (clobber (match_scratch:SI 4 ""))
16550 (clobber (match_scratch:SI 5 ""))
8bc527af 16551 (clobber (reg:CC FLAGS_REG))])]
f996902d
RH
16552 ""
16553{
dce81a1a
JJ
16554 if (flag_pic)
16555 operands[2] = pic_offset_table_rtx;
16556 else
16557 {
16558 operands[2] = gen_reg_rtx (Pmode);
16559 emit_insn (gen_set_got (operands[2]));
16560 }
5bf5a10b
AO
16561 if (TARGET_GNU2_TLS)
16562 {
16563 emit_insn (gen_tls_dynamic_gnu2_32
16564 (operands[0], operands[1], operands[2]));
16565 DONE;
16566 }
f996902d
RH
16567 operands[3] = ix86_tls_get_addr ();
16568})
16569
75d38379
JJ
16570(define_insn "*tls_global_dynamic_64"
16571 [(set (match_operand:DI 0 "register_operand" "=a")
e347ff9e
AO
16572 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16573 (match_operand:DI 3 "" "")))
75d38379
JJ
16574 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16575 UNSPEC_TLS_GD)]
16576 "TARGET_64BIT"
9ad5e54f 16577 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
75d38379
JJ
16578 [(set_attr "type" "multi")
16579 (set_attr "length" "16")])
16580
16581(define_expand "tls_global_dynamic_64"
16582 [(parallel [(set (match_operand:DI 0 "register_operand" "")
e347ff9e 16583 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
75d38379
JJ
16584 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16585 UNSPEC_TLS_GD)])]
16586 ""
16587{
5bf5a10b
AO
16588 if (TARGET_GNU2_TLS)
16589 {
16590 emit_insn (gen_tls_dynamic_gnu2_64
16591 (operands[0], operands[1]));
16592 DONE;
16593 }
75d38379
JJ
16594 operands[2] = ix86_tls_get_addr ();
16595})
16596
16597(define_insn "*tls_local_dynamic_base_32_gnu"
f996902d
RH
16598 [(set (match_operand:SI 0 "register_operand" "=a")
16599 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16600 (match_operand:SI 2 "call_insn_operand" "")]
16601 UNSPEC_TLS_LD_BASE))
16602 (clobber (match_scratch:SI 3 "=d"))
16603 (clobber (match_scratch:SI 4 "=c"))
8bc527af 16604 (clobber (reg:CC FLAGS_REG))]
75d38379 16605 "!TARGET_64BIT && TARGET_GNU_TLS"
f996902d
RH
16606 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16607 [(set_attr "type" "multi")
16608 (set_attr "length" "11")])
16609
75d38379 16610(define_insn "*tls_local_dynamic_base_32_sun"
f996902d
RH
16611 [(set (match_operand:SI 0 "register_operand" "=a")
16612 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16613 (match_operand:SI 2 "call_insn_operand" "")]
16614 UNSPEC_TLS_LD_BASE))
16615 (clobber (match_scratch:SI 3 "=d"))
16616 (clobber (match_scratch:SI 4 "=c"))
8bc527af 16617 (clobber (reg:CC FLAGS_REG))]
75d38379 16618 "!TARGET_64BIT && TARGET_SUN_TLS"
f996902d
RH
16619 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16620 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16621 [(set_attr "type" "multi")
16622 (set_attr "length" "13")])
16623
75d38379 16624(define_expand "tls_local_dynamic_base_32"
f996902d
RH
16625 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16626 (unspec:SI [(match_dup 1) (match_dup 2)]
16627 UNSPEC_TLS_LD_BASE))
16628 (clobber (match_scratch:SI 3 ""))
16629 (clobber (match_scratch:SI 4 ""))
8bc527af 16630 (clobber (reg:CC FLAGS_REG))])]
f996902d
RH
16631 ""
16632{
dce81a1a 16633 if (flag_pic)
9785f1d9 16634 operands[1] = pic_offset_table_rtx;
dce81a1a
JJ
16635 else
16636 {
9785f1d9
JJ
16637 operands[1] = gen_reg_rtx (Pmode);
16638 emit_insn (gen_set_got (operands[1]));
dce81a1a 16639 }
5bf5a10b
AO
16640 if (TARGET_GNU2_TLS)
16641 {
16642 emit_insn (gen_tls_dynamic_gnu2_32
16643 (operands[0], ix86_tls_module_base (), operands[1]));
16644 DONE;
16645 }
f996902d
RH
16646 operands[2] = ix86_tls_get_addr ();
16647})
16648
75d38379
JJ
16649(define_insn "*tls_local_dynamic_base_64"
16650 [(set (match_operand:DI 0 "register_operand" "=a")
e347ff9e
AO
16651 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16652 (match_operand:DI 2 "" "")))
75d38379
JJ
16653 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16654 "TARGET_64BIT"
9ad5e54f 16655 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
75d38379
JJ
16656 [(set_attr "type" "multi")
16657 (set_attr "length" "12")])
16658
16659(define_expand "tls_local_dynamic_base_64"
16660 [(parallel [(set (match_operand:DI 0 "register_operand" "")
e347ff9e 16661 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
75d38379
JJ
16662 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16663 ""
16664{
5bf5a10b
AO
16665 if (TARGET_GNU2_TLS)
16666 {
16667 emit_insn (gen_tls_dynamic_gnu2_64
16668 (operands[0], ix86_tls_module_base ()));
16669 DONE;
16670 }
75d38379
JJ
16671 operands[1] = ix86_tls_get_addr ();
16672})
16673
f996902d
RH
16674;; Local dynamic of a single variable is a lose. Show combine how
16675;; to convert that back to global dynamic.
16676
75d38379 16677(define_insn_and_split "*tls_local_dynamic_32_once"
f996902d
RH
16678 [(set (match_operand:SI 0 "register_operand" "=a")
16679 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16680 (match_operand:SI 2 "call_insn_operand" "")]
16681 UNSPEC_TLS_LD_BASE)
16682 (const:SI (unspec:SI
16683 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16684 UNSPEC_DTPOFF))))
16685 (clobber (match_scratch:SI 4 "=d"))
16686 (clobber (match_scratch:SI 5 "=c"))
8bc527af 16687 (clobber (reg:CC FLAGS_REG))]
f996902d
RH
16688 ""
16689 "#"
16690 ""
16691 [(parallel [(set (match_dup 0)
16692 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16693 UNSPEC_TLS_GD))
16694 (clobber (match_dup 4))
16695 (clobber (match_dup 5))
8bc527af 16696 (clobber (reg:CC FLAGS_REG))])]
f996902d 16697 "")
74dc3e94
RH
16698
16699;; Load and add the thread base pointer from %gs:0.
16700
16701(define_insn "*load_tp_si"
16702 [(set (match_operand:SI 0 "register_operand" "=r")
16703 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16704 "!TARGET_64BIT"
9ad5e54f 16705 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
74dc3e94
RH
16706 [(set_attr "type" "imov")
16707 (set_attr "modrm" "0")
16708 (set_attr "length" "7")
16709 (set_attr "memory" "load")
16710 (set_attr "imm_disp" "false")])
16711
16712(define_insn "*add_tp_si"
16713 [(set (match_operand:SI 0 "register_operand" "=r")
16714 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16715 (match_operand:SI 1 "register_operand" "0")))
8bc527af 16716 (clobber (reg:CC FLAGS_REG))]
74dc3e94 16717 "!TARGET_64BIT"
9ad5e54f 16718 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
74dc3e94
RH
16719 [(set_attr "type" "alu")
16720 (set_attr "modrm" "0")
16721 (set_attr "length" "7")
16722 (set_attr "memory" "load")
16723 (set_attr "imm_disp" "false")])
16724
16725(define_insn "*load_tp_di"
16726 [(set (match_operand:DI 0 "register_operand" "=r")
16727 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16728 "TARGET_64BIT"
9ad5e54f 16729 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
74dc3e94
RH
16730 [(set_attr "type" "imov")
16731 (set_attr "modrm" "0")
16732 (set_attr "length" "7")
16733 (set_attr "memory" "load")
16734 (set_attr "imm_disp" "false")])
16735
16736(define_insn "*add_tp_di"
16737 [(set (match_operand:DI 0 "register_operand" "=r")
16738 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16739 (match_operand:DI 1 "register_operand" "0")))
8bc527af 16740 (clobber (reg:CC FLAGS_REG))]
74dc3e94 16741 "TARGET_64BIT"
9ad5e54f 16742 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
74dc3e94
RH
16743 [(set_attr "type" "alu")
16744 (set_attr "modrm" "0")
16745 (set_attr "length" "7")
16746 (set_attr "memory" "load")
16747 (set_attr "imm_disp" "false")])
5bf5a10b
AO
16748
16749;; GNU2 TLS patterns can be split.
16750
16751(define_expand "tls_dynamic_gnu2_32"
16752 [(set (match_dup 3)
16753 (plus:SI (match_operand:SI 2 "register_operand" "")
16754 (const:SI
16755 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16756 UNSPEC_TLSDESC))))
16757 (parallel
16758 [(set (match_operand:SI 0 "register_operand" "")
16759 (unspec:SI [(match_dup 1) (match_dup 3)
16760 (match_dup 2) (reg:SI SP_REG)]
16761 UNSPEC_TLSDESC))
16762 (clobber (reg:CC FLAGS_REG))])]
16763 "!TARGET_64BIT && TARGET_GNU2_TLS"
16764{
b3a13419 16765 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
5bf5a10b
AO
16766 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16767})
16768
16769(define_insn "*tls_dynamic_lea_32"
16770 [(set (match_operand:SI 0 "register_operand" "=r")
16771 (plus:SI (match_operand:SI 1 "register_operand" "b")
16772 (const:SI
16773 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16774 UNSPEC_TLSDESC))))]
16775 "!TARGET_64BIT && TARGET_GNU2_TLS"
16776 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16777 [(set_attr "type" "lea")
16778 (set_attr "mode" "SI")
16779 (set_attr "length" "6")
16780 (set_attr "length_address" "4")])
16781
16782(define_insn "*tls_dynamic_call_32"
16783 [(set (match_operand:SI 0 "register_operand" "=a")
16784 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16785 (match_operand:SI 2 "register_operand" "0")
16786 ;; we have to make sure %ebx still points to the GOT
16787 (match_operand:SI 3 "register_operand" "b")
16788 (reg:SI SP_REG)]
16789 UNSPEC_TLSDESC))
16790 (clobber (reg:CC FLAGS_REG))]
16791 "!TARGET_64BIT && TARGET_GNU2_TLS"
16792 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16793 [(set_attr "type" "call")
16794 (set_attr "length" "2")
16795 (set_attr "length_address" "0")])
16796
16797(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16798 [(set (match_operand:SI 0 "register_operand" "=&a")
16799 (plus:SI
31ebc801
AO
16800 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16801 (match_operand:SI 4 "" "")
16802 (match_operand:SI 2 "register_operand" "b")
16803 (reg:SI SP_REG)]
16804 UNSPEC_TLSDESC)
5bf5a10b
AO
16805 (const:SI (unspec:SI
16806 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16807 UNSPEC_DTPOFF))))
16808 (clobber (reg:CC FLAGS_REG))]
16809 "!TARGET_64BIT && TARGET_GNU2_TLS"
16810 "#"
16811 ""
31ebc801 16812 [(set (match_dup 0) (match_dup 5))]
5bf5a10b 16813{
b3a13419 16814 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
5bf5a10b
AO
16815 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16816})
16817
16818(define_expand "tls_dynamic_gnu2_64"
16819 [(set (match_dup 2)
16820 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16821 UNSPEC_TLSDESC))
16822 (parallel
16823 [(set (match_operand:DI 0 "register_operand" "")
16824 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16825 UNSPEC_TLSDESC))
16826 (clobber (reg:CC FLAGS_REG))])]
16827 "TARGET_64BIT && TARGET_GNU2_TLS"
16828{
b3a13419 16829 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
5bf5a10b
AO
16830 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16831})
16832
16833(define_insn "*tls_dynamic_lea_64"
16834 [(set (match_operand:DI 0 "register_operand" "=r")
16835 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16836 UNSPEC_TLSDESC))]
16837 "TARGET_64BIT && TARGET_GNU2_TLS"
9ad5e54f 16838 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
5bf5a10b
AO
16839 [(set_attr "type" "lea")
16840 (set_attr "mode" "DI")
16841 (set_attr "length" "7")
16842 (set_attr "length_address" "4")])
16843
16844(define_insn "*tls_dynamic_call_64"
16845 [(set (match_operand:DI 0 "register_operand" "=a")
16846 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16847 (match_operand:DI 2 "register_operand" "0")
16848 (reg:DI SP_REG)]
16849 UNSPEC_TLSDESC))
16850 (clobber (reg:CC FLAGS_REG))]
16851 "TARGET_64BIT && TARGET_GNU2_TLS"
16852 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16853 [(set_attr "type" "call")
16854 (set_attr "length" "2")
16855 (set_attr "length_address" "0")])
16856
16857(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16858 [(set (match_operand:DI 0 "register_operand" "=&a")
16859 (plus:DI
31ebc801
AO
16860 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16861 (match_operand:DI 3 "" "")
16862 (reg:DI SP_REG)]
16863 UNSPEC_TLSDESC)
5bf5a10b
AO
16864 (const:DI (unspec:DI
16865 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16866 UNSPEC_DTPOFF))))
16867 (clobber (reg:CC FLAGS_REG))]
16868 "TARGET_64BIT && TARGET_GNU2_TLS"
16869 "#"
16870 ""
31ebc801 16871 [(set (match_dup 0) (match_dup 4))]
5bf5a10b 16872{
b3a13419 16873 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
5bf5a10b
AO
16874 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16875})
16876
16877;;
f996902d 16878\f
e075ae69
RH
16879;; These patterns match the binary 387 instructions for addM3, subM3,
16880;; mulM3 and divM3. There are three patterns for each of DFmode and
16881;; SFmode. The first is the normal insn, the second the same insn but
16882;; with one operand a conversion, and the third the same insn but with
16883;; the other operand a conversion. The conversion may be SFmode or
16884;; SImode if the target mode DFmode, but only SImode if the target mode
16885;; is SFmode.
16886
caa6ec8d
JH
16887;; Gcc is slightly more smart about handling normal two address instructions
16888;; so use special patterns for add and mull.
965f5423 16889
95879c72
L
16890(define_insn "*fop_<mode>_comm_mixed_avx"
16891 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16892 (match_operator:MODEF 3 "binary_fp_operator"
16893 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16894 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16895 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16896 && COMMUTATIVE_ARITH_P (operands[3])
16897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16898 "* return output_387_binary_op (insn, operands);"
16899 [(set (attr "type")
16900 (if_then_else (eq_attr "alternative" "1")
16901 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16902 (const_string "ssemul")
16903 (const_string "sseadd"))
16904 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16905 (const_string "fmul")
16906 (const_string "fop"))))
16907 (set_attr "prefix" "orig,maybe_vex")
16908 (set_attr "mode" "<MODE>")])
16909
ca3a2165
UB
16910(define_insn "*fop_<mode>_comm_mixed"
16911 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16912 (match_operator:MODEF 3 "binary_fp_operator"
16913 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16914 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16915 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
ec8e098d 16916 && COMMUTATIVE_ARITH_P (operands[3])
7656aee4 16917 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
caa6ec8d 16918 "* return output_387_binary_op (insn, operands);"
6300f037 16919 [(set (attr "type")
1deaa899 16920 (if_then_else (eq_attr "alternative" "1")
ca3a2165 16921 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
3d34cd91
JH
16922 (const_string "ssemul")
16923 (const_string "sseadd"))
ca3a2165 16924 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
1deaa899
JH
16925 (const_string "fmul")
16926 (const_string "fop"))))
ca3a2165 16927 (set_attr "mode" "<MODE>")])
1deaa899 16928
95879c72
L
16929(define_insn "*fop_<mode>_comm_avx"
16930 [(set (match_operand:MODEF 0 "register_operand" "=x")
16931 (match_operator:MODEF 3 "binary_fp_operator"
16932 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16933 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16934 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16935 && COMMUTATIVE_ARITH_P (operands[3])
16936 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16937 "* return output_387_binary_op (insn, operands);"
16938 [(set (attr "type")
16939 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16940 (const_string "ssemul")
16941 (const_string "sseadd")))
16942 (set_attr "prefix" "vex")
16943 (set_attr "mode" "<MODE>")])
16944
ca3a2165
UB
16945(define_insn "*fop_<mode>_comm_sse"
16946 [(set (match_operand:MODEF 0 "register_operand" "=x")
16947 (match_operator:MODEF 3 "binary_fp_operator"
16948 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16949 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16950 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
cfa185b8 16951 && COMMUTATIVE_ARITH_P (operands[3])
7656aee4 16952 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
1deaa899 16953 "* return output_387_binary_op (insn, operands);"
6300f037 16954 [(set (attr "type")
ca3a2165 16955 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
3d34cd91
JH
16956 (const_string "ssemul")
16957 (const_string "sseadd")))
ca3a2165 16958 (set_attr "mode" "<MODE>")])
caa6ec8d 16959
ca3a2165
UB
16960(define_insn "*fop_<mode>_comm_i387"
16961 [(set (match_operand:MODEF 0 "register_operand" "=f")
16962 (match_operator:MODEF 3 "binary_fp_operator"
16963 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16964 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
8ce94e44 16965 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
ec8e098d 16966 && COMMUTATIVE_ARITH_P (operands[3])
7656aee4 16967 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
965f5423 16968 "* return output_387_binary_op (insn, operands);"
6300f037 16969 [(set (attr "type")
ca3a2165 16970 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
965f5423
JH
16971 (const_string "fmul")
16972 (const_string "fop")))
ca3a2165 16973 (set_attr "mode" "<MODE>")])
965f5423 16974
95879c72
L
16975(define_insn "*fop_<mode>_1_mixed_avx"
16976 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16977 (match_operator:MODEF 3 "binary_fp_operator"
16978 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16979 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16980 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16981 && !COMMUTATIVE_ARITH_P (operands[3])
16982 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16983 "* return output_387_binary_op (insn, operands);"
16984 [(set (attr "type")
16985 (cond [(and (eq_attr "alternative" "2")
16986 (match_operand:MODEF 3 "mult_operator" ""))
16987 (const_string "ssemul")
16988 (and (eq_attr "alternative" "2")
16989 (match_operand:MODEF 3 "div_operator" ""))
16990 (const_string "ssediv")
16991 (eq_attr "alternative" "2")
16992 (const_string "sseadd")
16993 (match_operand:MODEF 3 "mult_operator" "")
16994 (const_string "fmul")
16995 (match_operand:MODEF 3 "div_operator" "")
16996 (const_string "fdiv")
16997 ]
16998 (const_string "fop")))
16999 (set_attr "prefix" "orig,orig,maybe_vex")
17000 (set_attr "mode" "<MODE>")])
17001
ca3a2165
UB
17002(define_insn "*fop_<mode>_1_mixed"
17003 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
17004 (match_operator:MODEF 3 "binary_fp_operator"
17005 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
17006 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
17007 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
ec8e098d 17008 && !COMMUTATIVE_ARITH_P (operands[3])
7656aee4 17009 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
e075ae69 17010 "* return output_387_binary_op (insn, operands);"
6300f037 17011 [(set (attr "type")
3d34cd91 17012 (cond [(and (eq_attr "alternative" "2")
ca3a2165 17013 (match_operand:MODEF 3 "mult_operator" ""))
3d34cd91
JH
17014 (const_string "ssemul")
17015 (and (eq_attr "alternative" "2")
ca3a2165 17016 (match_operand:MODEF 3 "div_operator" ""))
3d34cd91
JH
17017 (const_string "ssediv")
17018 (eq_attr "alternative" "2")
17019 (const_string "sseadd")
ca3a2165 17020 (match_operand:MODEF 3 "mult_operator" "")
e075ae69 17021 (const_string "fmul")
ca3a2165 17022 (match_operand:MODEF 3 "div_operator" "")
e075ae69
RH
17023 (const_string "fdiv")
17024 ]
6ef67412 17025 (const_string "fop")))
ca3a2165 17026 (set_attr "mode" "<MODE>")])
e075ae69 17027
6b889d89
UB
17028(define_insn "*rcpsf2_sse"
17029 [(set (match_operand:SF 0 "register_operand" "=x")
17030 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17031 UNSPEC_RCP))]
17032 "TARGET_SSE_MATH"
95879c72 17033 "%vrcpss\t{%1, %d0|%d0, %1}"
6b889d89 17034 [(set_attr "type" "sse")
b6837b94 17035 (set_attr "atom_sse_attr" "rcp")
95879c72 17036 (set_attr "prefix" "maybe_vex")
6b889d89
UB
17037 (set_attr "mode" "SF")])
17038
95879c72
L
17039(define_insn "*fop_<mode>_1_avx"
17040 [(set (match_operand:MODEF 0 "register_operand" "=x")
17041 (match_operator:MODEF 3 "binary_fp_operator"
17042 [(match_operand:MODEF 1 "register_operand" "x")
17043 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
17044 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17045 && !COMMUTATIVE_ARITH_P (operands[3])"
17046 "* return output_387_binary_op (insn, operands);"
17047 [(set (attr "type")
17048 (cond [(match_operand:MODEF 3 "mult_operator" "")
17049 (const_string "ssemul")
17050 (match_operand:MODEF 3 "div_operator" "")
17051 (const_string "ssediv")
17052 ]
17053 (const_string "sseadd")))
17054 (set_attr "prefix" "vex")
17055 (set_attr "mode" "<MODE>")])
17056
ca3a2165
UB
17057(define_insn "*fop_<mode>_1_sse"
17058 [(set (match_operand:MODEF 0 "register_operand" "=x")
17059 (match_operator:MODEF 3 "binary_fp_operator"
17060 [(match_operand:MODEF 1 "register_operand" "0")
17061 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
17062 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
ec8e098d 17063 && !COMMUTATIVE_ARITH_P (operands[3])"
1deaa899 17064 "* return output_387_binary_op (insn, operands);"
6300f037 17065 [(set (attr "type")
ca3a2165 17066 (cond [(match_operand:MODEF 3 "mult_operator" "")
3d34cd91 17067 (const_string "ssemul")
ca3a2165 17068 (match_operand:MODEF 3 "div_operator" "")
3d34cd91
JH
17069 (const_string "ssediv")
17070 ]
17071 (const_string "sseadd")))
ca3a2165 17072 (set_attr "mode" "<MODE>")])
1deaa899 17073
9e4ae64b 17074;; This pattern is not fully shadowed by the pattern above.
ca3a2165
UB
17075(define_insn "*fop_<mode>_1_i387"
17076 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17077 (match_operator:MODEF 3 "binary_fp_operator"
17078 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
17079 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
8ce94e44
JM
17080 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
17081 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
cfa185b8 17082 && !COMMUTATIVE_ARITH_P (operands[3])
7656aee4 17083 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
cfa185b8 17084 "* return output_387_binary_op (insn, operands);"
6300f037 17085 [(set (attr "type")
ca3a2165 17086 (cond [(match_operand:MODEF 3 "mult_operator" "")
cfa185b8 17087 (const_string "fmul")
ca3a2165 17088 (match_operand:MODEF 3 "div_operator" "")
cfa185b8
UB
17089 (const_string "fdiv")
17090 ]
17091 (const_string "fop")))
0e8c2b0d 17092 (set_attr "mode" "<MODE>")])
e075ae69 17093
1deaa899 17094;; ??? Add SSE splitters for these!
ca3a2165
UB
17095(define_insn "*fop_<MODEF:mode>_2_i387"
17096 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17097 (match_operator:MODEF 3 "binary_fp_operator"
17098 [(float:MODEF
17099 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17100 (match_operand:MODEF 2 "register_operand" "0,0")]))]
8ce94e44
JM
17101 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17102 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
3debdc1e 17103 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
e075ae69 17104 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
6300f037 17105 [(set (attr "type")
ca3a2165 17106 (cond [(match_operand:MODEF 3 "mult_operator" "")
e075ae69 17107 (const_string "fmul")
ca3a2165 17108 (match_operand:MODEF 3 "div_operator" "")
e075ae69
RH
17109 (const_string "fdiv")
17110 ]
17111 (const_string "fop")))
17112 (set_attr "fp_int_src" "true")
ca3a2165
UB
17113 (set_attr "mode" "<X87MODEI12:MODE>")])
17114
17115(define_insn "*fop_<MODEF:mode>_3_i387"
17116 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17117 (match_operator:MODEF 3 "binary_fp_operator"
17118 [(match_operand:MODEF 1 "register_operand" "0,0")
17119 (float:MODEF
17120 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
8ce94e44
JM
17121 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17122 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
3debdc1e 17123 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
e075ae69 17124 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
6300f037 17125 [(set (attr "type")
ca3a2165 17126 (cond [(match_operand:MODEF 3 "mult_operator" "")
e075ae69 17127 (const_string "fmul")
ca3a2165 17128 (match_operand:MODEF 3 "div_operator" "")
e075ae69
RH
17129 (const_string "fdiv")
17130 ]
17131 (const_string "fop")))
17132 (set_attr "fp_int_src" "true")
0e8c2b0d 17133 (set_attr "mode" "<MODE>")])
e075ae69 17134
cfa185b8 17135(define_insn "*fop_df_4_i387"
e075ae69
RH
17136 [(set (match_operand:DF 0 "register_operand" "=f,f")
17137 (match_operator:DF 3 "binary_fp_operator"
69002843
UB
17138 [(float_extend:DF
17139 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
e075ae69 17140 (match_operand:DF 2 "register_operand" "0,f")]))]
8ce94e44
JM
17141 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17142 && !(TARGET_SSE2 && TARGET_SSE_MATH)
7656aee4 17143 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
e075ae69 17144 "* return output_387_binary_op (insn, operands);"
6300f037
EC
17145 [(set (attr "type")
17146 (cond [(match_operand:DF 3 "mult_operator" "")
e075ae69 17147 (const_string "fmul")
6300f037 17148 (match_operand:DF 3 "div_operator" "")
e075ae69
RH
17149 (const_string "fdiv")
17150 ]
6ef67412
JH
17151 (const_string "fop")))
17152 (set_attr "mode" "SF")])
e075ae69 17153
cfa185b8 17154(define_insn "*fop_df_5_i387"
e075ae69
RH
17155 [(set (match_operand:DF 0 "register_operand" "=f,f")
17156 (match_operator:DF 3 "binary_fp_operator"
17157 [(match_operand:DF 1 "register_operand" "0,f")
17158 (float_extend:DF
17159 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
8ce94e44
JM
17160 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17161 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
e075ae69 17162 "* return output_387_binary_op (insn, operands);"
6300f037
EC
17163 [(set (attr "type")
17164 (cond [(match_operand:DF 3 "mult_operator" "")
e075ae69 17165 (const_string "fmul")
6300f037 17166 (match_operand:DF 3 "div_operator" "")
e075ae69
RH
17167 (const_string "fdiv")
17168 ]
6ef67412
JH
17169 (const_string "fop")))
17170 (set_attr "mode" "SF")])
e075ae69 17171
cfa185b8 17172(define_insn "*fop_df_6_i387"
4977bab6
ZW
17173 [(set (match_operand:DF 0 "register_operand" "=f,f")
17174 (match_operator:DF 3 "binary_fp_operator"
17175 [(float_extend:DF
17176 (match_operand:SF 1 "register_operand" "0,f"))
17177 (float_extend:DF
17178 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
8ce94e44
JM
17179 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17180 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
4977bab6 17181 "* return output_387_binary_op (insn, operands);"
6300f037
EC
17182 [(set (attr "type")
17183 (cond [(match_operand:DF 3 "mult_operator" "")
4977bab6 17184 (const_string "fmul")
6300f037 17185 (match_operand:DF 3 "div_operator" "")
4977bab6
ZW
17186 (const_string "fdiv")
17187 ]
17188 (const_string "fop")))
17189 (set_attr "mode" "SF")])
17190
cfa185b8
UB
17191(define_insn "*fop_xf_comm_i387"
17192 [(set (match_operand:XF 0 "register_operand" "=f")
17193 (match_operator:XF 3 "binary_fp_operator"
17194 [(match_operand:XF 1 "register_operand" "%0")
17195 (match_operand:XF 2 "register_operand" "f")]))]
17196 "TARGET_80387
17197 && COMMUTATIVE_ARITH_P (operands[3])"
17198 "* return output_387_binary_op (insn, operands);"
6300f037
EC
17199 [(set (attr "type")
17200 (if_then_else (match_operand:XF 3 "mult_operator" "")
cfa185b8
UB
17201 (const_string "fmul")
17202 (const_string "fop")))
17203 (set_attr "mode" "XF")])
17204
17205(define_insn "*fop_xf_1_i387"
e075ae69
RH
17206 [(set (match_operand:XF 0 "register_operand" "=f,f")
17207 (match_operator:XF 3 "binary_fp_operator"
17208 [(match_operand:XF 1 "register_operand" "0,f")
17209 (match_operand:XF 2 "register_operand" "f,0")]))]
f8a1ebc6 17210 "TARGET_80387
ec8e098d 17211 && !COMMUTATIVE_ARITH_P (operands[3])"
e075ae69 17212 "* return output_387_binary_op (insn, operands);"
6300f037
EC
17213 [(set (attr "type")
17214 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 17215 (const_string "fmul")
6300f037 17216 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
17217 (const_string "fdiv")
17218 ]
6ef67412
JH
17219 (const_string "fop")))
17220 (set_attr "mode" "XF")])
e075ae69 17221
ca3a2165 17222(define_insn "*fop_xf_2_i387"
e075ae69
RH
17223 [(set (match_operand:XF 0 "register_operand" "=f,f")
17224 (match_operator:XF 3 "binary_fp_operator"
ca3a2165
UB
17225 [(float:XF
17226 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17227 (match_operand:XF 2 "register_operand" "0,0")]))]
3debdc1e 17228 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
2b589241 17229 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
6300f037
EC
17230 [(set (attr "type")
17231 (cond [(match_operand:XF 3 "mult_operator" "")
2b589241 17232 (const_string "fmul")
6300f037 17233 (match_operand:XF 3 "div_operator" "")
2b589241
JH
17234 (const_string "fdiv")
17235 ]
17236 (const_string "fop")))
17237 (set_attr "fp_int_src" "true")
0e8c2b0d 17238 (set_attr "mode" "<MODE>")])
2b589241 17239
ca3a2165 17240(define_insn "*fop_xf_3_i387"
e075ae69
RH
17241 [(set (match_operand:XF 0 "register_operand" "=f,f")
17242 (match_operator:XF 3 "binary_fp_operator"
17243 [(match_operand:XF 1 "register_operand" "0,0")
ca3a2165
UB
17244 (float:XF
17245 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
3debdc1e 17246 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
e075ae69 17247 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
6300f037
EC
17248 [(set (attr "type")
17249 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 17250 (const_string "fmul")
6300f037 17251 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
17252 (const_string "fdiv")
17253 ]
17254 (const_string "fop")))
17255 (set_attr "fp_int_src" "true")
0e8c2b0d 17256 (set_attr "mode" "<MODE>")])
e075ae69 17257
cfa185b8 17258(define_insn "*fop_xf_4_i387"
e075ae69
RH
17259 [(set (match_operand:XF 0 "register_operand" "=f,f")
17260 (match_operator:XF 3 "binary_fp_operator"
8002331e 17261 [(float_extend:XF
00188daa 17262 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
e075ae69 17263 (match_operand:XF 2 "register_operand" "0,f")]))]
f8a1ebc6 17264 "TARGET_80387"
e075ae69 17265 "* return output_387_binary_op (insn, operands);"
6300f037
EC
17266 [(set (attr "type")
17267 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 17268 (const_string "fmul")
6300f037 17269 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
17270 (const_string "fdiv")
17271 ]
6ef67412 17272 (const_string "fop")))
ca3a2165 17273 (set_attr "mode" "<MODE>")])
e075ae69 17274
cfa185b8 17275(define_insn "*fop_xf_5_i387"
e075ae69
RH
17276 [(set (match_operand:XF 0 "register_operand" "=f,f")
17277 (match_operator:XF 3 "binary_fp_operator"
17278 [(match_operand:XF 1 "register_operand" "0,f")
17279 (float_extend:XF
00188daa 17280 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
f8a1ebc6 17281 "TARGET_80387"
e075ae69 17282 "* return output_387_binary_op (insn, operands);"
6300f037
EC
17283 [(set (attr "type")
17284 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 17285 (const_string "fmul")
6300f037 17286 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
17287 (const_string "fdiv")
17288 ]
6ef67412 17289 (const_string "fop")))
ca3a2165 17290 (set_attr "mode" "<MODE>")])
e075ae69 17291
cfa185b8 17292(define_insn "*fop_xf_6_i387"
e075ae69
RH
17293 [(set (match_operand:XF 0 "register_operand" "=f,f")
17294 (match_operator:XF 3 "binary_fp_operator"
4977bab6 17295 [(float_extend:XF
00188daa 17296 (match_operand:MODEF 1 "register_operand" "0,f"))
e075ae69 17297 (float_extend:XF
00188daa 17298 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
f8a1ebc6 17299 "TARGET_80387"
e075ae69 17300 "* return output_387_binary_op (insn, operands);"
6300f037
EC
17301 [(set (attr "type")
17302 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 17303 (const_string "fmul")
6300f037 17304 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
17305 (const_string "fdiv")
17306 ]
6ef67412 17307 (const_string "fop")))
ca3a2165 17308 (set_attr "mode" "<MODE>")])
e075ae69
RH
17309
17310(define_split
17311 [(set (match_operand 0 "register_operand" "")
17312 (match_operator 3 "binary_fp_operator"
0e8c2b0d 17313 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
e075ae69 17314 (match_operand 2 "register_operand" "")]))]
27ac40e2 17315 "reload_completed
8ce94e44
JM
17316 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17317 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
4211a8fb 17318 [(const_int 0)]
6300f037 17319{
4211a8fb
JH
17320 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
17321 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17322 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17323 gen_rtx_fmt_ee (GET_CODE (operands[3]),
17324 GET_MODE (operands[3]),
17325 operands[4],
17326 operands[2])));
17327 ix86_free_from_memory (GET_MODE (operands[1]));
17328 DONE;
0f40f9f7 17329})
e075ae69
RH
17330
17331(define_split
17332 [(set (match_operand 0 "register_operand" "")
17333 (match_operator 3 "binary_fp_operator"
17334 [(match_operand 1 "register_operand" "")
0e8c2b0d 17335 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
27ac40e2 17336 "reload_completed
8ce94e44
JM
17337 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17338 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
4211a8fb 17339 [(const_int 0)]
4211a8fb
JH
17340{
17341 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
17342 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17343 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2b66da3c 17344 gen_rtx_fmt_ee (GET_CODE (operands[3]),
4211a8fb
JH
17345 GET_MODE (operands[3]),
17346 operands[1],
17347 operands[4])));
17348 ix86_free_from_memory (GET_MODE (operands[2]));
17349 DONE;
0f40f9f7 17350})
e075ae69
RH
17351\f
17352;; FPU special functions.
17353
01302104
UB
17354;; This pattern implements a no-op XFmode truncation for
17355;; all fancy i386 XFmode math functions.
a8083431 17356
01302104 17357(define_insn "truncxf<mode>2_i387_noop_unspec"
00188daa
UB
17358 [(set (match_operand:MODEF 0 "register_operand" "=f")
17359 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
01302104 17360 UNSPEC_TRUNC_NOOP))]
22b768d4 17361 "TARGET_USE_FANCY_MATH_387"
01302104
UB
17362 "* return output_387_reg_move (insn, operands);"
17363 [(set_attr "type" "fmov")
17364 (set_attr "mode" "<MODE>")])
e075ae69
RH
17365
17366(define_insn "sqrtxf2"
17367 [(set (match_operand:XF 0 "register_operand" "=f")
17368 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
5a4171a0 17369 "TARGET_USE_FANCY_MATH_387"
2b589241
JH
17370 "fsqrt"
17371 [(set_attr "type" "fpspc")
17372 (set_attr "mode" "XF")
21efb4d4
HJ
17373 (set_attr "athlon_decode" "direct")
17374 (set_attr "amdfam10_decode" "direct")])
2b589241 17375
786f159e 17376(define_insn "sqrt_extend<mode>xf2_i387"
e075ae69 17377 [(set (match_operand:XF 0 "register_operand" "=f")
01302104
UB
17378 (sqrt:XF
17379 (float_extend:XF
00188daa 17380 (match_operand:MODEF 1 "register_operand" "0"))))]
ba2baa55 17381 "TARGET_USE_FANCY_MATH_387"
2b589241
JH
17382 "fsqrt"
17383 [(set_attr "type" "fpspc")
17384 (set_attr "mode" "XF")
4f3f76e6 17385 (set_attr "athlon_decode" "direct")
21efb4d4 17386 (set_attr "amdfam10_decode" "direct")])
2b589241 17387
6b889d89
UB
17388(define_insn "*rsqrtsf2_sse"
17389 [(set (match_operand:SF 0 "register_operand" "=x")
17390 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17391 UNSPEC_RSQRT))]
17392 "TARGET_SSE_MATH"
95879c72 17393 "%vrsqrtss\t{%1, %d0|%d0, %1}"
6b889d89 17394 [(set_attr "type" "sse")
b6837b94 17395 (set_attr "atom_sse_attr" "rcp")
95879c72 17396 (set_attr "prefix" "maybe_vex")
6b889d89
UB
17397 (set_attr "mode" "SF")])
17398
17399(define_expand "rsqrtsf2"
00188daa
UB
17400 [(set (match_operand:SF 0 "register_operand" "")
17401 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
6b889d89 17402 UNSPEC_RSQRT))]
f1bf33ce 17403 "TARGET_SSE_MATH"
6b889d89
UB
17404{
17405 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
17406 DONE;
17407})
17408
01302104 17409(define_insn "*sqrt<mode>2_sse"
00188daa
UB
17410 [(set (match_operand:MODEF 0 "register_operand" "=x")
17411 (sqrt:MODEF
17412 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
01302104 17413 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
95879c72 17414 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
01302104 17415 [(set_attr "type" "sse")
b6837b94 17416 (set_attr "atom_sse_attr" "sqrt")
95879c72 17417 (set_attr "prefix" "maybe_vex")
01302104 17418 (set_attr "mode" "<MODE>")
21efb4d4
HJ
17419 (set_attr "athlon_decode" "*")
17420 (set_attr "amdfam10_decode" "*")])
01302104
UB
17421
17422(define_expand "sqrt<mode>2"
00188daa
UB
17423 [(set (match_operand:MODEF 0 "register_operand" "")
17424 (sqrt:MODEF
17425 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
8ce94e44 17426 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
01302104
UB
17427 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17428{
6b889d89 17429 if (<MODE>mode == SFmode
3debdc1e 17430 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
6b889d89
UB
17431 && flag_finite_math_only && !flag_trapping_math
17432 && flag_unsafe_math_optimizations)
17433 {
17434 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
17435 DONE;
17436 }
17437
01302104
UB
17438 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
17439 {
17440 rtx op0 = gen_reg_rtx (XFmode);
17441 rtx op1 = force_reg (<MODE>mode, operands[1]);
17442
786f159e 17443 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
01302104
UB
17444 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17445 DONE;
17446 }
17447})
2b589241 17448
786f159e 17449(define_insn "fpremxf4_i387"
5ae27cfa
UB
17450 [(set (match_operand:XF 0 "register_operand" "=f")
17451 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17452 (match_operand:XF 3 "register_operand" "1")]
17453 UNSPEC_FPREM_F))
17454 (set (match_operand:XF 1 "register_operand" "=u")
17455 (unspec:XF [(match_dup 2) (match_dup 3)]
17456 UNSPEC_FPREM_U))
8bc527af 17457 (set (reg:CCFP FPSR_REG)
79cd820a
UB
17458 (unspec:CCFP [(match_dup 2) (match_dup 3)]
17459 UNSPEC_C2_FLAG))]
17b98269 17460 "TARGET_USE_FANCY_MATH_387"
5ae27cfa
UB
17461 "fprem"
17462 [(set_attr "type" "fpspc")
17463 (set_attr "mode" "XF")])
17464
786f159e
UB
17465(define_expand "fmodxf3"
17466 [(use (match_operand:XF 0 "register_operand" ""))
17c340e0
UB
17467 (use (match_operand:XF 1 "general_operand" ""))
17468 (use (match_operand:XF 2 "general_operand" ""))]
786f159e 17469 "TARGET_USE_FANCY_MATH_387"
5ae27cfa
UB
17470{
17471 rtx label = gen_label_rtx ();
17472
17c340e0
UB
17473 rtx op1 = gen_reg_rtx (XFmode);
17474 rtx op2 = gen_reg_rtx (XFmode);
21da84bd 17475
17c340e0 17476 emit_move_insn (op2, operands[2]);
f2a55e41 17477 emit_move_insn (op1, operands[1]);
5ae27cfa 17478
21da84bd 17479 emit_label (label);
17c340e0 17480 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
5ae27cfa 17481 ix86_emit_fp_unordered_jump (label);
79cd820a 17482 LABEL_NUSES (label) = 1;
5ae27cfa 17483
17c340e0 17484 emit_move_insn (operands[0], op1);
5ae27cfa
UB
17485 DONE;
17486})
17487
786f159e 17488(define_expand "fmod<mode>3"
00188daa
UB
17489 [(use (match_operand:MODEF 0 "register_operand" ""))
17490 (use (match_operand:MODEF 1 "general_operand" ""))
17491 (use (match_operand:MODEF 2 "general_operand" ""))]
e26feb2c 17492 "TARGET_USE_FANCY_MATH_387"
5ae27cfa
UB
17493{
17494 rtx label = gen_label_rtx ();
17495
17496 rtx op1 = gen_reg_rtx (XFmode);
17497 rtx op2 = gen_reg_rtx (XFmode);
17498
e26feb2c 17499 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
f2a55e41 17500 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
5ae27cfa
UB
17501
17502 emit_label (label);
786f159e 17503 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
5ae27cfa 17504 ix86_emit_fp_unordered_jump (label);
79cd820a 17505 LABEL_NUSES (label) = 1;
5ae27cfa 17506
e26feb2c
UB
17507 /* Truncate the result properly for strict SSE math. */
17508 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17509 && !TARGET_MIX_SSE_I387)
17510 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17511 else
17512 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17513
5ae27cfa
UB
17514 DONE;
17515})
17516
786f159e 17517(define_insn "fprem1xf4_i387"
5ae27cfa
UB
17518 [(set (match_operand:XF 0 "register_operand" "=f")
17519 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17520 (match_operand:XF 3 "register_operand" "1")]
17521 UNSPEC_FPREM1_F))
17522 (set (match_operand:XF 1 "register_operand" "=u")
17523 (unspec:XF [(match_dup 2) (match_dup 3)]
17524 UNSPEC_FPREM1_U))
8bc527af 17525 (set (reg:CCFP FPSR_REG)
79cd820a
UB
17526 (unspec:CCFP [(match_dup 2) (match_dup 3)]
17527 UNSPEC_C2_FLAG))]
17b98269 17528 "TARGET_USE_FANCY_MATH_387"
5ae27cfa
UB
17529 "fprem1"
17530 [(set_attr "type" "fpspc")
17531 (set_attr "mode" "XF")])
17532
786f159e
UB
17533(define_expand "remainderxf3"
17534 [(use (match_operand:XF 0 "register_operand" ""))
17c340e0
UB
17535 (use (match_operand:XF 1 "general_operand" ""))
17536 (use (match_operand:XF 2 "general_operand" ""))]
786f159e 17537 "TARGET_USE_FANCY_MATH_387"
5ae27cfa
UB
17538{
17539 rtx label = gen_label_rtx ();
17540
17c340e0
UB
17541 rtx op1 = gen_reg_rtx (XFmode);
17542 rtx op2 = gen_reg_rtx (XFmode);
21da84bd 17543
17c340e0 17544 emit_move_insn (op2, operands[2]);
f2a55e41 17545 emit_move_insn (op1, operands[1]);
5ae27cfa 17546
21da84bd 17547 emit_label (label);
17c340e0 17548 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
5ae27cfa 17549 ix86_emit_fp_unordered_jump (label);
79cd820a 17550 LABEL_NUSES (label) = 1;
5ae27cfa 17551
17c340e0 17552 emit_move_insn (operands[0], op1);
5ae27cfa
UB
17553 DONE;
17554})
17555
786f159e 17556(define_expand "remainder<mode>3"
00188daa
UB
17557 [(use (match_operand:MODEF 0 "register_operand" ""))
17558 (use (match_operand:MODEF 1 "general_operand" ""))
17559 (use (match_operand:MODEF 2 "general_operand" ""))]
e26feb2c 17560 "TARGET_USE_FANCY_MATH_387"
5ae27cfa
UB
17561{
17562 rtx label = gen_label_rtx ();
17563
17564 rtx op1 = gen_reg_rtx (XFmode);
17565 rtx op2 = gen_reg_rtx (XFmode);
17566
e26feb2c 17567 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
f2a55e41 17568 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
5ae27cfa
UB
17569
17570 emit_label (label);
17571
786f159e 17572 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
5ae27cfa 17573 ix86_emit_fp_unordered_jump (label);
79cd820a 17574 LABEL_NUSES (label) = 1;
5ae27cfa 17575
e26feb2c
UB
17576 /* Truncate the result properly for strict SSE math. */
17577 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17578 && !TARGET_MIX_SSE_I387)
17579 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17580 else
17581 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17582
5ae27cfa
UB
17583 DONE;
17584})
17585
c648dedb 17586(define_insn "*sinxf2_i387"
e075ae69 17587 [(set (match_operand:XF 0 "register_operand" "=f")
8ee41eaf 17588 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
ba2baa55 17589 "TARGET_USE_FANCY_MATH_387
de6c5979 17590 && flag_unsafe_math_optimizations"
2b589241
JH
17591 "fsin"
17592 [(set_attr "type" "fpspc")
17593 (set_attr "mode" "XF")])
17594
c648dedb
UB
17595(define_insn "*sin_extend<mode>xf2_i387"
17596 [(set (match_operand:XF 0 "register_operand" "=f")
17597 (unspec:XF [(float_extend:XF
00188daa 17598 (match_operand:MODEF 1 "register_operand" "0"))]
c648dedb 17599 UNSPEC_SIN))]
ba2baa55 17600 "TARGET_USE_FANCY_MATH_387
c648dedb
UB
17601 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17602 || TARGET_MIX_SSE_I387)
de6c5979 17603 && flag_unsafe_math_optimizations"
c648dedb 17604 "fsin"
6ef67412 17605 [(set_attr "type" "fpspc")
c648dedb 17606 (set_attr "mode" "XF")])
bca7cce2 17607
c648dedb
UB
17608(define_insn "*cosxf2_i387"
17609 [(set (match_operand:XF 0 "register_operand" "=f")
17610 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
ba2baa55 17611 "TARGET_USE_FANCY_MATH_387
de6c5979 17612 && flag_unsafe_math_optimizations"
e075ae69 17613 "fcos"
6ef67412 17614 [(set_attr "type" "fpspc")
c648dedb 17615 (set_attr "mode" "XF")])
5f3d14e3 17616
c648dedb 17617(define_insn "*cos_extend<mode>xf2_i387"
e075ae69 17618 [(set (match_operand:XF 0 "register_operand" "=f")
c648dedb 17619 (unspec:XF [(float_extend:XF
00188daa 17620 (match_operand:MODEF 1 "register_operand" "0"))]
c648dedb 17621 UNSPEC_COS))]
ba2baa55 17622 "TARGET_USE_FANCY_MATH_387
c648dedb
UB
17623 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17624 || TARGET_MIX_SSE_I387)
de6c5979 17625 && flag_unsafe_math_optimizations"
2b589241
JH
17626 "fcos"
17627 [(set_attr "type" "fpspc")
17628 (set_attr "mode" "XF")])
1fb54135 17629
c648dedb 17630;; When sincos pattern is defined, sin and cos builtin functions will be
6300f037 17631;; expanded to sincos pattern with one of its outputs left unused.
c648dedb 17632;; CSE pass will figure out if two sincos patterns can be combined,
1ae58c30 17633;; otherwise sincos pattern will be split back to sin or cos pattern,
6c7cf1f0
UB
17634;; depending on the unused output.
17635
c648dedb
UB
17636(define_insn "sincosxf3"
17637 [(set (match_operand:XF 0 "register_operand" "=f")
17638 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
6c7cf1f0 17639 UNSPEC_SINCOS_COS))
c648dedb
UB
17640 (set (match_operand:XF 1 "register_operand" "=u")
17641 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
ba2baa55 17642 "TARGET_USE_FANCY_MATH_387
6c7cf1f0
UB
17643 && flag_unsafe_math_optimizations"
17644 "fsincos"
17645 [(set_attr "type" "fpspc")
c648dedb 17646 (set_attr "mode" "XF")])
6c7cf1f0
UB
17647
17648(define_split
c648dedb
UB
17649 [(set (match_operand:XF 0 "register_operand" "")
17650 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
6c7cf1f0 17651 UNSPEC_SINCOS_COS))
c648dedb
UB
17652 (set (match_operand:XF 1 "register_operand" "")
17653 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
6c7cf1f0 17654 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
00188daa 17655 && !(reload_completed || reload_in_progress)"
c648dedb 17656 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
6c7cf1f0
UB
17657 "")
17658
17659(define_split
c648dedb
UB
17660 [(set (match_operand:XF 0 "register_operand" "")
17661 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
6c7cf1f0 17662 UNSPEC_SINCOS_COS))
c648dedb
UB
17663 (set (match_operand:XF 1 "register_operand" "")
17664 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
6c7cf1f0 17665 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
00188daa 17666 && !(reload_completed || reload_in_progress)"
c648dedb 17667 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
6c7cf1f0
UB
17668 "")
17669
c648dedb 17670(define_insn "sincos_extend<mode>xf3_i387"
6c7cf1f0 17671 [(set (match_operand:XF 0 "register_operand" "=f")
c648dedb 17672 (unspec:XF [(float_extend:XF
00188daa 17673 (match_operand:MODEF 2 "register_operand" "0"))]
6c7cf1f0
UB
17674 UNSPEC_SINCOS_COS))
17675 (set (match_operand:XF 1 "register_operand" "=u")
c648dedb 17676 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
ba2baa55 17677 "TARGET_USE_FANCY_MATH_387
c648dedb
UB
17678 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17679 || TARGET_MIX_SSE_I387)
6c7cf1f0
UB
17680 && flag_unsafe_math_optimizations"
17681 "fsincos"
17682 [(set_attr "type" "fpspc")
17683 (set_attr "mode" "XF")])
17684
17685(define_split
17686 [(set (match_operand:XF 0 "register_operand" "")
c648dedb 17687 (unspec:XF [(float_extend:XF
00188daa 17688 (match_operand:MODEF 2 "register_operand" ""))]
6c7cf1f0
UB
17689 UNSPEC_SINCOS_COS))
17690 (set (match_operand:XF 1 "register_operand" "")
c648dedb 17691 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
6c7cf1f0 17692 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
00188daa 17693 && !(reload_completed || reload_in_progress)"
c648dedb 17694 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
6c7cf1f0
UB
17695 "")
17696
17697(define_split
17698 [(set (match_operand:XF 0 "register_operand" "")
c648dedb 17699 (unspec:XF [(float_extend:XF
00188daa 17700 (match_operand:MODEF 2 "register_operand" ""))]
6c7cf1f0
UB
17701 UNSPEC_SINCOS_COS))
17702 (set (match_operand:XF 1 "register_operand" "")
c648dedb 17703 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
6c7cf1f0 17704 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
00188daa 17705 && !(reload_completed || reload_in_progress)"
c648dedb 17706 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
6c7cf1f0
UB
17707 "")
17708
c648dedb 17709(define_expand "sincos<mode>3"
00188daa
UB
17710 [(use (match_operand:MODEF 0 "register_operand" ""))
17711 (use (match_operand:MODEF 1 "register_operand" ""))
17712 (use (match_operand:MODEF 2 "register_operand" ""))]
c648dedb
UB
17713 "TARGET_USE_FANCY_MATH_387
17714 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17715 || TARGET_MIX_SSE_I387)
17716 && flag_unsafe_math_optimizations"
17717{
17718 rtx op0 = gen_reg_rtx (XFmode);
17719 rtx op1 = gen_reg_rtx (XFmode);
17720
17721 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
d85c7550
UB
17722 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17723 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
c648dedb
UB
17724 DONE;
17725})
17726
d85c7550
UB
17727(define_insn "fptanxf4_i387"
17728 [(set (match_operand:XF 0 "register_operand" "=f")
17729 (match_operand:XF 3 "const_double_operand" "F"))
17730 (set (match_operand:XF 1 "register_operand" "=u")
17731 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17732 UNSPEC_TAN))]
ba2baa55 17733 "TARGET_USE_FANCY_MATH_387
d85c7550
UB
17734 && flag_unsafe_math_optimizations
17735 && standard_80387_constant_p (operands[3]) == 2"
a072d43b
UB
17736 "fptan"
17737 [(set_attr "type" "fpspc")
d85c7550 17738 (set_attr "mode" "XF")])
a072d43b 17739
d85c7550 17740(define_insn "fptan_extend<mode>xf4_i387"
00188daa
UB
17741 [(set (match_operand:MODEF 0 "register_operand" "=f")
17742 (match_operand:MODEF 3 "const_double_operand" "F"))
d85c7550
UB
17743 (set (match_operand:XF 1 "register_operand" "=u")
17744 (unspec:XF [(float_extend:XF
00188daa 17745 (match_operand:MODEF 2 "register_operand" "0"))]
d85c7550 17746 UNSPEC_TAN))]
ba2baa55 17747 "TARGET_USE_FANCY_MATH_387
d85c7550
UB
17748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17749 || TARGET_MIX_SSE_I387)
17750 && flag_unsafe_math_optimizations
17751 && standard_80387_constant_p (operands[3]) == 2"
a072d43b
UB
17752 "fptan"
17753 [(set_attr "type" "fpspc")
d85c7550 17754 (set_attr "mode" "XF")])
a072d43b 17755
d85c7550
UB
17756(define_expand "tanxf2"
17757 [(use (match_operand:XF 0 "register_operand" ""))
17758 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 17759 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
17760 && flag_unsafe_math_optimizations"
17761{
d85c7550 17762 rtx one = gen_reg_rtx (XFmode);
9db27449 17763 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
d85c7550 17764
9db27449 17765 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
d85c7550 17766 DONE;
a072d43b
UB
17767})
17768
d85c7550 17769(define_expand "tan<mode>2"
00188daa
UB
17770 [(use (match_operand:MODEF 0 "register_operand" ""))
17771 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 17772 "TARGET_USE_FANCY_MATH_387
d85c7550
UB
17773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17774 || TARGET_MIX_SSE_I387)
a072d43b 17775 && flag_unsafe_math_optimizations"
d85c7550
UB
17776{
17777 rtx op0 = gen_reg_rtx (XFmode);
a072d43b 17778
d85c7550 17779 rtx one = gen_reg_rtx (<MODE>mode);
9db27449 17780 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
a072d43b 17781
d85c7550 17782 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
9db27449 17783 operands[1], op2));
d85c7550
UB
17784 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17785 DONE;
a072d43b
UB
17786})
17787
8ef4f42c
UB
17788(define_insn "*fpatanxf3_i387"
17789 [(set (match_operand:XF 0 "register_operand" "=f")
17790 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17791 (match_operand:XF 2 "register_operand" "u")]
17792 UNSPEC_FPATAN))
17793 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 17794 "TARGET_USE_FANCY_MATH_387
1fb54135
RS
17795 && flag_unsafe_math_optimizations"
17796 "fpatan"
17797 [(set_attr "type" "fpspc")
8ef4f42c 17798 (set_attr "mode" "XF")])
a6bf61c7 17799
8ef4f42c 17800(define_insn "fpatan_extend<mode>xf3_i387"
cb0bc263 17801 [(set (match_operand:XF 0 "register_operand" "=f")
8ef4f42c 17802 (unspec:XF [(float_extend:XF
00188daa 17803 (match_operand:MODEF 1 "register_operand" "0"))
8ef4f42c 17804 (float_extend:XF
00188daa 17805 (match_operand:MODEF 2 "register_operand" "u"))]
cb0bc263 17806 UNSPEC_FPATAN))
8ef4f42c 17807 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 17808 "TARGET_USE_FANCY_MATH_387
8ef4f42c
UB
17809 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17810 || TARGET_MIX_SSE_I387)
f8a1ebc6 17811 && flag_unsafe_math_optimizations"
1fb54135
RS
17812 "fpatan"
17813 [(set_attr "type" "fpspc")
17814 (set_attr "mode" "XF")])
17815
afeeac3f 17816(define_expand "atan2xf3"
8ef4f42c
UB
17817 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17818 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17819 (match_operand:XF 1 "register_operand" "")]
17820 UNSPEC_FPATAN))
17821 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 17822 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 17823 && flag_unsafe_math_optimizations"
8ef4f42c
UB
17824 "")
17825
17826(define_expand "atan2<mode>3"
00188daa
UB
17827 [(use (match_operand:MODEF 0 "register_operand" ""))
17828 (use (match_operand:MODEF 1 "register_operand" ""))
17829 (use (match_operand:MODEF 2 "register_operand" ""))]
8ef4f42c
UB
17830 "TARGET_USE_FANCY_MATH_387
17831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17832 || TARGET_MIX_SSE_I387)
17833 && flag_unsafe_math_optimizations"
afeeac3f 17834{
8ef4f42c
UB
17835 rtx op0 = gen_reg_rtx (XFmode);
17836
17837 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
afeeac3f 17839 DONE;
923c4cf2 17840})
afeeac3f 17841
a6bf61c7
UB
17842(define_expand "atanxf2"
17843 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17844 (unspec:XF [(match_dup 2)
17845 (match_operand:XF 1 "register_operand" "")]
8ef4f42c 17846 UNSPEC_FPATAN))
a6bf61c7 17847 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 17848 "TARGET_USE_FANCY_MATH_387
a6bf61c7
UB
17849 && flag_unsafe_math_optimizations"
17850{
17851 operands[2] = gen_reg_rtx (XFmode);
17852 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17853})
17854
8ef4f42c 17855(define_expand "atan<mode>2"
00188daa
UB
17856 [(use (match_operand:MODEF 0 "register_operand" ""))
17857 (use (match_operand:MODEF 1 "register_operand" ""))]
8ef4f42c
UB
17858 "TARGET_USE_FANCY_MATH_387
17859 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17860 || TARGET_MIX_SSE_I387)
17861 && flag_unsafe_math_optimizations"
17862{
17863 rtx op0 = gen_reg_rtx (XFmode);
17864
9db27449
UB
17865 rtx op2 = gen_reg_rtx (<MODE>mode);
17866 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
8ef4f42c 17867
9db27449 17868 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
8ef4f42c
UB
17869 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17870 DONE;
17871})
17872
c56122d8
UB
17873(define_expand "asinxf2"
17874 [(set (match_dup 2)
17875 (mult:XF (match_operand:XF 1 "register_operand" "")
17876 (match_dup 1)))
17877 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17878 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17879 (parallel [(set (match_operand:XF 0 "register_operand" "")
17880 (unspec:XF [(match_dup 5) (match_dup 1)]
17881 UNSPEC_FPATAN))
17882 (clobber (match_scratch:XF 6 ""))])]
ba2baa55 17883 "TARGET_USE_FANCY_MATH_387
18bd082d 17884 && flag_unsafe_math_optimizations"
c56122d8
UB
17885{
17886 int i;
17887
18bd082d
JH
17888 if (optimize_insn_for_size_p ())
17889 FAIL;
17890
e2fc57a3 17891 for (i = 2; i < 6; i++)
c56122d8
UB
17892 operands[i] = gen_reg_rtx (XFmode);
17893
17894 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17895})
17896
e2fc57a3 17897(define_expand "asin<mode>2"
00188daa
UB
17898 [(use (match_operand:MODEF 0 "register_operand" ""))
17899 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
17900 "TARGET_USE_FANCY_MATH_387
17901 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17902 || TARGET_MIX_SSE_I387)
18bd082d 17903 && flag_unsafe_math_optimizations"
c56122d8 17904{
e2fc57a3
UB
17905 rtx op0 = gen_reg_rtx (XFmode);
17906 rtx op1 = gen_reg_rtx (XFmode);
c56122d8 17907
18bd082d
JH
17908 if (optimize_insn_for_size_p ())
17909 FAIL;
17910
e2fc57a3
UB
17911 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17912 emit_insn (gen_asinxf2 (op0, op1));
17913 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17914 DONE;
c56122d8
UB
17915})
17916
17917(define_expand "acosxf2"
17918 [(set (match_dup 2)
17919 (mult:XF (match_operand:XF 1 "register_operand" "")
17920 (match_dup 1)))
17921 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17922 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17923 (parallel [(set (match_operand:XF 0 "register_operand" "")
17924 (unspec:XF [(match_dup 1) (match_dup 5)]
17925 UNSPEC_FPATAN))
17926 (clobber (match_scratch:XF 6 ""))])]
ba2baa55 17927 "TARGET_USE_FANCY_MATH_387
18bd082d 17928 && flag_unsafe_math_optimizations"
c56122d8
UB
17929{
17930 int i;
17931
18bd082d
JH
17932 if (optimize_insn_for_size_p ())
17933 FAIL;
17934
e2fc57a3 17935 for (i = 2; i < 6; i++)
c56122d8
UB
17936 operands[i] = gen_reg_rtx (XFmode);
17937
17938 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17939})
17940
e2fc57a3 17941(define_expand "acos<mode>2"
00188daa
UB
17942 [(use (match_operand:MODEF 0 "register_operand" ""))
17943 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
17944 "TARGET_USE_FANCY_MATH_387
17945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17946 || TARGET_MIX_SSE_I387)
18bd082d 17947 && flag_unsafe_math_optimizations"
e2fc57a3
UB
17948{
17949 rtx op0 = gen_reg_rtx (XFmode);
17950 rtx op1 = gen_reg_rtx (XFmode);
17951
18bd082d
JH
17952 if (optimize_insn_for_size_p ())
17953 FAIL;
17954
e2fc57a3
UB
17955 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17956 emit_insn (gen_acosxf2 (op0, op1));
17957 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17958 DONE;
17959})
17960
0ac45694 17961(define_insn "fyl2xxf3_i387"
cb0bc263 17962 [(set (match_operand:XF 0 "register_operand" "=f")
0ac45694
UB
17963 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17964 (match_operand:XF 2 "register_operand" "u")]
cb0bc263 17965 UNSPEC_FYL2X))
0ac45694 17966 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 17967 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 17968 && flag_unsafe_math_optimizations"
358997e2
RS
17969 "fyl2x"
17970 [(set_attr "type" "fpspc")
17971 (set_attr "mode" "XF")])
17972
0ac45694
UB
17973(define_insn "fyl2x_extend<mode>xf3_i387"
17974 [(set (match_operand:XF 0 "register_operand" "=f")
17975 (unspec:XF [(float_extend:XF
00188daa 17976 (match_operand:MODEF 1 "register_operand" "0"))
0ac45694
UB
17977 (match_operand:XF 2 "register_operand" "u")]
17978 UNSPEC_FYL2X))
17979 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 17980 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
17981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17982 || TARGET_MIX_SSE_I387)
358997e2 17983 && flag_unsafe_math_optimizations"
0ac45694
UB
17984 "fyl2x"
17985 [(set_attr "type" "fpspc")
17986 (set_attr "mode" "XF")])
358997e2 17987
0ac45694
UB
17988(define_expand "logxf2"
17989 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17990 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17991 (match_dup 2)] UNSPEC_FYL2X))
17992 (clobber (match_scratch:XF 3 ""))])]
17993 "TARGET_USE_FANCY_MATH_387
17994 && flag_unsafe_math_optimizations"
17995{
f8a1ebc6 17996 operands[2] = gen_reg_rtx (XFmode);
0ac45694 17997 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
358997e2
RS
17998})
17999
0ac45694 18000(define_expand "log<mode>2"
00188daa
UB
18001 [(use (match_operand:MODEF 0 "register_operand" ""))
18002 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 18003 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
18004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18005 || TARGET_MIX_SSE_I387)
358997e2
RS
18006 && flag_unsafe_math_optimizations"
18007{
0ac45694 18008 rtx op0 = gen_reg_rtx (XFmode);
358997e2 18009
9db27449
UB
18010 rtx op2 = gen_reg_rtx (XFmode);
18011 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
6adcf89d 18012
9db27449 18013 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
e2fc57a3 18014 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
0ac45694 18015 DONE;
358997e2
RS
18016})
18017
0ac45694 18018(define_expand "log10xf2"
e43736ad
RS
18019 [(parallel [(set (match_operand:XF 0 "register_operand" "")
18020 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18021 (match_dup 2)] UNSPEC_FYL2X))
cb0bc263 18022 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 18023 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 18024 && flag_unsafe_math_optimizations"
358997e2 18025{
3b8e0c91 18026 operands[2] = gen_reg_rtx (XFmode);
0ac45694 18027 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
3b8e0c91
UB
18028})
18029
0ac45694 18030(define_expand "log10<mode>2"
00188daa
UB
18031 [(use (match_operand:MODEF 0 "register_operand" ""))
18032 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 18033 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
18034 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18035 || TARGET_MIX_SSE_I387)
3b8e0c91
UB
18036 && flag_unsafe_math_optimizations"
18037{
0ac45694 18038 rtx op0 = gen_reg_rtx (XFmode);
3b8e0c91 18039
9db27449
UB
18040 rtx op2 = gen_reg_rtx (XFmode);
18041 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
6adcf89d 18042
9db27449 18043 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
e2fc57a3 18044 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
0ac45694 18045 DONE;
3b8e0c91
UB
18046})
18047
0ac45694 18048(define_expand "log2xf2"
3b8e0c91
UB
18049 [(parallel [(set (match_operand:XF 0 "register_operand" "")
18050 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18051 (match_dup 2)] UNSPEC_FYL2X))
18052 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 18053 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
18054 && flag_unsafe_math_optimizations"
18055{
3b8e0c91 18056 operands[2] = gen_reg_rtx (XFmode);
0ac45694 18057 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
3b8e0c91
UB
18058})
18059
0ac45694 18060(define_expand "log2<mode>2"
00188daa
UB
18061 [(use (match_operand:MODEF 0 "register_operand" ""))
18062 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 18063 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
18064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18065 || TARGET_MIX_SSE_I387)
3b8e0c91
UB
18066 && flag_unsafe_math_optimizations"
18067{
0ac45694 18068 rtx op0 = gen_reg_rtx (XFmode);
3b8e0c91 18069
9db27449
UB
18070 rtx op2 = gen_reg_rtx (XFmode);
18071 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
6adcf89d 18072
9db27449 18073 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
e2fc57a3 18074 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
0ac45694 18075 DONE;
3b8e0c91
UB
18076})
18077
0ac45694
UB
18078(define_insn "fyl2xp1xf3_i387"
18079 [(set (match_operand:XF 0 "register_operand" "=f")
18080 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
18081 (match_operand:XF 2 "register_operand" "u")]
18082 UNSPEC_FYL2XP1))
18083 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 18084 "TARGET_USE_FANCY_MATH_387
3b8e0c91 18085 && flag_unsafe_math_optimizations"
0ac45694
UB
18086 "fyl2xp1"
18087 [(set_attr "type" "fpspc")
18088 (set_attr "mode" "XF")])
3b8e0c91 18089
0ac45694 18090(define_insn "fyl2xp1_extend<mode>xf3_i387"
c2fcfa4f 18091 [(set (match_operand:XF 0 "register_operand" "=f")
0ac45694 18092 (unspec:XF [(float_extend:XF
00188daa 18093 (match_operand:MODEF 1 "register_operand" "0"))
0ac45694 18094 (match_operand:XF 2 "register_operand" "u")]
c2fcfa4f 18095 UNSPEC_FYL2XP1))
0ac45694 18096 (clobber (match_scratch:XF 3 "=2"))]
ba2baa55 18097 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
18098 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18099 || TARGET_MIX_SSE_I387)
c2fcfa4f
UB
18100 && flag_unsafe_math_optimizations"
18101 "fyl2xp1"
18102 [(set_attr "type" "fpspc")
18103 (set_attr "mode" "XF")])
18104
0ac45694
UB
18105(define_expand "log1pxf2"
18106 [(use (match_operand:XF 0 "register_operand" ""))
18107 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 18108 "TARGET_USE_FANCY_MATH_387
18bd082d 18109 && flag_unsafe_math_optimizations"
c2fcfa4f 18110{
18bd082d
JH
18111 if (optimize_insn_for_size_p ())
18112 FAIL;
18113
0ac45694 18114 ix86_emit_i387_log1p (operands[0], operands[1]);
c2fcfa4f
UB
18115 DONE;
18116})
18117
0ac45694 18118(define_expand "log1p<mode>2"
00188daa
UB
18119 [(use (match_operand:MODEF 0 "register_operand" ""))
18120 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 18121 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
18122 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18123 || TARGET_MIX_SSE_I387)
18bd082d 18124 && flag_unsafe_math_optimizations"
c2fcfa4f 18125{
18bd082d
JH
18126 rtx op0;
18127
18128 if (optimize_insn_for_size_p ())
18129 FAIL;
18130
18131 op0 = gen_reg_rtx (XFmode);
c2fcfa4f 18132
0ac45694 18133 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
c2fcfa4f 18134
0ac45694 18135 ix86_emit_i387_log1p (op0, operands[1]);
e2fc57a3 18136 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
c2fcfa4f
UB
18137 DONE;
18138})
18139
eaee4464 18140(define_insn "fxtractxf3_i387"
6adcf89d
UB
18141 [(set (match_operand:XF 0 "register_operand" "=f")
18142 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
88b28a31 18143 UNSPEC_XTRACT_FRACT))
6adcf89d
UB
18144 (set (match_operand:XF 1 "register_operand" "=u")
18145 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
ba2baa55 18146 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
18147 && flag_unsafe_math_optimizations"
18148 "fxtract"
18149 [(set_attr "type" "fpspc")
6adcf89d 18150 (set_attr "mode" "XF")])
88b28a31 18151
0ac45694
UB
18152(define_insn "fxtract_extend<mode>xf3_i387"
18153 [(set (match_operand:XF 0 "register_operand" "=f")
18154 (unspec:XF [(float_extend:XF
00188daa 18155 (match_operand:MODEF 2 "register_operand" "0"))]
0ac45694
UB
18156 UNSPEC_XTRACT_FRACT))
18157 (set (match_operand:XF 1 "register_operand" "=u")
18158 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
ba2baa55 18159 "TARGET_USE_FANCY_MATH_387
0ac45694
UB
18160 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18161 || TARGET_MIX_SSE_I387)
88b28a31 18162 && flag_unsafe_math_optimizations"
0ac45694
UB
18163 "fxtract"
18164 [(set_attr "type" "fpspc")
18165 (set_attr "mode" "XF")])
88b28a31 18166
88b28a31
UB
18167(define_expand "logbxf2"
18168 [(parallel [(set (match_dup 2)
18169 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18170 UNSPEC_XTRACT_FRACT))
18171 (set (match_operand:XF 0 "register_operand" "")
18172 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
ba2baa55 18173 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
18174 && flag_unsafe_math_optimizations"
18175{
18176 operands[2] = gen_reg_rtx (XFmode);
18177})
18178
0ac45694 18179(define_expand "logb<mode>2"
00188daa
UB
18180 [(use (match_operand:MODEF 0 "register_operand" ""))
18181 (use (match_operand:MODEF 1 "register_operand" ""))]
0ac45694
UB
18182 "TARGET_USE_FANCY_MATH_387
18183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18184 || TARGET_MIX_SSE_I387)
18185 && flag_unsafe_math_optimizations"
18186{
18187 rtx op0 = gen_reg_rtx (XFmode);
18188 rtx op1 = gen_reg_rtx (XFmode);
18189
18190 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
e2fc57a3 18191 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
0ac45694
UB
18192 DONE;
18193})
18194
eaee4464
UB
18195(define_expand "ilogbxf2"
18196 [(use (match_operand:SI 0 "register_operand" ""))
18197 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 18198 "TARGET_USE_FANCY_MATH_387
18bd082d 18199 && flag_unsafe_math_optimizations"
88b28a31 18200{
18bd082d
JH
18201 rtx op0, op1;
18202
18203 if (optimize_insn_for_size_p ())
18204 FAIL;
18205
18206 op0 = gen_reg_rtx (XFmode);
18207 op1 = gen_reg_rtx (XFmode);
eaee4464
UB
18208
18209 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
18210 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18211 DONE;
18212})
18213
18214(define_expand "ilogb<mode>2"
18215 [(use (match_operand:SI 0 "register_operand" ""))
00188daa 18216 (use (match_operand:MODEF 1 "register_operand" ""))]
eaee4464
UB
18217 "TARGET_USE_FANCY_MATH_387
18218 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18219 || TARGET_MIX_SSE_I387)
18bd082d 18220 && flag_unsafe_math_optimizations"
eaee4464 18221{
18bd082d
JH
18222 rtx op0, op1;
18223
18224 if (optimize_insn_for_size_p ())
18225 FAIL;
18226
18227 op0 = gen_reg_rtx (XFmode);
18228 op1 = gen_reg_rtx (XFmode);
eaee4464
UB
18229
18230 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18231 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18232 DONE;
88b28a31
UB
18233})
18234
e2fc57a3 18235(define_insn "*f2xm1xf2_i387"
9d5b9dae
RS
18236 [(set (match_operand:XF 0 "register_operand" "=f")
18237 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
e2fc57a3 18238 UNSPEC_F2XM1))]
ba2baa55 18239 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 18240 && flag_unsafe_math_optimizations"
9d5b9dae
RS
18241 "f2xm1"
18242 [(set_attr "type" "fpspc")
18243 (set_attr "mode" "XF")])
18244
e2fc57a3 18245(define_insn "*fscalexf4_i387"
f964bd29
UB
18246 [(set (match_operand:XF 0 "register_operand" "=f")
18247 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
18248 (match_operand:XF 3 "register_operand" "1")]
18249 UNSPEC_FSCALE_FRACT))
18250 (set (match_operand:XF 1 "register_operand" "=u")
18251 (unspec:XF [(match_dup 2) (match_dup 3)]
18252 UNSPEC_FSCALE_EXP))]
ba2baa55 18253 "TARGET_USE_FANCY_MATH_387
f964bd29
UB
18254 && flag_unsafe_math_optimizations"
18255 "fscale"
18256 [(set_attr "type" "fpspc")
152e3565 18257 (set_attr "mode" "XF")])
f964bd29 18258
e2fc57a3 18259(define_expand "expNcorexf3"
9d5b9dae 18260 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
e2fc57a3 18261 (match_operand:XF 2 "register_operand" "")))
9d5b9dae
RS
18262 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18263 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18264 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18265 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
18266 (parallel [(set (match_operand:XF 0 "register_operand" "")
f964bd29
UB
18267 (unspec:XF [(match_dup 8) (match_dup 4)]
18268 UNSPEC_FSCALE_FRACT))
18269 (set (match_dup 9)
18270 (unspec:XF [(match_dup 8) (match_dup 4)]
18271 UNSPEC_FSCALE_EXP))])]
ba2baa55 18272 "TARGET_USE_FANCY_MATH_387
18bd082d 18273 && flag_unsafe_math_optimizations"
9d5b9dae 18274{
9d5b9dae
RS
18275 int i;
18276
18bd082d
JH
18277 if (optimize_insn_for_size_p ())
18278 FAIL;
18279
e2fc57a3 18280 for (i = 3; i < 10; i++)
9d5b9dae 18281 operands[i] = gen_reg_rtx (XFmode);
e2fc57a3 18282
9d5b9dae
RS
18283 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
18284})
82d397c7 18285
e2fc57a3
UB
18286(define_expand "expxf2"
18287 [(use (match_operand:XF 0 "register_operand" ""))
18288 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 18289 "TARGET_USE_FANCY_MATH_387
18bd082d 18290 && flag_unsafe_math_optimizations"
a251102e 18291{
18bd082d
JH
18292 rtx op2;
18293
18294 if (optimize_insn_for_size_p ())
18295 FAIL;
18296
18297 op2 = gen_reg_rtx (XFmode);
9db27449 18298 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
a251102e 18299
9db27449 18300 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
e2fc57a3 18301 DONE;
a251102e
UB
18302})
18303
e2fc57a3 18304(define_expand "exp<mode>2"
00188daa
UB
18305 [(use (match_operand:MODEF 0 "register_operand" ""))
18306 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
18307 "TARGET_USE_FANCY_MATH_387
18308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18309 || TARGET_MIX_SSE_I387)
18bd082d 18310 && flag_unsafe_math_optimizations"
a251102e 18311{
18bd082d
JH
18312 rtx op0, op1;
18313
18314 if (optimize_insn_for_size_p ())
18315 FAIL;
18316
18317 op0 = gen_reg_rtx (XFmode);
18318 op1 = gen_reg_rtx (XFmode);
a251102e 18319
e2fc57a3
UB
18320 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18321 emit_insn (gen_expxf2 (op0, op1));
18322 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18323 DONE;
a251102e
UB
18324})
18325
18326(define_expand "exp10xf2"
e2fc57a3
UB
18327 [(use (match_operand:XF 0 "register_operand" ""))
18328 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 18329 "TARGET_USE_FANCY_MATH_387
18bd082d 18330 && flag_unsafe_math_optimizations"
a251102e 18331{
18bd082d
JH
18332 rtx op2;
18333
18334 if (optimize_insn_for_size_p ())
18335 FAIL;
18336
18337 op2 = gen_reg_rtx (XFmode);
9db27449 18338 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
a251102e 18339
9db27449 18340 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
e2fc57a3 18341 DONE;
a251102e
UB
18342})
18343
e2fc57a3 18344(define_expand "exp10<mode>2"
00188daa
UB
18345 [(use (match_operand:MODEF 0 "register_operand" ""))
18346 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
18347 "TARGET_USE_FANCY_MATH_387
18348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18349 || TARGET_MIX_SSE_I387)
18bd082d 18350 && flag_unsafe_math_optimizations"
a251102e 18351{
18bd082d
JH
18352 rtx op0, op1;
18353
18354 if (optimize_insn_for_size_p ())
18355 FAIL;
18356
18357 op0 = gen_reg_rtx (XFmode);
18358 op1 = gen_reg_rtx (XFmode);
a251102e 18359
e2fc57a3
UB
18360 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18361 emit_insn (gen_exp10xf2 (op0, op1));
18362 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18363 DONE;
a251102e
UB
18364})
18365
18366(define_expand "exp2xf2"
e2fc57a3
UB
18367 [(use (match_operand:XF 0 "register_operand" ""))
18368 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 18369 "TARGET_USE_FANCY_MATH_387
18bd082d 18370 && flag_unsafe_math_optimizations"
7a8e07c7 18371{
18bd082d
JH
18372 rtx op2;
18373
18374 if (optimize_insn_for_size_p ())
18375 FAIL;
18376
18377 op2 = gen_reg_rtx (XFmode);
9db27449 18378 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
7a8e07c7 18379
9db27449 18380 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
e2fc57a3 18381 DONE;
7a8e07c7
UB
18382})
18383
e2fc57a3 18384(define_expand "exp2<mode>2"
00188daa
UB
18385 [(use (match_operand:MODEF 0 "register_operand" ""))
18386 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
18387 "TARGET_USE_FANCY_MATH_387
18388 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18389 || TARGET_MIX_SSE_I387)
18bd082d 18390 && flag_unsafe_math_optimizations"
7a8e07c7 18391{
18bd082d
JH
18392 rtx op0, op1;
18393
18394 if (optimize_insn_for_size_p ())
18395 FAIL;
18396
18397 op0 = gen_reg_rtx (XFmode);
18398 op1 = gen_reg_rtx (XFmode);
7a8e07c7 18399
e2fc57a3
UB
18400 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18401 emit_insn (gen_exp2xf2 (op0, op1));
18402 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18403 DONE;
7a8e07c7
UB
18404})
18405
18406(define_expand "expm1xf2"
18407 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18408 (match_dup 2)))
18409 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18410 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
6bdcc60c 18411 (set (match_dup 9) (float_extend:XF (match_dup 13)))
7a8e07c7
UB
18412 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18413 (parallel [(set (match_dup 7)
18414 (unspec:XF [(match_dup 6) (match_dup 4)]
18415 UNSPEC_FSCALE_FRACT))
6bdcc60c 18416 (set (match_dup 8)
7a8e07c7
UB
18417 (unspec:XF [(match_dup 6) (match_dup 4)]
18418 UNSPEC_FSCALE_EXP))])
18419 (parallel [(set (match_dup 10)
18420 (unspec:XF [(match_dup 9) (match_dup 8)]
18421 UNSPEC_FSCALE_FRACT))
18422 (set (match_dup 11)
18423 (unspec:XF [(match_dup 9) (match_dup 8)]
18424 UNSPEC_FSCALE_EXP))])
6bdcc60c
UB
18425 (set (match_dup 12) (minus:XF (match_dup 10)
18426 (float_extend:XF (match_dup 13))))
7a8e07c7
UB
18427 (set (match_operand:XF 0 "register_operand" "")
18428 (plus:XF (match_dup 12) (match_dup 7)))]
ba2baa55 18429 "TARGET_USE_FANCY_MATH_387
18bd082d 18430 && flag_unsafe_math_optimizations"
7a8e07c7 18431{
7a8e07c7
UB
18432 int i;
18433
18bd082d
JH
18434 if (optimize_insn_for_size_p ())
18435 FAIL;
18436
e2fc57a3 18437 for (i = 2; i < 13; i++)
7a8e07c7 18438 operands[i] = gen_reg_rtx (XFmode);
6bdcc60c
UB
18439
18440 operands[13]
18441 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
18442
e2fc57a3 18443 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
7a8e07c7 18444})
c94a75af 18445
e2fc57a3 18446(define_expand "expm1<mode>2"
00188daa
UB
18447 [(use (match_operand:MODEF 0 "register_operand" ""))
18448 (use (match_operand:MODEF 1 "general_operand" ""))]
e2fc57a3
UB
18449 "TARGET_USE_FANCY_MATH_387
18450 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18451 || TARGET_MIX_SSE_I387)
18bd082d 18452 && flag_unsafe_math_optimizations"
c94a75af 18453{
18bd082d
JH
18454 rtx op0, op1;
18455
18456 if (optimize_insn_for_size_p ())
18457 FAIL;
18458
18459 op0 = gen_reg_rtx (XFmode);
18460 op1 = gen_reg_rtx (XFmode);
c94a75af 18461
e2fc57a3
UB
18462 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18463 emit_insn (gen_expm1xf2 (op0, op1));
18464 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18465 DONE;
c94a75af
UB
18466})
18467
18468(define_expand "ldexpxf3"
18469 [(set (match_dup 3)
18470 (float:XF (match_operand:SI 2 "register_operand" "")))
18471 (parallel [(set (match_operand:XF 0 " register_operand" "")
18472 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18473 (match_dup 3)]
18474 UNSPEC_FSCALE_FRACT))
18475 (set (match_dup 4)
18476 (unspec:XF [(match_dup 1) (match_dup 3)]
18477 UNSPEC_FSCALE_EXP))])]
18478 "TARGET_USE_FANCY_MATH_387
18bd082d 18479 && flag_unsafe_math_optimizations"
c94a75af 18480{
18bd082d
JH
18481 if (optimize_insn_for_size_p ())
18482 FAIL;
18483
e2fc57a3
UB
18484 operands[3] = gen_reg_rtx (XFmode);
18485 operands[4] = gen_reg_rtx (XFmode);
18486})
c94a75af 18487
e2fc57a3 18488(define_expand "ldexp<mode>3"
00188daa
UB
18489 [(use (match_operand:MODEF 0 "register_operand" ""))
18490 (use (match_operand:MODEF 1 "general_operand" ""))
e2fc57a3
UB
18491 (use (match_operand:SI 2 "register_operand" ""))]
18492 "TARGET_USE_FANCY_MATH_387
18493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18494 || TARGET_MIX_SSE_I387)
18bd082d 18495 && flag_unsafe_math_optimizations"
e2fc57a3 18496{
18bd082d
JH
18497 rtx op0, op1;
18498
18499 if (optimize_insn_for_size_p ())
18500 FAIL;
18501
18502 op0 = gen_reg_rtx (XFmode);
18503 op1 = gen_reg_rtx (XFmode);
e2fc57a3
UB
18504
18505 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18506 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
18507 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18508 DONE;
c94a75af 18509})
0c0d910d
KG
18510
18511(define_expand "scalbxf3"
18512 [(parallel [(set (match_operand:XF 0 " register_operand" "")
18513 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18514 (match_operand:XF 2 "register_operand" "")]
18515 UNSPEC_FSCALE_FRACT))
18516 (set (match_dup 3)
18517 (unspec:XF [(match_dup 1) (match_dup 2)]
18518 UNSPEC_FSCALE_EXP))])]
18519 "TARGET_USE_FANCY_MATH_387
18bd082d 18520 && flag_unsafe_math_optimizations"
0c0d910d 18521{
18bd082d
JH
18522 if (optimize_insn_for_size_p ())
18523 FAIL;
18524
0c0d910d
KG
18525 operands[3] = gen_reg_rtx (XFmode);
18526})
18527
18528(define_expand "scalb<mode>3"
00188daa
UB
18529 [(use (match_operand:MODEF 0 "register_operand" ""))
18530 (use (match_operand:MODEF 1 "general_operand" ""))
18531 (use (match_operand:MODEF 2 "register_operand" ""))]
0c0d910d
KG
18532 "TARGET_USE_FANCY_MATH_387
18533 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18534 || TARGET_MIX_SSE_I387)
18bd082d 18535 && flag_unsafe_math_optimizations"
0c0d910d 18536{
18bd082d
JH
18537 rtx op0, op1, op2;
18538
18539 if (optimize_insn_for_size_p ())
18540 FAIL;
18541
18542 op0 = gen_reg_rtx (XFmode);
18543 op1 = gen_reg_rtx (XFmode);
18544 op2 = gen_reg_rtx (XFmode);
0c0d910d
KG
18545
18546 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18547 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18548 emit_insn (gen_scalbxf3 (op0, op1, op2));
18549 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18550 DONE;
18551})
edeacc14
UB
18552\f
18553
f28eb39c 18554(define_insn "sse4_1_round<mode>2"
00188daa
UB
18555 [(set (match_operand:MODEF 0 "register_operand" "=x")
18556 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18557 (match_operand:SI 2 "const_0_to_15_operand" "n")]
18558 UNSPEC_ROUND))]
04e1d06b 18559 "TARGET_ROUND"
95879c72 18560 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
f28eb39c
UB
18561 [(set_attr "type" "ssecvt")
18562 (set_attr "prefix_extra" "1")
95879c72 18563 (set_attr "prefix" "maybe_vex")
f28eb39c
UB
18564 (set_attr "mode" "<MODE>")])
18565
acaaf0c6 18566(define_insn "rintxf2"
edeacc14
UB
18567 [(set (match_operand:XF 0 "register_operand" "=f")
18568 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
acaaf0c6 18569 UNSPEC_FRNDINT))]
ba2baa55 18570 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
18571 && flag_unsafe_math_optimizations"
18572 "frndint"
18573 [(set_attr "type" "fpspc")
18574 (set_attr "mode" "XF")])
18575
acaaf0c6 18576(define_expand "rint<mode>2"
00188daa
UB
18577 [(use (match_operand:MODEF 0 "register_operand" ""))
18578 (use (match_operand:MODEF 1 "register_operand" ""))]
c7d32ff6 18579 "(TARGET_USE_FANCY_MATH_387
acaaf0c6
UB
18580 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18581 || TARGET_MIX_SSE_I387)
c7d32ff6 18582 && flag_unsafe_math_optimizations)
acaaf0c6 18583 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 18584 && !flag_trapping_math)"
c7d32ff6 18585{
acaaf0c6 18586 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 18587 && !flag_trapping_math)
f28eb39c 18588 {
18bd082d
JH
18589 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18590 FAIL;
04e1d06b 18591 if (TARGET_ROUND)
f28eb39c
UB
18592 emit_insn (gen_sse4_1_round<mode>2
18593 (operands[0], operands[1], GEN_INT (0x04)));
18594 else
18595 ix86_expand_rint (operand0, operand1);
18596 }
c7d32ff6
RG
18597 else
18598 {
1d08f955
RG
18599 rtx op0 = gen_reg_rtx (XFmode);
18600 rtx op1 = gen_reg_rtx (XFmode);
edeacc14 18601
acaaf0c6
UB
18602 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18603 emit_insn (gen_rintxf2 (op0, op1));
edeacc14 18604
acaaf0c6 18605 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
c7d32ff6 18606 }
edeacc14
UB
18607 DONE;
18608})
18609
acaaf0c6 18610(define_expand "round<mode>2"
00188daa
UB
18611 [(match_operand:MODEF 0 "register_operand" "")
18612 (match_operand:MODEF 1 "nonimmediate_operand" "")]
acaaf0c6 18613 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 18614 && !flag_trapping_math && !flag_rounding_math"
097f2964 18615{
18bd082d
JH
18616 if (optimize_insn_for_size_p ())
18617 FAIL;
f28eb39c 18618 if (TARGET_64BIT || (<MODE>mode != DFmode))
097f2964
RG
18619 ix86_expand_round (operand0, operand1);
18620 else
18621 ix86_expand_rounddf_32 (operand0, operand1);
18622 DONE;
18623})
18624
4d06b0a2 18625(define_insn_and_split "*fistdi2_1"
00188daa
UB
18626 [(set (match_operand:DI 0 "nonimmediate_operand" "")
18627 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 18628 UNSPEC_FIST))]
87bb8864 18629 "TARGET_USE_FANCY_MATH_387
87bb8864
UB
18630 && !(reload_completed || reload_in_progress)"
18631 "#"
18632 "&& 1"
18633 [(const_int 0)]
18634{
18635 if (memory_operand (operands[0], VOIDmode))
4d06b0a2 18636 emit_insn (gen_fistdi2 (operands[0], operands[1]));
87bb8864
UB
18637 else
18638 {
4d06b0a2
UB
18639 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18640 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18641 operands[2]));
87bb8864
UB
18642 }
18643 DONE;
18644}
18645 [(set_attr "type" "fpspc")
4d06b0a2 18646 (set_attr "mode" "DI")])
87bb8864 18647
6e858d45
UB
18648(define_insn "fistdi2"
18649 [(set (match_operand:DI 0 "memory_operand" "=m")
18650 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
acaaf0c6 18651 UNSPEC_FIST))
6e858d45 18652 (clobber (match_scratch:XF 2 "=&1f"))]
bb7f0423 18653 "TARGET_USE_FANCY_MATH_387"
6e858d45
UB
18654 "* return output_fix_trunc (insn, operands, 0);"
18655 [(set_attr "type" "fpspc")
18656 (set_attr "mode" "DI")])
18657
18658(define_insn "fistdi2_with_temp"
18659 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18660 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
acaaf0c6 18661 UNSPEC_FIST))
73e8165a 18662 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
6e858d45 18663 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
bb7f0423 18664 "TARGET_USE_FANCY_MATH_387"
6e858d45
UB
18665 "#"
18666 [(set_attr "type" "fpspc")
18667 (set_attr "mode" "DI")])
18668
6300f037 18669(define_split
6e858d45
UB
18670 [(set (match_operand:DI 0 "register_operand" "")
18671 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 18672 UNSPEC_FIST))
6e858d45
UB
18673 (clobber (match_operand:DI 2 "memory_operand" ""))
18674 (clobber (match_scratch 3 ""))]
18675 "reload_completed"
18676 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18677 (clobber (match_dup 3))])
18678 (set (match_dup 0) (match_dup 2))]
18679 "")
18680
6300f037 18681(define_split
6e858d45
UB
18682 [(set (match_operand:DI 0 "memory_operand" "")
18683 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 18684 UNSPEC_FIST))
6e858d45
UB
18685 (clobber (match_operand:DI 2 "memory_operand" ""))
18686 (clobber (match_scratch 3 ""))]
18687 "reload_completed"
18688 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18689 (clobber (match_dup 3))])]
18690 "")
18691
4d06b0a2 18692(define_insn_and_split "*fist<mode>2_1"
00188daa
UB
18693 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18694 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 18695 UNSPEC_FIST))]
4d06b0a2 18696 "TARGET_USE_FANCY_MATH_387
4d06b0a2
UB
18697 && !(reload_completed || reload_in_progress)"
18698 "#"
18699 "&& 1"
18700 [(const_int 0)]
18701{
18702 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18703 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18704 operands[2]));
18705 DONE;
18706}
18707 [(set_attr "type" "fpspc")
18708 (set_attr "mode" "<MODE>")])
18709
6e858d45
UB
18710(define_insn "fist<mode>2"
18711 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18712 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
acaaf0c6 18713 UNSPEC_FIST))]
bb7f0423 18714 "TARGET_USE_FANCY_MATH_387"
6e858d45
UB
18715 "* return output_fix_trunc (insn, operands, 0);"
18716 [(set_attr "type" "fpspc")
18717 (set_attr "mode" "<MODE>")])
18718
18719(define_insn "fist<mode>2_with_temp"
4d06b0a2
UB
18720 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18721 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
acaaf0c6 18722 UNSPEC_FIST))
4d06b0a2 18723 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
bb7f0423 18724 "TARGET_USE_FANCY_MATH_387"
6e858d45
UB
18725 "#"
18726 [(set_attr "type" "fpspc")
18727 (set_attr "mode" "<MODE>")])
18728
6300f037 18729(define_split
6e858d45
UB
18730 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18731 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 18732 UNSPEC_FIST))
6e858d45
UB
18733 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18734 "reload_completed"
acaaf0c6 18735 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
6e858d45
UB
18736 (set (match_dup 0) (match_dup 2))]
18737 "")
18738
6300f037 18739(define_split
6e858d45
UB
18740 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18741 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 18742 UNSPEC_FIST))
cec471db 18743 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
6e858d45 18744 "reload_completed"
acaaf0c6 18745 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
6e858d45
UB
18746 "")
18747
bb7f0423 18748(define_expand "lrintxf<mode>2"
87bb8864 18749 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
bb7f0423 18750 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
acaaf0c6 18751 UNSPEC_FIST))]
bb7f0423
RG
18752 "TARGET_USE_FANCY_MATH_387"
18753 "")
18754
00188daa 18755(define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
acaaf0c6 18756 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
00188daa 18757 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
acaaf0c6 18758 UNSPEC_FIX_NOTRUNC))]
00188daa 18759 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
acaaf0c6 18760 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
bb7f0423
RG
18761 "")
18762
00188daa 18763(define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
acaaf0c6 18764 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
00188daa
UB
18765 (match_operand:MODEF 1 "register_operand" "")]
18766 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
acaaf0c6 18767 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18bd082d 18768 && !flag_trapping_math && !flag_rounding_math"
4d81bf84 18769{
18bd082d
JH
18770 if (optimize_insn_for_size_p ())
18771 FAIL;
4d81bf84
RG
18772 ix86_expand_lround (operand0, operand1);
18773 DONE;
18774})
18775
c9d3aede
UB
18776;; Rounding mode control word calculation could clobber FLAGS_REG.
18777(define_insn_and_split "frndintxf2_floor"
00188daa
UB
18778 [(set (match_operand:XF 0 "register_operand" "")
18779 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
c9d3aede
UB
18780 UNSPEC_FRNDINT_FLOOR))
18781 (clobber (reg:CC FLAGS_REG))]
18782 "TARGET_USE_FANCY_MATH_387
18783 && flag_unsafe_math_optimizations
18784 && !(reload_completed || reload_in_progress)"
18785 "#"
18786 "&& 1"
18787 [(const_int 0)]
18788{
ff680eb1 18789 ix86_optimize_mode_switching[I387_FLOOR] = 1;
c9d3aede 18790
ff680eb1
UB
18791 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18792 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
c9d3aede
UB
18793
18794 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18795 operands[2], operands[3]));
18796 DONE;
18797}
18798 [(set_attr "type" "frndint")
18799 (set_attr "i387_cw" "floor")
18800 (set_attr "mode" "XF")])
18801
18802(define_insn "frndintxf2_floor_i387"
edeacc14
UB
18803 [(set (match_operand:XF 0 "register_operand" "=f")
18804 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18805 UNSPEC_FRNDINT_FLOOR))
18806 (use (match_operand:HI 2 "memory_operand" "m"))
18807 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 18808 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
18809 && flag_unsafe_math_optimizations"
18810 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18811 [(set_attr "type" "frndint")
18812 (set_attr "i387_cw" "floor")
18813 (set_attr "mode" "XF")])
18814
c9d3aede
UB
18815(define_expand "floorxf2"
18816 [(use (match_operand:XF 0 "register_operand" ""))
18817 (use (match_operand:XF 1 "register_operand" ""))]
18818 "TARGET_USE_FANCY_MATH_387
18bd082d 18819 && flag_unsafe_math_optimizations"
c9d3aede 18820{
18bd082d
JH
18821 if (optimize_insn_for_size_p ())
18822 FAIL;
c9d3aede
UB
18823 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18824 DONE;
18825})
18826
f28eb39c 18827(define_expand "floor<mode>2"
00188daa
UB
18828 [(use (match_operand:MODEF 0 "register_operand" ""))
18829 (use (match_operand:MODEF 1 "register_operand" ""))]
f28eb39c
UB
18830 "(TARGET_USE_FANCY_MATH_387
18831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18832 || TARGET_MIX_SSE_I387)
18bd082d 18833 && flag_unsafe_math_optimizations)
f28eb39c 18834 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 18835 && !flag_trapping_math)"
edeacc14 18836{
f28eb39c
UB
18837 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18838 && !flag_trapping_math
18bd082d 18839 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
d096ecdd 18840 {
18bd082d
JH
18841 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18842 FAIL;
04e1d06b 18843 if (TARGET_ROUND)
f28eb39c
UB
18844 emit_insn (gen_sse4_1_round<mode>2
18845 (operands[0], operands[1], GEN_INT (0x01)));
18846 else if (TARGET_64BIT || (<MODE>mode != DFmode))
d096ecdd
RG
18847 ix86_expand_floorceil (operand0, operand1, true);
18848 else
18849 ix86_expand_floorceildf_32 (operand0, operand1, true);
18850 }
18851 else
18852 {
18bd082d
JH
18853 rtx op0, op1;
18854
18855 if (optimize_insn_for_size_p ())
18856 FAIL;
edeacc14 18857
18bd082d
JH
18858 op0 = gen_reg_rtx (XFmode);
18859 op1 = gen_reg_rtx (XFmode);
f28eb39c 18860 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
d096ecdd 18861 emit_insn (gen_frndintxf2_floor (op0, op1));
edeacc14 18862
f28eb39c 18863 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
d096ecdd 18864 }
edeacc14
UB
18865 DONE;
18866})
18867
4a927664 18868(define_insn_and_split "*fist<mode>2_floor_1"
00188daa
UB
18869 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18870 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
4a927664
UB
18871 UNSPEC_FIST_FLOOR))
18872 (clobber (reg:CC FLAGS_REG))]
18873 "TARGET_USE_FANCY_MATH_387
18874 && flag_unsafe_math_optimizations
18875 && !(reload_completed || reload_in_progress)"
18876 "#"
18877 "&& 1"
18878 [(const_int 0)]
18879{
ff680eb1
UB
18880 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18881
18882 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18883 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
4a927664
UB
18884 if (memory_operand (operands[0], VOIDmode))
18885 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18886 operands[2], operands[3]));
18887 else
18888 {
ff680eb1 18889 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4a927664
UB
18890 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18891 operands[2], operands[3],
18892 operands[4]));
18893 }
18894 DONE;
18895}
18896 [(set_attr "type" "fistp")
18897 (set_attr "i387_cw" "floor")
18898 (set_attr "mode" "<MODE>")])
18899
18900(define_insn "fistdi2_floor"
18901 [(set (match_operand:DI 0 "memory_operand" "=m")
18902 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18903 UNSPEC_FIST_FLOOR))
18904 (use (match_operand:HI 2 "memory_operand" "m"))
18905 (use (match_operand:HI 3 "memory_operand" "m"))
18906 (clobber (match_scratch:XF 4 "=&1f"))]
18907 "TARGET_USE_FANCY_MATH_387
18908 && flag_unsafe_math_optimizations"
18909 "* return output_fix_trunc (insn, operands, 0);"
18910 [(set_attr "type" "fistp")
18911 (set_attr "i387_cw" "floor")
18912 (set_attr "mode" "DI")])
18913
18914(define_insn "fistdi2_floor_with_temp"
18915 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18916 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18917 UNSPEC_FIST_FLOOR))
18918 (use (match_operand:HI 2 "memory_operand" "m,m"))
18919 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 18920 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4a927664
UB
18921 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18922 "TARGET_USE_FANCY_MATH_387
18923 && flag_unsafe_math_optimizations"
18924 "#"
18925 [(set_attr "type" "fistp")
18926 (set_attr "i387_cw" "floor")
18927 (set_attr "mode" "DI")])
18928
6300f037 18929(define_split
4a927664
UB
18930 [(set (match_operand:DI 0 "register_operand" "")
18931 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18932 UNSPEC_FIST_FLOOR))
18933 (use (match_operand:HI 2 "memory_operand" ""))
18934 (use (match_operand:HI 3 "memory_operand" ""))
18935 (clobber (match_operand:DI 4 "memory_operand" ""))
18936 (clobber (match_scratch 5 ""))]
18937 "reload_completed"
18938 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18939 (use (match_dup 2))
18940 (use (match_dup 3))
18941 (clobber (match_dup 5))])
18942 (set (match_dup 0) (match_dup 4))]
18943 "")
18944
6300f037 18945(define_split
4a927664
UB
18946 [(set (match_operand:DI 0 "memory_operand" "")
18947 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18948 UNSPEC_FIST_FLOOR))
18949 (use (match_operand:HI 2 "memory_operand" ""))
18950 (use (match_operand:HI 3 "memory_operand" ""))
18951 (clobber (match_operand:DI 4 "memory_operand" ""))
18952 (clobber (match_scratch 5 ""))]
18953 "reload_completed"
18954 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18955 (use (match_dup 2))
18956 (use (match_dup 3))
18957 (clobber (match_dup 5))])]
18958 "")
18959
18960(define_insn "fist<mode>2_floor"
18961 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18962 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18963 UNSPEC_FIST_FLOOR))
18964 (use (match_operand:HI 2 "memory_operand" "m"))
18965 (use (match_operand:HI 3 "memory_operand" "m"))]
18966 "TARGET_USE_FANCY_MATH_387
18967 && flag_unsafe_math_optimizations"
18968 "* return output_fix_trunc (insn, operands, 0);"
18969 [(set_attr "type" "fistp")
18970 (set_attr "i387_cw" "floor")
18971 (set_attr "mode" "<MODE>")])
18972
18973(define_insn "fist<mode>2_floor_with_temp"
18974 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18975 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18976 UNSPEC_FIST_FLOOR))
18977 (use (match_operand:HI 2 "memory_operand" "m,m"))
18978 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 18979 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4a927664
UB
18980 "TARGET_USE_FANCY_MATH_387
18981 && flag_unsafe_math_optimizations"
18982 "#"
18983 [(set_attr "type" "fistp")
18984 (set_attr "i387_cw" "floor")
18985 (set_attr "mode" "<MODE>")])
18986
6300f037 18987(define_split
4a927664
UB
18988 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18989 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18990 UNSPEC_FIST_FLOOR))
18991 (use (match_operand:HI 2 "memory_operand" ""))
18992 (use (match_operand:HI 3 "memory_operand" ""))
18993 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18994 "reload_completed"
18995 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18996 UNSPEC_FIST_FLOOR))
18997 (use (match_dup 2))
18998 (use (match_dup 3))])
18999 (set (match_dup 0) (match_dup 4))]
19000 "")
19001
6300f037 19002(define_split
4a927664
UB
19003 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19004 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19005 UNSPEC_FIST_FLOOR))
19006 (use (match_operand:HI 2 "memory_operand" ""))
19007 (use (match_operand:HI 3 "memory_operand" ""))
19008 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19009 "reload_completed"
19010 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19011 UNSPEC_FIST_FLOOR))
19012 (use (match_dup 2))
19013 (use (match_dup 3))])]
19014 "")
19015
c3a4177f 19016(define_expand "lfloorxf<mode>2"
4a927664
UB
19017 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19018 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19019 UNSPEC_FIST_FLOOR))
19020 (clobber (reg:CC FLAGS_REG))])]
19021 "TARGET_USE_FANCY_MATH_387
19022 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19023 && flag_unsafe_math_optimizations"
19024 "")
19025
c3a4177f
RG
19026(define_expand "lfloor<mode>di2"
19027 [(match_operand:DI 0 "nonimmediate_operand" "")
00188daa 19028 (match_operand:MODEF 1 "register_operand" "")]
c3a4177f 19029 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18bd082d 19030 && !flag_trapping_math"
c3a4177f 19031{
18bd082d
JH
19032 if (optimize_insn_for_size_p ())
19033 FAIL;
c3a4177f
RG
19034 ix86_expand_lfloorceil (operand0, operand1, true);
19035 DONE;
19036})
19037
19038(define_expand "lfloor<mode>si2"
19039 [(match_operand:SI 0 "nonimmediate_operand" "")
00188daa 19040 (match_operand:MODEF 1 "register_operand" "")]
c3a4177f 19041 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 19042 && !flag_trapping_math"
c3a4177f 19043{
18bd082d
JH
19044 if (optimize_insn_for_size_p () && TARGET_64BIT)
19045 FAIL;
c3a4177f
RG
19046 ix86_expand_lfloorceil (operand0, operand1, true);
19047 DONE;
19048})
19049
c9d3aede
UB
19050;; Rounding mode control word calculation could clobber FLAGS_REG.
19051(define_insn_and_split "frndintxf2_ceil"
00188daa
UB
19052 [(set (match_operand:XF 0 "register_operand" "")
19053 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
c9d3aede
UB
19054 UNSPEC_FRNDINT_CEIL))
19055 (clobber (reg:CC FLAGS_REG))]
ba2baa55 19056 "TARGET_USE_FANCY_MATH_387
c9d3aede
UB
19057 && flag_unsafe_math_optimizations
19058 && !(reload_completed || reload_in_progress)"
19059 "#"
19060 "&& 1"
19061 [(const_int 0)]
edeacc14 19062{
ff680eb1 19063 ix86_optimize_mode_switching[I387_CEIL] = 1;
edeacc14 19064
ff680eb1
UB
19065 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19066 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
c9d3aede
UB
19067
19068 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
19069 operands[2], operands[3]));
edeacc14 19070 DONE;
c9d3aede
UB
19071}
19072 [(set_attr "type" "frndint")
19073 (set_attr "i387_cw" "ceil")
19074 (set_attr "mode" "XF")])
edeacc14 19075
c9d3aede 19076(define_insn "frndintxf2_ceil_i387"
edeacc14
UB
19077 [(set (match_operand:XF 0 "register_operand" "=f")
19078 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19079 UNSPEC_FRNDINT_CEIL))
19080 (use (match_operand:HI 2 "memory_operand" "m"))
19081 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 19082 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
19083 && flag_unsafe_math_optimizations"
19084 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19085 [(set_attr "type" "frndint")
19086 (set_attr "i387_cw" "ceil")
19087 (set_attr "mode" "XF")])
19088
c9d3aede
UB
19089(define_expand "ceilxf2"
19090 [(use (match_operand:XF 0 "register_operand" ""))
19091 (use (match_operand:XF 1 "register_operand" ""))]
19092 "TARGET_USE_FANCY_MATH_387
18bd082d 19093 && flag_unsafe_math_optimizations"
c9d3aede 19094{
18bd082d
JH
19095 if (optimize_insn_for_size_p ())
19096 FAIL;
c9d3aede
UB
19097 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
19098 DONE;
19099})
19100
f28eb39c 19101(define_expand "ceil<mode>2"
00188daa
UB
19102 [(use (match_operand:MODEF 0 "register_operand" ""))
19103 (use (match_operand:MODEF 1 "register_operand" ""))]
f28eb39c
UB
19104 "(TARGET_USE_FANCY_MATH_387
19105 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19106 || TARGET_MIX_SSE_I387)
18bd082d 19107 && flag_unsafe_math_optimizations)
f28eb39c 19108 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 19109 && !flag_trapping_math)"
edeacc14 19110{
f28eb39c
UB
19111 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19112 && !flag_trapping_math
18bd082d 19113 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
d096ecdd 19114 {
04e1d06b 19115 if (TARGET_ROUND)
f28eb39c
UB
19116 emit_insn (gen_sse4_1_round<mode>2
19117 (operands[0], operands[1], GEN_INT (0x02)));
18bd082d
JH
19118 else if (optimize_insn_for_size_p ())
19119 FAIL;
f28eb39c 19120 else if (TARGET_64BIT || (<MODE>mode != DFmode))
d096ecdd
RG
19121 ix86_expand_floorceil (operand0, operand1, false);
19122 else
19123 ix86_expand_floorceildf_32 (operand0, operand1, false);
19124 }
19125 else
19126 {
18bd082d
JH
19127 rtx op0, op1;
19128
19129 if (optimize_insn_for_size_p ())
19130 FAIL;
edeacc14 19131
18bd082d
JH
19132 op0 = gen_reg_rtx (XFmode);
19133 op1 = gen_reg_rtx (XFmode);
f28eb39c 19134 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
d096ecdd 19135 emit_insn (gen_frndintxf2_ceil (op0, op1));
edeacc14 19136
f28eb39c 19137 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
d096ecdd 19138 }
edeacc14
UB
19139 DONE;
19140})
19141
4a927664 19142(define_insn_and_split "*fist<mode>2_ceil_1"
00188daa
UB
19143 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19144 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
4a927664
UB
19145 UNSPEC_FIST_CEIL))
19146 (clobber (reg:CC FLAGS_REG))]
19147 "TARGET_USE_FANCY_MATH_387
19148 && flag_unsafe_math_optimizations
19149 && !(reload_completed || reload_in_progress)"
19150 "#"
19151 "&& 1"
19152 [(const_int 0)]
19153{
ff680eb1
UB
19154 ix86_optimize_mode_switching[I387_CEIL] = 1;
19155
19156 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19157 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
4a927664
UB
19158 if (memory_operand (operands[0], VOIDmode))
19159 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
19160 operands[2], operands[3]));
19161 else
19162 {
ff680eb1 19163 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4a927664
UB
19164 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
19165 operands[2], operands[3],
19166 operands[4]));
19167 }
19168 DONE;
19169}
19170 [(set_attr "type" "fistp")
19171 (set_attr "i387_cw" "ceil")
19172 (set_attr "mode" "<MODE>")])
19173
19174(define_insn "fistdi2_ceil"
19175 [(set (match_operand:DI 0 "memory_operand" "=m")
19176 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
19177 UNSPEC_FIST_CEIL))
19178 (use (match_operand:HI 2 "memory_operand" "m"))
19179 (use (match_operand:HI 3 "memory_operand" "m"))
19180 (clobber (match_scratch:XF 4 "=&1f"))]
19181 "TARGET_USE_FANCY_MATH_387
19182 && flag_unsafe_math_optimizations"
19183 "* return output_fix_trunc (insn, operands, 0);"
19184 [(set_attr "type" "fistp")
19185 (set_attr "i387_cw" "ceil")
19186 (set_attr "mode" "DI")])
19187
19188(define_insn "fistdi2_ceil_with_temp"
19189 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
19190 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
19191 UNSPEC_FIST_CEIL))
19192 (use (match_operand:HI 2 "memory_operand" "m,m"))
19193 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 19194 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4a927664
UB
19195 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
19196 "TARGET_USE_FANCY_MATH_387
19197 && flag_unsafe_math_optimizations"
19198 "#"
19199 [(set_attr "type" "fistp")
19200 (set_attr "i387_cw" "ceil")
19201 (set_attr "mode" "DI")])
19202
6300f037 19203(define_split
4a927664
UB
19204 [(set (match_operand:DI 0 "register_operand" "")
19205 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19206 UNSPEC_FIST_CEIL))
19207 (use (match_operand:HI 2 "memory_operand" ""))
19208 (use (match_operand:HI 3 "memory_operand" ""))
19209 (clobber (match_operand:DI 4 "memory_operand" ""))
19210 (clobber (match_scratch 5 ""))]
19211 "reload_completed"
19212 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19213 (use (match_dup 2))
19214 (use (match_dup 3))
19215 (clobber (match_dup 5))])
19216 (set (match_dup 0) (match_dup 4))]
19217 "")
19218
6300f037 19219(define_split
4a927664
UB
19220 [(set (match_operand:DI 0 "memory_operand" "")
19221 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19222 UNSPEC_FIST_CEIL))
19223 (use (match_operand:HI 2 "memory_operand" ""))
19224 (use (match_operand:HI 3 "memory_operand" ""))
19225 (clobber (match_operand:DI 4 "memory_operand" ""))
19226 (clobber (match_scratch 5 ""))]
19227 "reload_completed"
19228 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19229 (use (match_dup 2))
19230 (use (match_dup 3))
19231 (clobber (match_dup 5))])]
19232 "")
19233
19234(define_insn "fist<mode>2_ceil"
19235 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
19236 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
19237 UNSPEC_FIST_CEIL))
19238 (use (match_operand:HI 2 "memory_operand" "m"))
19239 (use (match_operand:HI 3 "memory_operand" "m"))]
19240 "TARGET_USE_FANCY_MATH_387
19241 && flag_unsafe_math_optimizations"
19242 "* return output_fix_trunc (insn, operands, 0);"
19243 [(set_attr "type" "fistp")
19244 (set_attr "i387_cw" "ceil")
19245 (set_attr "mode" "<MODE>")])
19246
19247(define_insn "fist<mode>2_ceil_with_temp"
19248 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
19249 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
19250 UNSPEC_FIST_CEIL))
19251 (use (match_operand:HI 2 "memory_operand" "m,m"))
19252 (use (match_operand:HI 3 "memory_operand" "m,m"))
73e8165a 19253 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4a927664
UB
19254 "TARGET_USE_FANCY_MATH_387
19255 && flag_unsafe_math_optimizations"
19256 "#"
19257 [(set_attr "type" "fistp")
19258 (set_attr "i387_cw" "ceil")
19259 (set_attr "mode" "<MODE>")])
19260
6300f037 19261(define_split
4a927664
UB
19262 [(set (match_operand:X87MODEI12 0 "register_operand" "")
19263 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19264 UNSPEC_FIST_CEIL))
19265 (use (match_operand:HI 2 "memory_operand" ""))
19266 (use (match_operand:HI 3 "memory_operand" ""))
19267 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19268 "reload_completed"
19269 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
19270 UNSPEC_FIST_CEIL))
19271 (use (match_dup 2))
19272 (use (match_dup 3))])
19273 (set (match_dup 0) (match_dup 4))]
19274 "")
19275
6300f037 19276(define_split
4a927664
UB
19277 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19278 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19279 UNSPEC_FIST_CEIL))
19280 (use (match_operand:HI 2 "memory_operand" ""))
19281 (use (match_operand:HI 3 "memory_operand" ""))
19282 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19283 "reload_completed"
19284 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19285 UNSPEC_FIST_CEIL))
19286 (use (match_dup 2))
19287 (use (match_dup 3))])]
19288 "")
19289
c3a4177f 19290(define_expand "lceilxf<mode>2"
4a927664
UB
19291 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19292 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19293 UNSPEC_FIST_CEIL))
19294 (clobber (reg:CC FLAGS_REG))])]
19295 "TARGET_USE_FANCY_MATH_387
19296 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19297 && flag_unsafe_math_optimizations"
19298 "")
19299
c3a4177f
RG
19300(define_expand "lceil<mode>di2"
19301 [(match_operand:DI 0 "nonimmediate_operand" "")
00188daa 19302 (match_operand:MODEF 1 "register_operand" "")]
c3a4177f
RG
19303 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
19304 && !flag_trapping_math"
19305{
19306 ix86_expand_lfloorceil (operand0, operand1, false);
19307 DONE;
19308})
19309
19310(define_expand "lceil<mode>si2"
19311 [(match_operand:SI 0 "nonimmediate_operand" "")
00188daa 19312 (match_operand:MODEF 1 "register_operand" "")]
c3a4177f
RG
19313 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19314 && !flag_trapping_math"
19315{
19316 ix86_expand_lfloorceil (operand0, operand1, false);
19317 DONE;
19318})
19319
c9d3aede
UB
19320;; Rounding mode control word calculation could clobber FLAGS_REG.
19321(define_insn_and_split "frndintxf2_trunc"
00188daa
UB
19322 [(set (match_operand:XF 0 "register_operand" "")
19323 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
c9d3aede
UB
19324 UNSPEC_FRNDINT_TRUNC))
19325 (clobber (reg:CC FLAGS_REG))]
ba2baa55 19326 "TARGET_USE_FANCY_MATH_387
c9d3aede
UB
19327 && flag_unsafe_math_optimizations
19328 && !(reload_completed || reload_in_progress)"
19329 "#"
19330 "&& 1"
19331 [(const_int 0)]
edeacc14 19332{
ff680eb1 19333 ix86_optimize_mode_switching[I387_TRUNC] = 1;
edeacc14 19334
ff680eb1
UB
19335 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19336 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
c9d3aede
UB
19337
19338 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
19339 operands[2], operands[3]));
edeacc14 19340 DONE;
c9d3aede
UB
19341}
19342 [(set_attr "type" "frndint")
19343 (set_attr "i387_cw" "trunc")
19344 (set_attr "mode" "XF")])
edeacc14 19345
c9d3aede 19346(define_insn "frndintxf2_trunc_i387"
edeacc14
UB
19347 [(set (match_operand:XF 0 "register_operand" "=f")
19348 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19349 UNSPEC_FRNDINT_TRUNC))
19350 (use (match_operand:HI 2 "memory_operand" "m"))
19351 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 19352 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
19353 && flag_unsafe_math_optimizations"
19354 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19355 [(set_attr "type" "frndint")
19356 (set_attr "i387_cw" "trunc")
19357 (set_attr "mode" "XF")])
19358
c9d3aede
UB
19359(define_expand "btruncxf2"
19360 [(use (match_operand:XF 0 "register_operand" ""))
19361 (use (match_operand:XF 1 "register_operand" ""))]
19362 "TARGET_USE_FANCY_MATH_387
18bd082d 19363 && flag_unsafe_math_optimizations"
c9d3aede 19364{
18bd082d
JH
19365 if (optimize_insn_for_size_p ())
19366 FAIL;
c9d3aede
UB
19367 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
19368 DONE;
19369})
19370
f28eb39c 19371(define_expand "btrunc<mode>2"
00188daa
UB
19372 [(use (match_operand:MODEF 0 "register_operand" ""))
19373 (use (match_operand:MODEF 1 "register_operand" ""))]
f28eb39c
UB
19374 "(TARGET_USE_FANCY_MATH_387
19375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19376 || TARGET_MIX_SSE_I387)
18bd082d 19377 && flag_unsafe_math_optimizations)
f28eb39c 19378 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18bd082d 19379 && !flag_trapping_math)"
edeacc14 19380{
f28eb39c
UB
19381 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19382 && !flag_trapping_math
18bd082d 19383 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
044928d6 19384 {
04e1d06b 19385 if (TARGET_ROUND)
f28eb39c
UB
19386 emit_insn (gen_sse4_1_round<mode>2
19387 (operands[0], operands[1], GEN_INT (0x03)));
18bd082d
JH
19388 else if (optimize_insn_for_size_p ())
19389 FAIL;
f28eb39c 19390 else if (TARGET_64BIT || (<MODE>mode != DFmode))
044928d6
RG
19391 ix86_expand_trunc (operand0, operand1);
19392 else
19393 ix86_expand_truncdf_32 (operand0, operand1);
19394 }
19395 else
19396 {
18bd082d
JH
19397 rtx op0, op1;
19398
19399 if (optimize_insn_for_size_p ())
19400 FAIL;
edeacc14 19401
18bd082d
JH
19402 op0 = gen_reg_rtx (XFmode);
19403 op1 = gen_reg_rtx (XFmode);
f28eb39c 19404 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
044928d6 19405 emit_insn (gen_frndintxf2_trunc (op0, op1));
edeacc14 19406
f28eb39c 19407 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
044928d6 19408 }
edeacc14
UB
19409 DONE;
19410})
19411
c9d3aede
UB
19412;; Rounding mode control word calculation could clobber FLAGS_REG.
19413(define_insn_and_split "frndintxf2_mask_pm"
00188daa
UB
19414 [(set (match_operand:XF 0 "register_operand" "")
19415 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
c9d3aede
UB
19416 UNSPEC_FRNDINT_MASK_PM))
19417 (clobber (reg:CC FLAGS_REG))]
ba2baa55 19418 "TARGET_USE_FANCY_MATH_387
c9d3aede
UB
19419 && flag_unsafe_math_optimizations
19420 && !(reload_completed || reload_in_progress)"
19421 "#"
19422 "&& 1"
19423 [(const_int 0)]
edeacc14 19424{
ff680eb1 19425 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
edeacc14 19426
ff680eb1
UB
19427 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19428 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
c9d3aede
UB
19429
19430 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
19431 operands[2], operands[3]));
edeacc14 19432 DONE;
c9d3aede
UB
19433}
19434 [(set_attr "type" "frndint")
19435 (set_attr "i387_cw" "mask_pm")
19436 (set_attr "mode" "XF")])
edeacc14 19437
c9d3aede 19438(define_insn "frndintxf2_mask_pm_i387"
edeacc14
UB
19439 [(set (match_operand:XF 0 "register_operand" "=f")
19440 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19441 UNSPEC_FRNDINT_MASK_PM))
19442 (use (match_operand:HI 2 "memory_operand" "m"))
19443 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 19444 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
19445 && flag_unsafe_math_optimizations"
19446 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
19447 [(set_attr "type" "frndint")
19448 (set_attr "i387_cw" "mask_pm")
19449 (set_attr "mode" "XF")])
19450
c9d3aede
UB
19451(define_expand "nearbyintxf2"
19452 [(use (match_operand:XF 0 "register_operand" ""))
19453 (use (match_operand:XF 1 "register_operand" ""))]
19454 "TARGET_USE_FANCY_MATH_387
19455 && flag_unsafe_math_optimizations"
19456{
19457 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
19458
19459 DONE;
19460})
19461
00188daa
UB
19462(define_expand "nearbyint<mode>2"
19463 [(use (match_operand:MODEF 0 "register_operand" ""))
19464 (use (match_operand:MODEF 1 "register_operand" ""))]
ba2baa55 19465 "TARGET_USE_FANCY_MATH_387
00188daa
UB
19466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19467 || TARGET_MIX_SSE_I387)
edeacc14
UB
19468 && flag_unsafe_math_optimizations"
19469{
19470 rtx op0 = gen_reg_rtx (XFmode);
19471 rtx op1 = gen_reg_rtx (XFmode);
edeacc14 19472
00188daa 19473 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
c9d3aede 19474 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
edeacc14 19475
00188daa 19476 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
edeacc14
UB
19477 DONE;
19478})
19479
9ed4207f
UB
19480(define_insn "fxam<mode>2_i387"
19481 [(set (match_operand:HI 0 "register_operand" "=a")
19482 (unspec:HI
19483 [(match_operand:X87MODEF 1 "register_operand" "f")]
19484 UNSPEC_FXAM))]
19485 "TARGET_USE_FANCY_MATH_387"
19486 "fxam\n\tfnstsw\t%0"
19487 [(set_attr "type" "multi")
725fd454 19488 (set_attr "length" "4")
9ed4207f
UB
19489 (set_attr "unit" "i387")
19490 (set_attr "mode" "<MODE>")])
19491
6b67572e
UB
19492(define_insn_and_split "fxam<mode>2_i387_with_temp"
19493 [(set (match_operand:HI 0 "register_operand" "")
19494 (unspec:HI
19495 [(match_operand:MODEF 1 "memory_operand" "")]
19496 UNSPEC_FXAM_MEM))]
19497 "TARGET_USE_FANCY_MATH_387
19498 && !(reload_completed || reload_in_progress)"
19499 "#"
19500 "&& 1"
19501 [(set (match_dup 2)(match_dup 1))
19502 (set (match_dup 0)
19503 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
19504{
19505 operands[2] = gen_reg_rtx (<MODE>mode);
19506
19507 MEM_VOLATILE_P (operands[1]) = 1;
19508}
19509 [(set_attr "type" "multi")
19510 (set_attr "unit" "i387")
19511 (set_attr "mode" "<MODE>")])
19512
19513(define_expand "isinfxf2"
19514 [(use (match_operand:SI 0 "register_operand" ""))
19515 (use (match_operand:XF 1 "register_operand" ""))]
19516 "TARGET_USE_FANCY_MATH_387
19517 && TARGET_C99_FUNCTIONS"
19518{
19519 rtx mask = GEN_INT (0x45);
19520 rtx val = GEN_INT (0x05);
19521
19522 rtx cond;
19523
19524 rtx scratch = gen_reg_rtx (HImode);
19525 rtx res = gen_reg_rtx (QImode);
19526
19527 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
19528
19529 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19530 emit_insn (gen_cmpqi_ext_3 (scratch, val));
19531 cond = gen_rtx_fmt_ee (EQ, QImode,
19532 gen_rtx_REG (CCmode, FLAGS_REG),
19533 const0_rtx);
19534 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19535 emit_insn (gen_zero_extendqisi2 (operands[0], res));
19536 DONE;
19537})
19538
9ed4207f
UB
19539(define_expand "isinf<mode>2"
19540 [(use (match_operand:SI 0 "register_operand" ""))
6b67572e 19541 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
9ed4207f 19542 "TARGET_USE_FANCY_MATH_387
81e864cb 19543 && TARGET_C99_FUNCTIONS
d0c9d431 19544 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9ed4207f
UB
19545{
19546 rtx mask = GEN_INT (0x45);
19547 rtx val = GEN_INT (0x05);
19548
19549 rtx cond;
19550
19551 rtx scratch = gen_reg_rtx (HImode);
19552 rtx res = gen_reg_rtx (QImode);
19553
6b67572e
UB
19554 /* Remove excess precision by forcing value through memory. */
19555 if (memory_operand (operands[1], VOIDmode))
19556 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19557 else
19558 {
bbbbb16a
ILT
19559 enum ix86_stack_slot slot = (virtuals_instantiated
19560 ? SLOT_TEMP
19561 : SLOT_VIRTUAL);
6b67572e
UB
19562 rtx temp = assign_386_stack_local (<MODE>mode, slot);
19563
19564 emit_move_insn (temp, operands[1]);
19565 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19566 }
19567
9ed4207f
UB
19568 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19569 emit_insn (gen_cmpqi_ext_3 (scratch, val));
19570 cond = gen_rtx_fmt_ee (EQ, QImode,
19571 gen_rtx_REG (CCmode, FLAGS_REG),
19572 const0_rtx);
19573 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19574 emit_insn (gen_zero_extendqisi2 (operands[0], res));
19575 DONE;
19576})
19577
d0c9d431
UB
19578(define_expand "signbit<mode>2"
19579 [(use (match_operand:SI 0 "register_operand" ""))
19580 (use (match_operand:X87MODEF 1 "register_operand" ""))]
19581 "TARGET_USE_FANCY_MATH_387
19582 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19583{
19584 rtx mask = GEN_INT (0x0200);
19585
19586 rtx scratch = gen_reg_rtx (HImode);
19587
19588 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19589 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19590 DONE;
19591})
e075ae69
RH
19592\f
19593;; Block operation instructions
886c62d1 19594
922e3e33
UB
19595(define_insn "cld"
19596 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19597 ""
19598 "cld"
19599 [(set_attr "length" "1")
19600 (set_attr "length_immediate" "0")
19601 (set_attr "modrm" "0")])
19602
70128ad9 19603(define_expand "movmemsi"
f90800f8
JH
19604 [(use (match_operand:BLK 0 "memory_operand" ""))
19605 (use (match_operand:BLK 1 "memory_operand" ""))
79f05c19 19606 (use (match_operand:SI 2 "nonmemory_operand" ""))
079a182e
JH
19607 (use (match_operand:SI 3 "const_int_operand" ""))
19608 (use (match_operand:SI 4 "const_int_operand" ""))
19609 (use (match_operand:SI 5 "const_int_operand" ""))]
8c996513 19610 ""
886c62d1 19611{
8c996513 19612 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
079a182e 19613 operands[4], operands[5]))
0945b39d
JH
19614 DONE;
19615 else
19616 FAIL;
0f40f9f7 19617})
79f05c19 19618
70128ad9 19619(define_expand "movmemdi"
0945b39d
JH
19620 [(use (match_operand:BLK 0 "memory_operand" ""))
19621 (use (match_operand:BLK 1 "memory_operand" ""))
19622 (use (match_operand:DI 2 "nonmemory_operand" ""))
079a182e
JH
19623 (use (match_operand:DI 3 "const_int_operand" ""))
19624 (use (match_operand:SI 4 "const_int_operand" ""))
19625 (use (match_operand:SI 5 "const_int_operand" ""))]
0945b39d 19626 "TARGET_64BIT"
0945b39d 19627{
8c996513 19628 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
079a182e 19629 operands[4], operands[5]))
0945b39d
JH
19630 DONE;
19631 else
19632 FAIL;
0f40f9f7 19633})
79f05c19 19634
0945b39d
JH
19635;; Most CPUs don't like single string operations
19636;; Handle this case here to simplify previous expander.
79f05c19 19637
4e44c1ef
JJ
19638(define_expand "strmov"
19639 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19640 (set (match_operand 1 "memory_operand" "") (match_dup 4))
19641 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
8bc527af 19642 (clobber (reg:CC FLAGS_REG))])
4e44c1ef 19643 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
8bc527af 19644 (clobber (reg:CC FLAGS_REG))])]
79f05c19 19645 ""
79f05c19 19646{
4e44c1ef 19647 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
79f05c19 19648
4e44c1ef
JJ
19649 /* If .md ever supports :P for Pmode, these can be directly
19650 in the pattern above. */
19651 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19652 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
0945b39d 19653
3c285765 19654 /* Can't use this if the user has appropriated esi or edi. */
18bd082d 19655 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
ec382b8c 19656 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
886c62d1 19657 {
4e44c1ef
JJ
19658 emit_insn (gen_strmov_singleop (operands[0], operands[1],
19659 operands[2], operands[3],
19660 operands[5], operands[6]));
f90800f8
JH
19661 DONE;
19662 }
886c62d1 19663
4e44c1ef 19664 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
0f40f9f7 19665})
f90800f8 19666
4e44c1ef
JJ
19667(define_expand "strmov_singleop"
19668 [(parallel [(set (match_operand 1 "memory_operand" "")
19669 (match_operand 3 "memory_operand" ""))
19670 (set (match_operand 0 "register_operand" "")
19671 (match_operand 4 "" ""))
19672 (set (match_operand 2 "register_operand" "")
90c56b45 19673 (match_operand 5 "" ""))])]
18bd082d 19674 ""
922e3e33 19675 "ix86_current_function_needs_cld = 1;")
0945b39d 19676
4e44c1ef 19677(define_insn "*strmovdi_rex_1"
0945b39d
JH
19678 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19679 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19680 (set (match_operand:DI 0 "register_operand" "=D")
19681 (plus:DI (match_dup 2)
19682 (const_int 8)))
19683 (set (match_operand:DI 1 "register_operand" "=S")
19684 (plus:DI (match_dup 3)
90c56b45 19685 (const_int 8)))]
bdfd2026 19686 "TARGET_64BIT"
0945b39d
JH
19687 "movsq"
19688 [(set_attr "type" "str")
19689 (set_attr "mode" "DI")
19690 (set_attr "memory" "both")])
19691
4e44c1ef 19692(define_insn "*strmovsi_1"
79f05c19
JH
19693 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19694 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19695 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 19696 (plus:SI (match_dup 2)
79f05c19
JH
19697 (const_int 4)))
19698 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 19699 (plus:SI (match_dup 3)
90c56b45 19700 (const_int 4)))]
bdfd2026 19701 "!TARGET_64BIT"
62d2739a 19702 "movs{l|d}"
0945b39d
JH
19703 [(set_attr "type" "str")
19704 (set_attr "mode" "SI")
19705 (set_attr "memory" "both")])
19706
4e44c1ef 19707(define_insn "*strmovsi_rex_1"
0945b39d
JH
19708 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19709 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19710 (set (match_operand:DI 0 "register_operand" "=D")
19711 (plus:DI (match_dup 2)
19712 (const_int 4)))
19713 (set (match_operand:DI 1 "register_operand" "=S")
19714 (plus:DI (match_dup 3)
90c56b45 19715 (const_int 4)))]
bdfd2026 19716 "TARGET_64BIT"
62d2739a 19717 "movs{l|d}"
79f05c19 19718 [(set_attr "type" "str")
6ef67412 19719 (set_attr "mode" "SI")
79f05c19
JH
19720 (set_attr "memory" "both")])
19721
4e44c1ef 19722(define_insn "*strmovhi_1"
f90800f8
JH
19723 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19724 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19725 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 19726 (plus:SI (match_dup 2)
f90800f8
JH
19727 (const_int 2)))
19728 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 19729 (plus:SI (match_dup 3)
90c56b45 19730 (const_int 2)))]
bdfd2026 19731 "!TARGET_64BIT"
0945b39d
JH
19732 "movsw"
19733 [(set_attr "type" "str")
19734 (set_attr "memory" "both")
19735 (set_attr "mode" "HI")])
19736
4e44c1ef 19737(define_insn "*strmovhi_rex_1"
0945b39d
JH
19738 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19739 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19740 (set (match_operand:DI 0 "register_operand" "=D")
19741 (plus:DI (match_dup 2)
19742 (const_int 2)))
19743 (set (match_operand:DI 1 "register_operand" "=S")
19744 (plus:DI (match_dup 3)
90c56b45 19745 (const_int 2)))]
bdfd2026 19746 "TARGET_64BIT"
f90800f8
JH
19747 "movsw"
19748 [(set_attr "type" "str")
19749 (set_attr "memory" "both")
6ef67412 19750 (set_attr "mode" "HI")])
f90800f8 19751
4e44c1ef 19752(define_insn "*strmovqi_1"
f90800f8
JH
19753 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19754 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19755 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 19756 (plus:SI (match_dup 2)
f90800f8
JH
19757 (const_int 1)))
19758 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 19759 (plus:SI (match_dup 3)
90c56b45 19760 (const_int 1)))]
bdfd2026 19761 "!TARGET_64BIT"
f90800f8
JH
19762 "movsb"
19763 [(set_attr "type" "str")
6ef67412
JH
19764 (set_attr "memory" "both")
19765 (set_attr "mode" "QI")])
f90800f8 19766
4e44c1ef 19767(define_insn "*strmovqi_rex_1"
0945b39d
JH
19768 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19769 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19770 (set (match_operand:DI 0 "register_operand" "=D")
19771 (plus:DI (match_dup 2)
19772 (const_int 1)))
19773 (set (match_operand:DI 1 "register_operand" "=S")
19774 (plus:DI (match_dup 3)
90c56b45 19775 (const_int 1)))]
bdfd2026 19776 "TARGET_64BIT"
0945b39d
JH
19777 "movsb"
19778 [(set_attr "type" "str")
19779 (set_attr "memory" "both")
a952487c 19780 (set_attr "prefix_rex" "0")
0945b39d
JH
19781 (set_attr "mode" "QI")])
19782
4e44c1ef
JJ
19783(define_expand "rep_mov"
19784 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19785 (set (match_operand 0 "register_operand" "")
19786 (match_operand 5 "" ""))
19787 (set (match_operand 2 "register_operand" "")
19788 (match_operand 6 "" ""))
19789 (set (match_operand 1 "memory_operand" "")
19790 (match_operand 3 "memory_operand" ""))
90c56b45 19791 (use (match_dup 4))])]
4e44c1ef 19792 ""
922e3e33 19793 "ix86_current_function_needs_cld = 1;")
4e44c1ef
JJ
19794
19795(define_insn "*rep_movdi_rex64"
0945b39d 19796 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
6300f037 19797 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
19798 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19799 (const_int 3))
19800 (match_operand:DI 3 "register_operand" "0")))
6300f037 19801 (set (match_operand:DI 1 "register_operand" "=S")
0945b39d
JH
19802 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19803 (match_operand:DI 4 "register_operand" "1")))
19804 (set (mem:BLK (match_dup 3))
19805 (mem:BLK (match_dup 4)))
90c56b45 19806 (use (match_dup 5))]
0945b39d 19807 "TARGET_64BIT"
57c2d13f 19808 "rep movsq"
0945b39d
JH
19809 [(set_attr "type" "str")
19810 (set_attr "prefix_rep" "1")
19811 (set_attr "memory" "both")
19812 (set_attr "mode" "DI")])
19813
4e44c1ef 19814(define_insn "*rep_movsi"
f90800f8 19815 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
6300f037 19816 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
19817 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19818 (const_int 2))
19819 (match_operand:SI 3 "register_operand" "0")))
6300f037 19820 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb
JH
19821 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19822 (match_operand:SI 4 "register_operand" "1")))
f90800f8
JH
19823 (set (mem:BLK (match_dup 3))
19824 (mem:BLK (match_dup 4)))
90c56b45 19825 (use (match_dup 5))]
0945b39d 19826 "!TARGET_64BIT"
57c2d13f 19827 "rep movs{l|d}"
0945b39d
JH
19828 [(set_attr "type" "str")
19829 (set_attr "prefix_rep" "1")
19830 (set_attr "memory" "both")
19831 (set_attr "mode" "SI")])
19832
4e44c1ef 19833(define_insn "*rep_movsi_rex64"
0945b39d 19834 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
6300f037 19835 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
19836 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19837 (const_int 2))
19838 (match_operand:DI 3 "register_operand" "0")))
6300f037 19839 (set (match_operand:DI 1 "register_operand" "=S")
0945b39d
JH
19840 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19841 (match_operand:DI 4 "register_operand" "1")))
19842 (set (mem:BLK (match_dup 3))
19843 (mem:BLK (match_dup 4)))
90c56b45 19844 (use (match_dup 5))]
0945b39d 19845 "TARGET_64BIT"
57c2d13f 19846 "rep movs{l|d}"
f90800f8 19847 [(set_attr "type" "str")
6ef67412
JH
19848 (set_attr "prefix_rep" "1")
19849 (set_attr "memory" "both")
19850 (set_attr "mode" "SI")])
f90800f8 19851
4e44c1ef 19852(define_insn "*rep_movqi"
f90800f8 19853 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
6300f037 19854 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
19855 (plus:SI (match_operand:SI 3 "register_operand" "0")
19856 (match_operand:SI 5 "register_operand" "2")))
6300f037 19857 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 19858 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
f90800f8
JH
19859 (set (mem:BLK (match_dup 3))
19860 (mem:BLK (match_dup 4)))
90c56b45 19861 (use (match_dup 5))]
0945b39d 19862 "!TARGET_64BIT"
57c2d13f 19863 "rep movsb"
0945b39d
JH
19864 [(set_attr "type" "str")
19865 (set_attr "prefix_rep" "1")
19866 (set_attr "memory" "both")
19867 (set_attr "mode" "SI")])
19868
4e44c1ef 19869(define_insn "*rep_movqi_rex64"
0945b39d 19870 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
6300f037 19871 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
19872 (plus:DI (match_operand:DI 3 "register_operand" "0")
19873 (match_operand:DI 5 "register_operand" "2")))
6300f037 19874 (set (match_operand:DI 1 "register_operand" "=S")
0945b39d
JH
19875 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19876 (set (mem:BLK (match_dup 3))
19877 (mem:BLK (match_dup 4)))
90c56b45 19878 (use (match_dup 5))]
0945b39d 19879 "TARGET_64BIT"
57c2d13f 19880 "rep movsb"
f90800f8 19881 [(set_attr "type" "str")
6ef67412
JH
19882 (set_attr "prefix_rep" "1")
19883 (set_attr "memory" "both")
19884 (set_attr "mode" "SI")])
886c62d1 19885
57e84f18 19886(define_expand "setmemsi"
e2e52e1b 19887 [(use (match_operand:BLK 0 "memory_operand" ""))
79f05c19 19888 (use (match_operand:SI 1 "nonmemory_operand" ""))
57e84f18 19889 (use (match_operand 2 "const_int_operand" ""))
079a182e
JH
19890 (use (match_operand 3 "const_int_operand" ""))
19891 (use (match_operand:SI 4 "const_int_operand" ""))
19892 (use (match_operand:SI 5 "const_int_operand" ""))]
0ae40045 19893 ""
0ae40045 19894{
8c996513
JH
19895 if (ix86_expand_setmem (operands[0], operands[1],
19896 operands[2], operands[3],
079a182e 19897 operands[4], operands[5]))
0945b39d
JH
19898 DONE;
19899 else
19900 FAIL;
0f40f9f7 19901})
e2e52e1b 19902
57e84f18 19903(define_expand "setmemdi"
0945b39d
JH
19904 [(use (match_operand:BLK 0 "memory_operand" ""))
19905 (use (match_operand:DI 1 "nonmemory_operand" ""))
57e84f18 19906 (use (match_operand 2 "const_int_operand" ""))
8c996513
JH
19907 (use (match_operand 3 "const_int_operand" ""))
19908 (use (match_operand 4 "const_int_operand" ""))
19909 (use (match_operand 5 "const_int_operand" ""))]
0945b39d 19910 "TARGET_64BIT"
0945b39d 19911{
8c996513
JH
19912 if (ix86_expand_setmem (operands[0], operands[1],
19913 operands[2], operands[3],
079a182e 19914 operands[4], operands[5]))
0945b39d
JH
19915 DONE;
19916 else
19917 FAIL;
0f40f9f7 19918})
e2e52e1b 19919
0945b39d
JH
19920;; Most CPUs don't like single string operations
19921;; Handle this case here to simplify previous expander.
79f05c19 19922
4e44c1ef
JJ
19923(define_expand "strset"
19924 [(set (match_operand 1 "memory_operand" "")
19925 (match_operand 2 "register_operand" ""))
19926 (parallel [(set (match_operand 0 "register_operand" "")
19927 (match_dup 3))
8bc527af 19928 (clobber (reg:CC FLAGS_REG))])]
79f05c19 19929 ""
79f05c19 19930{
4e44c1ef
JJ
19931 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19932 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
79f05c19 19933
4e44c1ef
JJ
19934 /* If .md ever supports :P for Pmode, this can be directly
19935 in the pattern above. */
19936 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19937 GEN_INT (GET_MODE_SIZE (GET_MODE
19938 (operands[2]))));
18bd082d 19939 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
0945b39d 19940 {
4e44c1ef
JJ
19941 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19942 operands[3]));
0945b39d
JH
19943 DONE;
19944 }
0f40f9f7 19945})
0945b39d 19946
4e44c1ef
JJ
19947(define_expand "strset_singleop"
19948 [(parallel [(set (match_operand 1 "memory_operand" "")
19949 (match_operand 2 "register_operand" ""))
19950 (set (match_operand 0 "register_operand" "")
90c56b45 19951 (match_operand 3 "" ""))])]
bdfd2026 19952 ""
922e3e33 19953 "ix86_current_function_needs_cld = 1;")
0945b39d 19954
4e44c1ef 19955(define_insn "*strsetdi_rex_1"
22116d84
L
19956 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19957 (match_operand:DI 2 "register_operand" "a"))
0945b39d
JH
19958 (set (match_operand:DI 0 "register_operand" "=D")
19959 (plus:DI (match_dup 1)
90c56b45 19960 (const_int 8)))]
bdfd2026 19961 "TARGET_64BIT"
0945b39d
JH
19962 "stosq"
19963 [(set_attr "type" "str")
19964 (set_attr "memory" "store")
19965 (set_attr "mode" "DI")])
19966
4e44c1ef 19967(define_insn "*strsetsi_1"
79f05c19
JH
19968 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19969 (match_operand:SI 2 "register_operand" "a"))
19970 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 19971 (plus:SI (match_dup 1)
90c56b45 19972 (const_int 4)))]
bdfd2026 19973 "!TARGET_64BIT"
62d2739a 19974 "stos{l|d}"
0945b39d
JH
19975 [(set_attr "type" "str")
19976 (set_attr "memory" "store")
19977 (set_attr "mode" "SI")])
19978
4e44c1ef 19979(define_insn "*strsetsi_rex_1"
0945b39d
JH
19980 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19981 (match_operand:SI 2 "register_operand" "a"))
19982 (set (match_operand:DI 0 "register_operand" "=D")
19983 (plus:DI (match_dup 1)
90c56b45 19984 (const_int 4)))]
bdfd2026 19985 "TARGET_64BIT"
62d2739a 19986 "stos{l|d}"
79f05c19 19987 [(set_attr "type" "str")
6ef67412
JH
19988 (set_attr "memory" "store")
19989 (set_attr "mode" "SI")])
79f05c19 19990
4e44c1ef 19991(define_insn "*strsethi_1"
e2e52e1b
JH
19992 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19993 (match_operand:HI 2 "register_operand" "a"))
19994 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 19995 (plus:SI (match_dup 1)
90c56b45 19996 (const_int 2)))]
bdfd2026 19997 "!TARGET_64BIT"
0945b39d
JH
19998 "stosw"
19999 [(set_attr "type" "str")
20000 (set_attr "memory" "store")
20001 (set_attr "mode" "HI")])
20002
4e44c1ef 20003(define_insn "*strsethi_rex_1"
0945b39d
JH
20004 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
20005 (match_operand:HI 2 "register_operand" "a"))
20006 (set (match_operand:DI 0 "register_operand" "=D")
20007 (plus:DI (match_dup 1)
90c56b45 20008 (const_int 2)))]
bdfd2026 20009 "TARGET_64BIT"
e2e52e1b
JH
20010 "stosw"
20011 [(set_attr "type" "str")
20012 (set_attr "memory" "store")
6ef67412 20013 (set_attr "mode" "HI")])
e2e52e1b 20014
4e44c1ef 20015(define_insn "*strsetqi_1"
e2e52e1b
JH
20016 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
20017 (match_operand:QI 2 "register_operand" "a"))
20018 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 20019 (plus:SI (match_dup 1)
90c56b45 20020 (const_int 1)))]
bdfd2026 20021 "!TARGET_64BIT"
0945b39d
JH
20022 "stosb"
20023 [(set_attr "type" "str")
20024 (set_attr "memory" "store")
20025 (set_attr "mode" "QI")])
20026
4e44c1ef 20027(define_insn "*strsetqi_rex_1"
0945b39d
JH
20028 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
20029 (match_operand:QI 2 "register_operand" "a"))
20030 (set (match_operand:DI 0 "register_operand" "=D")
20031 (plus:DI (match_dup 1)
90c56b45 20032 (const_int 1)))]
bdfd2026 20033 "TARGET_64BIT"
e2e52e1b
JH
20034 "stosb"
20035 [(set_attr "type" "str")
6ef67412 20036 (set_attr "memory" "store")
a952487c 20037 (set_attr "prefix_rex" "0")
6ef67412 20038 (set_attr "mode" "QI")])
e2e52e1b 20039
4e44c1ef
JJ
20040(define_expand "rep_stos"
20041 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
20042 (set (match_operand 0 "register_operand" "")
20043 (match_operand 4 "" ""))
20044 (set (match_operand 2 "memory_operand" "") (const_int 0))
20045 (use (match_operand 3 "register_operand" ""))
90c56b45 20046 (use (match_dup 1))])]
4e44c1ef 20047 ""
922e3e33 20048 "ix86_current_function_needs_cld = 1;")
4e44c1ef
JJ
20049
20050(define_insn "*rep_stosdi_rex64"
0945b39d 20051 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
6300f037 20052 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
20053 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20054 (const_int 3))
20055 (match_operand:DI 3 "register_operand" "0")))
20056 (set (mem:BLK (match_dup 3))
20057 (const_int 0))
20058 (use (match_operand:DI 2 "register_operand" "a"))
90c56b45 20059 (use (match_dup 4))]
0945b39d 20060 "TARGET_64BIT"
57c2d13f 20061 "rep stosq"
0945b39d
JH
20062 [(set_attr "type" "str")
20063 (set_attr "prefix_rep" "1")
20064 (set_attr "memory" "store")
20065 (set_attr "mode" "DI")])
20066
4e44c1ef 20067(define_insn "*rep_stossi"
e2e52e1b 20068 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
6300f037 20069 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
20070 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
20071 (const_int 2))
20072 (match_operand:SI 3 "register_operand" "0")))
e2e52e1b 20073 (set (mem:BLK (match_dup 3))
0ae40045 20074 (const_int 0))
b1cdafbb 20075 (use (match_operand:SI 2 "register_operand" "a"))
90c56b45 20076 (use (match_dup 4))]
0945b39d 20077 "!TARGET_64BIT"
57c2d13f 20078 "rep stos{l|d}"
0945b39d
JH
20079 [(set_attr "type" "str")
20080 (set_attr "prefix_rep" "1")
20081 (set_attr "memory" "store")
20082 (set_attr "mode" "SI")])
20083
4e44c1ef 20084(define_insn "*rep_stossi_rex64"
0945b39d 20085 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
6300f037 20086 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
20087 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20088 (const_int 2))
20089 (match_operand:DI 3 "register_operand" "0")))
20090 (set (mem:BLK (match_dup 3))
20091 (const_int 0))
20092 (use (match_operand:SI 2 "register_operand" "a"))
90c56b45 20093 (use (match_dup 4))]
0945b39d 20094 "TARGET_64BIT"
57c2d13f 20095 "rep stos{l|d}"
e2e52e1b 20096 [(set_attr "type" "str")
6ef67412
JH
20097 (set_attr "prefix_rep" "1")
20098 (set_attr "memory" "store")
20099 (set_attr "mode" "SI")])
0ae40045 20100
4e44c1ef 20101(define_insn "*rep_stosqi"
e2e52e1b 20102 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
6300f037 20103 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
20104 (plus:SI (match_operand:SI 3 "register_operand" "0")
20105 (match_operand:SI 4 "register_operand" "1")))
e2e52e1b
JH
20106 (set (mem:BLK (match_dup 3))
20107 (const_int 0))
b1cdafbb 20108 (use (match_operand:QI 2 "register_operand" "a"))
90c56b45 20109 (use (match_dup 4))]
0945b39d 20110 "!TARGET_64BIT"
57c2d13f 20111 "rep stosb"
0945b39d
JH
20112 [(set_attr "type" "str")
20113 (set_attr "prefix_rep" "1")
20114 (set_attr "memory" "store")
20115 (set_attr "mode" "QI")])
20116
4e44c1ef 20117(define_insn "*rep_stosqi_rex64"
0945b39d 20118 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
6300f037 20119 (set (match_operand:DI 0 "register_operand" "=D")
0945b39d
JH
20120 (plus:DI (match_operand:DI 3 "register_operand" "0")
20121 (match_operand:DI 4 "register_operand" "1")))
20122 (set (mem:BLK (match_dup 3))
20123 (const_int 0))
20124 (use (match_operand:QI 2 "register_operand" "a"))
90c56b45 20125 (use (match_dup 4))]
0945b39d 20126 "TARGET_64BIT"
57c2d13f 20127 "rep stosb"
e2e52e1b 20128 [(set_attr "type" "str")
6ef67412
JH
20129 (set_attr "prefix_rep" "1")
20130 (set_attr "memory" "store")
a952487c 20131 (set_attr "prefix_rex" "0")
6ef67412 20132 (set_attr "mode" "QI")])
0ae40045 20133
40c1d5f8 20134(define_expand "cmpstrnsi"
e075ae69
RH
20135 [(set (match_operand:SI 0 "register_operand" "")
20136 (compare:SI (match_operand:BLK 1 "general_operand" "")
20137 (match_operand:BLK 2 "general_operand" "")))
0945b39d
JH
20138 (use (match_operand 3 "general_operand" ""))
20139 (use (match_operand 4 "immediate_operand" ""))]
18bd082d 20140 ""
886c62d1 20141{
e075ae69
RH
20142 rtx addr1, addr2, out, outlow, count, countreg, align;
20143
18bd082d
JH
20144 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
20145 FAIL;
20146
d0a5295a 20147 /* Can't use this if the user has appropriated esi or edi. */
ec382b8c 20148 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
d0a5295a
RH
20149 FAIL;
20150
e075ae69 20151 out = operands[0];
7656aee4 20152 if (!REG_P (out))
e075ae69 20153 out = gen_reg_rtx (SImode);
783cdf65
JVA
20154
20155 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
20156 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
4e44c1ef
JJ
20157 if (addr1 != XEXP (operands[1], 0))
20158 operands[1] = replace_equiv_address_nv (operands[1], addr1);
20159 if (addr2 != XEXP (operands[2], 0))
20160 operands[2] = replace_equiv_address_nv (operands[2], addr2);
20161
e075ae69 20162 count = operands[3];
d24b3457 20163 countreg = ix86_zero_extend_to_Pmode (count);
e075ae69
RH
20164
20165 /* %%% Iff we are testing strict equality, we can use known alignment
20166 to good advantage. This may be possible with combine, particularly
20167 once cc0 is dead. */
20168 align = operands[4];
783cdf65 20169
7656aee4 20170 if (CONST_INT_P (count))
e075ae69
RH
20171 {
20172 if (INTVAL (count) == 0)
20173 {
20174 emit_move_insn (operands[0], const0_rtx);
20175 DONE;
20176 }
40c1d5f8
AS
20177 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
20178 operands[1], operands[2]));
e075ae69
RH
20179 }
20180 else
e2e52e1b 20181 {
0945b39d 20182 if (TARGET_64BIT)
4e44c1ef 20183 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
0945b39d 20184 else
4e44c1ef 20185 emit_insn (gen_cmpsi_1 (countreg, countreg));
40c1d5f8
AS
20186 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
20187 operands[1], operands[2]));
e2e52e1b 20188 }
e075ae69
RH
20189
20190 outlow = gen_lowpart (QImode, out);
20191 emit_insn (gen_cmpintqi (outlow));
20192 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
783cdf65 20193
e075ae69
RH
20194 if (operands[0] != out)
20195 emit_move_insn (operands[0], out);
783cdf65 20196
e075ae69 20197 DONE;
0f40f9f7 20198})
886c62d1 20199
e075ae69
RH
20200;; Produce a tri-state integer (-1, 0, 1) from condition codes.
20201
20202(define_expand "cmpintqi"
20203 [(set (match_dup 1)
8bc527af 20204 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
e075ae69 20205 (set (match_dup 2)
8bc527af 20206 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
e075ae69
RH
20207 (parallel [(set (match_operand:QI 0 "register_operand" "")
20208 (minus:QI (match_dup 1)
20209 (match_dup 2)))
8bc527af 20210 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
20211 ""
20212 "operands[1] = gen_reg_rtx (QImode);
20213 operands[2] = gen_reg_rtx (QImode);")
20214
f76e3b05
JVA
20215;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
20216;; zero. Emit extra code to make sure that a zero-length compare is EQ.
56c0e8fa 20217
40c1d5f8 20218(define_expand "cmpstrnqi_nz_1"
8bc527af 20219 [(parallel [(set (reg:CC FLAGS_REG)
4e44c1ef
JJ
20220 (compare:CC (match_operand 4 "memory_operand" "")
20221 (match_operand 5 "memory_operand" "")))
20222 (use (match_operand 2 "register_operand" ""))
20223 (use (match_operand:SI 3 "immediate_operand" ""))
4e44c1ef
JJ
20224 (clobber (match_operand 0 "register_operand" ""))
20225 (clobber (match_operand 1 "register_operand" ""))
20226 (clobber (match_dup 2))])]
20227 ""
922e3e33 20228 "ix86_current_function_needs_cld = 1;")
4e44c1ef 20229
40c1d5f8 20230(define_insn "*cmpstrnqi_nz_1"
8bc527af 20231 [(set (reg:CC FLAGS_REG)
b1cdafbb
JH
20232 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20233 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
20234 (use (match_operand:SI 6 "register_operand" "2"))
886c62d1 20235 (use (match_operand:SI 3 "immediate_operand" "i"))
b1cdafbb
JH
20236 (clobber (match_operand:SI 0 "register_operand" "=S"))
20237 (clobber (match_operand:SI 1 "register_operand" "=D"))
20238 (clobber (match_operand:SI 2 "register_operand" "=c"))]
0945b39d 20239 "!TARGET_64BIT"
57c2d13f 20240 "repz cmpsb"
0945b39d
JH
20241 [(set_attr "type" "str")
20242 (set_attr "mode" "QI")
20243 (set_attr "prefix_rep" "1")])
20244
40c1d5f8 20245(define_insn "*cmpstrnqi_nz_rex_1"
8bc527af 20246 [(set (reg:CC FLAGS_REG)
0945b39d
JH
20247 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20248 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
20249 (use (match_operand:DI 6 "register_operand" "2"))
20250 (use (match_operand:SI 3 "immediate_operand" "i"))
0945b39d
JH
20251 (clobber (match_operand:DI 0 "register_operand" "=S"))
20252 (clobber (match_operand:DI 1 "register_operand" "=D"))
20253 (clobber (match_operand:DI 2 "register_operand" "=c"))]
20254 "TARGET_64BIT"
57c2d13f 20255 "repz cmpsb"
e2e52e1b 20256 [(set_attr "type" "str")
6ef67412 20257 (set_attr "mode" "QI")
a952487c 20258 (set_attr "prefix_rex" "0")
6ef67412 20259 (set_attr "prefix_rep" "1")])
886c62d1 20260
e075ae69 20261;; The same, but the count is not known to not be zero.
886c62d1 20262
40c1d5f8 20263(define_expand "cmpstrnqi_1"
8bc527af 20264 [(parallel [(set (reg:CC FLAGS_REG)
4e44c1ef
JJ
20265 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
20266 (const_int 0))
20267 (compare:CC (match_operand 4 "memory_operand" "")
20268 (match_operand 5 "memory_operand" ""))
20269 (const_int 0)))
20270 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af 20271 (use (reg:CC FLAGS_REG))
4e44c1ef
JJ
20272 (clobber (match_operand 0 "register_operand" ""))
20273 (clobber (match_operand 1 "register_operand" ""))
20274 (clobber (match_dup 2))])]
20275 ""
922e3e33 20276 "ix86_current_function_needs_cld = 1;")
4e44c1ef 20277
40c1d5f8 20278(define_insn "*cmpstrnqi_1"
8bc527af 20279 [(set (reg:CC FLAGS_REG)
b1cdafbb 20280 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
e075ae69 20281 (const_int 0))
2bed3391 20282 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
b1cdafbb 20283 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
e075ae69
RH
20284 (const_int 0)))
20285 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af 20286 (use (reg:CC FLAGS_REG))
b1cdafbb
JH
20287 (clobber (match_operand:SI 0 "register_operand" "=S"))
20288 (clobber (match_operand:SI 1 "register_operand" "=D"))
20289 (clobber (match_operand:SI 2 "register_operand" "=c"))]
0945b39d 20290 "!TARGET_64BIT"
57c2d13f 20291 "repz cmpsb"
0945b39d
JH
20292 [(set_attr "type" "str")
20293 (set_attr "mode" "QI")
20294 (set_attr "prefix_rep" "1")])
20295
40c1d5f8 20296(define_insn "*cmpstrnqi_rex_1"
8bc527af 20297 [(set (reg:CC FLAGS_REG)
0945b39d
JH
20298 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
20299 (const_int 0))
20300 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20301 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
20302 (const_int 0)))
20303 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af 20304 (use (reg:CC FLAGS_REG))
0945b39d
JH
20305 (clobber (match_operand:DI 0 "register_operand" "=S"))
20306 (clobber (match_operand:DI 1 "register_operand" "=D"))
20307 (clobber (match_operand:DI 2 "register_operand" "=c"))]
20308 "TARGET_64BIT"
57c2d13f 20309 "repz cmpsb"
e2e52e1b 20310 [(set_attr "type" "str")
6ef67412 20311 (set_attr "mode" "QI")
a952487c 20312 (set_attr "prefix_rex" "0")
6ef67412 20313 (set_attr "prefix_rep" "1")])
886c62d1 20314
e075ae69
RH
20315(define_expand "strlensi"
20316 [(set (match_operand:SI 0 "register_operand" "")
20317 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
20318 (match_operand:QI 2 "immediate_operand" "")
8ee41eaf 20319 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
886c62d1 20320 ""
886c62d1 20321{
0945b39d
JH
20322 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20323 DONE;
20324 else
20325 FAIL;
0f40f9f7 20326})
e075ae69 20327
0945b39d
JH
20328(define_expand "strlendi"
20329 [(set (match_operand:DI 0 "register_operand" "")
20330 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
20331 (match_operand:QI 2 "immediate_operand" "")
8ee41eaf 20332 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
0945b39d 20333 ""
0945b39d
JH
20334{
20335 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20336 DONE;
20337 else
20338 FAIL;
0f40f9f7 20339})
19c3fc24 20340
4e44c1ef
JJ
20341(define_expand "strlenqi_1"
20342 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
4e44c1ef 20343 (clobber (match_operand 1 "register_operand" ""))
8bc527af 20344 (clobber (reg:CC FLAGS_REG))])]
4e44c1ef 20345 ""
922e3e33 20346 "ix86_current_function_needs_cld = 1;")
4e44c1ef
JJ
20347
20348(define_insn "*strlenqi_1"
e075ae69 20349 [(set (match_operand:SI 0 "register_operand" "=&c")
b1cdafbb 20350 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
0945b39d 20351 (match_operand:QI 2 "register_operand" "a")
e075ae69 20352 (match_operand:SI 3 "immediate_operand" "i")
8ee41eaf 20353 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
b1cdafbb 20354 (clobber (match_operand:SI 1 "register_operand" "=D"))
8bc527af 20355 (clobber (reg:CC FLAGS_REG))]
0945b39d 20356 "!TARGET_64BIT"
57c2d13f 20357 "repnz scasb"
0945b39d
JH
20358 [(set_attr "type" "str")
20359 (set_attr "mode" "QI")
20360 (set_attr "prefix_rep" "1")])
20361
4e44c1ef 20362(define_insn "*strlenqi_rex_1"
0945b39d
JH
20363 [(set (match_operand:DI 0 "register_operand" "=&c")
20364 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
20365 (match_operand:QI 2 "register_operand" "a")
20366 (match_operand:DI 3 "immediate_operand" "i")
8ee41eaf 20367 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
0945b39d 20368 (clobber (match_operand:DI 1 "register_operand" "=D"))
8bc527af 20369 (clobber (reg:CC FLAGS_REG))]
0945b39d 20370 "TARGET_64BIT"
57c2d13f 20371 "repnz scasb"
e2e52e1b 20372 [(set_attr "type" "str")
6ef67412 20373 (set_attr "mode" "QI")
a952487c 20374 (set_attr "prefix_rex" "0")
6ef67412 20375 (set_attr "prefix_rep" "1")])
a3e991f2 20376
40c1d5f8 20377;; Peephole optimizations to clean up after cmpstrn*. This should be
a3e991f2 20378;; handled in combine, but it is not currently up to the task.
40c1d5f8 20379;; When used for their truth value, the cmpstrn* expanders generate
a3e991f2
ZW
20380;; code like this:
20381;;
20382;; repz cmpsb
20383;; seta %al
20384;; setb %dl
20385;; cmpb %al, %dl
20386;; jcc label
20387;;
20388;; The intermediate three instructions are unnecessary.
20389
40c1d5f8 20390;; This one handles cmpstrn*_nz_1...
a3e991f2
ZW
20391(define_peephole2
20392 [(parallel[
8bc527af 20393 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
20394 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20395 (mem:BLK (match_operand 5 "register_operand" ""))))
20396 (use (match_operand 6 "register_operand" ""))
20397 (use (match_operand:SI 3 "immediate_operand" ""))
a3e991f2
ZW
20398 (clobber (match_operand 0 "register_operand" ""))
20399 (clobber (match_operand 1 "register_operand" ""))
20400 (clobber (match_operand 2 "register_operand" ""))])
20401 (set (match_operand:QI 7 "register_operand" "")
8bc527af 20402 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
a3e991f2 20403 (set (match_operand:QI 8 "register_operand" "")
8bc527af 20404 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
42fabf21 20405 (set (reg FLAGS_REG)
a3e991f2
ZW
20406 (compare (match_dup 7) (match_dup 8)))
20407 ]
244ec848 20408 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
a3e991f2 20409 [(parallel[
8bc527af 20410 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
20411 (compare:CC (mem:BLK (match_dup 4))
20412 (mem:BLK (match_dup 5))))
20413 (use (match_dup 6))
20414 (use (match_dup 3))
a3e991f2
ZW
20415 (clobber (match_dup 0))
20416 (clobber (match_dup 1))
244ec848 20417 (clobber (match_dup 2))])]
a3e991f2
ZW
20418 "")
20419
40c1d5f8 20420;; ...and this one handles cmpstrn*_1.
a3e991f2
ZW
20421(define_peephole2
20422 [(parallel[
8bc527af 20423 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
20424 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
20425 (const_int 0))
20426 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20427 (mem:BLK (match_operand 5 "register_operand" "")))
20428 (const_int 0)))
20429 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af 20430 (use (reg:CC FLAGS_REG))
a3e991f2
ZW
20431 (clobber (match_operand 0 "register_operand" ""))
20432 (clobber (match_operand 1 "register_operand" ""))
20433 (clobber (match_operand 2 "register_operand" ""))])
20434 (set (match_operand:QI 7 "register_operand" "")
8bc527af 20435 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
a3e991f2 20436 (set (match_operand:QI 8 "register_operand" "")
8bc527af 20437 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
42fabf21 20438 (set (reg FLAGS_REG)
a3e991f2
ZW
20439 (compare (match_dup 7) (match_dup 8)))
20440 ]
244ec848 20441 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
a3e991f2 20442 [(parallel[
8bc527af 20443 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
20444 (if_then_else:CC (ne (match_dup 6)
20445 (const_int 0))
20446 (compare:CC (mem:BLK (match_dup 4))
20447 (mem:BLK (match_dup 5)))
20448 (const_int 0)))
20449 (use (match_dup 3))
8bc527af 20450 (use (reg:CC FLAGS_REG))
a3e991f2
ZW
20451 (clobber (match_dup 0))
20452 (clobber (match_dup 1))
244ec848 20453 (clobber (match_dup 2))])]
a3e991f2
ZW
20454 "")
20455
20456
e075ae69
RH
20457\f
20458;; Conditional move instructions.
726e2d54 20459
44cf5b6a 20460(define_expand "movdicc"
885a70fd
JH
20461 [(set (match_operand:DI 0 "register_operand" "")
20462 (if_then_else:DI (match_operand 1 "comparison_operator" "")
44cf5b6a
JH
20463 (match_operand:DI 2 "general_operand" "")
20464 (match_operand:DI 3 "general_operand" "")))]
885a70fd 20465 "TARGET_64BIT"
85845bb9 20466 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
885a70fd 20467
e74061a9 20468(define_insn "x86_movdicc_0_m1_rex64"
885a70fd 20469 [(set (match_operand:DI 0 "register_operand" "=r")
e6e81735 20470 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
885a70fd
JH
20471 (const_int -1)
20472 (const_int 0)))
8bc527af 20473 (clobber (reg:CC FLAGS_REG))]
885a70fd 20474 "TARGET_64BIT"
0f40f9f7 20475 "sbb{q}\t%0, %0"
885a70fd
JH
20476 ; Since we don't have the proper number of operands for an alu insn,
20477 ; fill in all the blanks.
20478 [(set_attr "type" "alu")
b6837b94 20479 (set_attr "use_carry" "1")
890d52e8 20480 (set_attr "pent_pair" "pu")
885a70fd
JH
20481 (set_attr "memory" "none")
20482 (set_attr "imm_disp" "false")
20483 (set_attr "mode" "DI")
20484 (set_attr "length_immediate" "0")])
20485
0e93e1b4
UB
20486(define_insn "*x86_movdicc_0_m1_se"
20487 [(set (match_operand:DI 0 "register_operand" "=r")
20488 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
20489 (const_int 1)
20490 (const_int 0)))
20491 (clobber (reg:CC FLAGS_REG))]
20492 ""
20493 "sbb{q}\t%0, %0"
20494 [(set_attr "type" "alu")
b6837b94 20495 (set_attr "use_carry" "1")
0e93e1b4
UB
20496 (set_attr "pent_pair" "pu")
20497 (set_attr "memory" "none")
20498 (set_attr "imm_disp" "false")
20499 (set_attr "mode" "DI")
20500 (set_attr "length_immediate" "0")])
20501
eaa49b49 20502(define_insn "*movdicc_c_rex64"
885a70fd 20503 [(set (match_operand:DI 0 "register_operand" "=r,r")
6300f037 20504 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
42fabf21 20505 [(reg FLAGS_REG) (const_int 0)])
885a70fd
JH
20506 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
20507 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
20508 "TARGET_64BIT && TARGET_CMOVE
7656aee4 20509 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
885a70fd 20510 "@
048b1c95
JJ
20511 cmov%O2%C1\t{%2, %0|%0, %2}
20512 cmov%O2%c1\t{%3, %0|%0, %3}"
885a70fd
JH
20513 [(set_attr "type" "icmov")
20514 (set_attr "mode" "DI")])
20515
e075ae69 20516(define_expand "movsicc"
6a4a5d95 20517 [(set (match_operand:SI 0 "register_operand" "")
e075ae69
RH
20518 (if_then_else:SI (match_operand 1 "comparison_operator" "")
20519 (match_operand:SI 2 "general_operand" "")
20520 (match_operand:SI 3 "general_operand" "")))]
20521 ""
85845bb9 20522 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
726e2d54 20523
e075ae69
RH
20524;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
20525;; the register first winds up with `sbbl $0,reg', which is also weird.
20526;; So just document what we're doing explicitly.
20527
20528(define_insn "x86_movsicc_0_m1"
20529 [(set (match_operand:SI 0 "register_operand" "=r")
e6e81735 20530 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
e075ae69
RH
20531 (const_int -1)
20532 (const_int 0)))
8bc527af 20533 (clobber (reg:CC FLAGS_REG))]
e075ae69 20534 ""
0f40f9f7 20535 "sbb{l}\t%0, %0"
e075ae69
RH
20536 ; Since we don't have the proper number of operands for an alu insn,
20537 ; fill in all the blanks.
20538 [(set_attr "type" "alu")
b6837b94 20539 (set_attr "use_carry" "1")
890d52e8 20540 (set_attr "pent_pair" "pu")
e075ae69
RH
20541 (set_attr "memory" "none")
20542 (set_attr "imm_disp" "false")
6ef67412
JH
20543 (set_attr "mode" "SI")
20544 (set_attr "length_immediate" "0")])
e075ae69 20545
0e93e1b4
UB
20546(define_insn "*x86_movsicc_0_m1_se"
20547 [(set (match_operand:SI 0 "register_operand" "=r")
20548 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
20549 (const_int 1)
20550 (const_int 0)))
20551 (clobber (reg:CC FLAGS_REG))]
20552 ""
20553 "sbb{l}\t%0, %0"
20554 [(set_attr "type" "alu")
b6837b94 20555 (set_attr "use_carry" "1")
0e93e1b4
UB
20556 (set_attr "pent_pair" "pu")
20557 (set_attr "memory" "none")
20558 (set_attr "imm_disp" "false")
20559 (set_attr "mode" "SI")
20560 (set_attr "length_immediate" "0")])
20561
6343a50e 20562(define_insn "*movsicc_noc"
e075ae69 20563 [(set (match_operand:SI 0 "register_operand" "=r,r")
6300f037 20564 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
42fabf21 20565 [(reg FLAGS_REG) (const_int 0)])
e075ae69
RH
20566 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20567 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
d525dfdf 20568 "TARGET_CMOVE
7656aee4 20569 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
e075ae69 20570 "@
048b1c95
JJ
20571 cmov%O2%C1\t{%2, %0|%0, %2}
20572 cmov%O2%c1\t{%3, %0|%0, %3}"
6ef67412
JH
20573 [(set_attr "type" "icmov")
20574 (set_attr "mode" "SI")])
726e2d54 20575
726e2d54
JW
20576(define_expand "movhicc"
20577 [(set (match_operand:HI 0 "register_operand" "")
20578 (if_then_else:HI (match_operand 1 "comparison_operator" "")
4977bab6
ZW
20579 (match_operand:HI 2 "general_operand" "")
20580 (match_operand:HI 3 "general_operand" "")))]
20581 "TARGET_HIMODE_MATH"
85845bb9 20582 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
726e2d54 20583
6343a50e 20584(define_insn "*movhicc_noc"
e075ae69 20585 [(set (match_operand:HI 0 "register_operand" "=r,r")
6300f037 20586 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
42fabf21 20587 [(reg FLAGS_REG) (const_int 0)])
e075ae69
RH
20588 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20589 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
d525dfdf 20590 "TARGET_CMOVE
7656aee4 20591 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
e075ae69 20592 "@
048b1c95
JJ
20593 cmov%O2%C1\t{%2, %0|%0, %2}
20594 cmov%O2%c1\t{%3, %0|%0, %3}"
6ef67412
JH
20595 [(set_attr "type" "icmov")
20596 (set_attr "mode" "HI")])
726e2d54 20597
4977bab6
ZW
20598(define_expand "movqicc"
20599 [(set (match_operand:QI 0 "register_operand" "")
20600 (if_then_else:QI (match_operand 1 "comparison_operator" "")
20601 (match_operand:QI 2 "general_operand" "")
20602 (match_operand:QI 3 "general_operand" "")))]
20603 "TARGET_QIMODE_MATH"
85845bb9 20604 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
4977bab6
ZW
20605
20606(define_insn_and_split "*movqicc_noc"
20607 [(set (match_operand:QI 0 "register_operand" "=r,r")
6300f037 20608 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
eaa49b49
RH
20609 [(match_operand 4 "flags_reg_operand" "")
20610 (const_int 0)])
4977bab6
ZW
20611 (match_operand:QI 2 "register_operand" "r,0")
20612 (match_operand:QI 3 "register_operand" "0,r")))]
20613 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20614 "#"
20615 "&& reload_completed"
20616 [(set (match_dup 0)
20617 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20618 (match_dup 2)
20619 (match_dup 3)))]
20620 "operands[0] = gen_lowpart (SImode, operands[0]);
20621 operands[2] = gen_lowpart (SImode, operands[2]);
20622 operands[3] = gen_lowpart (SImode, operands[3]);"
20623 [(set_attr "type" "icmov")
20624 (set_attr "mode" "SI")])
20625
85845bb9
UB
20626(define_expand "mov<mode>cc"
20627 [(set (match_operand:X87MODEF 0 "register_operand" "")
20628 (if_then_else:X87MODEF
20629 (match_operand 1 "comparison_operator" "")
20630 (match_operand:X87MODEF 2 "register_operand" "")
20631 (match_operand:X87MODEF 3 "register_operand" "")))]
20632 "(TARGET_80387 && TARGET_CMOVE)
20633 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20634 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
726e2d54 20635
eaa49b49 20636(define_insn "*movsfcc_1_387"
b5c82fa1 20637 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
6300f037 20638 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
42fabf21 20639 [(reg FLAGS_REG) (const_int 0)])
b5c82fa1
PB
20640 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20641 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
eaa49b49 20642 "TARGET_80387 && TARGET_CMOVE
7656aee4 20643 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
e075ae69 20644 "@
0f40f9f7
ZW
20645 fcmov%F1\t{%2, %0|%0, %2}
20646 fcmov%f1\t{%3, %0|%0, %3}
048b1c95
JJ
20647 cmov%O2%C1\t{%2, %0|%0, %2}
20648 cmov%O2%c1\t{%3, %0|%0, %3}"
7093c9ea
JH
20649 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20650 (set_attr "mode" "SF,SF,SI,SI")])
56710e42 20651
6343a50e 20652(define_insn "*movdfcc_1"
b5c82fa1 20653 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
6300f037 20654 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
42fabf21 20655 [(reg FLAGS_REG) (const_int 0)])
b5c82fa1
PB
20656 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20657 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
eaa49b49 20658 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
7656aee4 20659 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
e075ae69 20660 "@
0f40f9f7
ZW
20661 fcmov%F1\t{%2, %0|%0, %2}
20662 fcmov%f1\t{%3, %0|%0, %3}
7093c9ea
JH
20663 #
20664 #"
20665 [(set_attr "type" "fcmov,fcmov,multi,multi")
6ef67412 20666 (set_attr "mode" "DF")])
56710e42 20667
1e07edd3 20668(define_insn "*movdfcc_1_rex64"
b5c82fa1 20669 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
6300f037 20670 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
42fabf21 20671 [(reg FLAGS_REG) (const_int 0)])
b5c82fa1
PB
20672 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20673 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
eaa49b49 20674 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
7656aee4 20675 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
1e07edd3 20676 "@
0f40f9f7
ZW
20677 fcmov%F1\t{%2, %0|%0, %2}
20678 fcmov%f1\t{%3, %0|%0, %3}
048b1c95
JJ
20679 cmov%O2%C1\t{%2, %0|%0, %2}
20680 cmov%O2%c1\t{%3, %0|%0, %3}"
1e07edd3
JH
20681 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20682 (set_attr "mode" "DF")])
20683
7093c9ea 20684(define_split
c3c637e3 20685 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
6300f037 20686 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
eaa49b49
RH
20687 [(match_operand 4 "flags_reg_operand" "")
20688 (const_int 0)])
7093c9ea
JH
20689 (match_operand:DF 2 "nonimmediate_operand" "")
20690 (match_operand:DF 3 "nonimmediate_operand" "")))]
c3c637e3 20691 "!TARGET_64BIT && reload_completed"
7093c9ea
JH
20692 [(set (match_dup 2)
20693 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20694 (match_dup 5)
c2b814b9 20695 (match_dup 6)))
7093c9ea
JH
20696 (set (match_dup 3)
20697 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
c2b814b9 20698 (match_dup 7)
7093c9ea 20699 (match_dup 8)))]
c2b814b9
UB
20700 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20701 split_di (&operands[0], 1, &operands[2], &operands[3]);")
7093c9ea 20702
6343a50e 20703(define_insn "*movxfcc_1"
3aeae608 20704 [(set (match_operand:XF 0 "register_operand" "=f,f")
6300f037 20705 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
42fabf21 20706 [(reg FLAGS_REG) (const_int 0)])
3aeae608
JW
20707 (match_operand:XF 2 "register_operand" "f,0")
20708 (match_operand:XF 3 "register_operand" "0,f")))]
eaa49b49 20709 "TARGET_80387 && TARGET_CMOVE"
2b589241 20710 "@
0f40f9f7
ZW
20711 fcmov%F1\t{%2, %0|%0, %2}
20712 fcmov%f1\t{%3, %0|%0, %3}"
2b589241
JH
20713 [(set_attr "type" "fcmov")
20714 (set_attr "mode" "XF")])
7ada6625 20715
d51fba8e
DR
20716;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20717;; the scalar versions to have only XMM registers as operands.
20718
04e1d06b
MM
20719;; SSE5 conditional move
20720(define_insn "*sse5_pcmov_<mode>"
d51fba8e 20721 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4f3f76e6 20722 (if_then_else:MODEF
d51fba8e
DR
20723 (match_operand:MODEF 1 "register_operand" "x,0")
20724 (match_operand:MODEF 2 "register_operand" "0,x")
20725 (match_operand:MODEF 3 "register_operand" "x,x")))]
f258e5e5 20726 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
04e1d06b
MM
20727 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20728 [(set_attr "type" "sse4arg")])
20729
eaa49b49 20730;; These versions of the min/max patterns are intentionally ignorant of
35fd3193 20731;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
eaa49b49
RH
20732;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20733;; are undefined in this condition, we're certain this is correct.
7ada6625 20734
95879c72
L
20735(define_insn "*avx_<code><mode>3"
20736 [(set (match_operand:MODEF 0 "register_operand" "=x")
20737 (smaxmin:MODEF
20738 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20739 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20740 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20741 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20742 [(set_attr "type" "sseadd")
20743 (set_attr "prefix" "vex")
20744 (set_attr "mode" "<MODE>")])
20745
78e8956b 20746(define_insn "<code><mode>3"
d6023b50 20747 [(set (match_operand:MODEF 0 "register_operand" "=x")
78e8956b 20748 (smaxmin:MODEF
d6023b50
UB
20749 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20750 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20751 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
78e8956b 20752 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
ab8efbd8 20753 [(set_attr "type" "sseadd")
d6023b50 20754 (set_attr "mode" "<MODE>")])
ab8efbd8
RH
20755
20756;; These versions of the min/max patterns implement exactly the operations
20757;; min = (op1 < op2 ? op1 : op2)
20758;; max = (!(op1 < op2) ? op1 : op2)
20759;; Their operands are not commutative, and thus they may be used in the
20760;; presence of -0.0 and NaN.
20761
95879c72
L
20762(define_insn "*avx_ieee_smin<mode>3"
20763 [(set (match_operand:MODEF 0 "register_operand" "=x")
20764 (unspec:MODEF
20765 [(match_operand:MODEF 1 "register_operand" "x")
20766 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20767 UNSPEC_IEEE_MIN))]
20768 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20769 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20770 [(set_attr "type" "sseadd")
20771 (set_attr "prefix" "vex")
20772 (set_attr "mode" "<MODE>")])
20773
d6023b50
UB
20774(define_insn "*ieee_smin<mode>3"
20775 [(set (match_operand:MODEF 0 "register_operand" "=x")
20776 (unspec:MODEF
20777 [(match_operand:MODEF 1 "register_operand" "0")
20778 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20779 UNSPEC_IEEE_MIN))]
20780 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20781 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
ab8efbd8 20782 [(set_attr "type" "sseadd")
d6023b50 20783 (set_attr "mode" "<MODE>")])
ab8efbd8 20784
95879c72
L
20785(define_insn "*avx_ieee_smax<mode>3"
20786 [(set (match_operand:MODEF 0 "register_operand" "=x")
20787 (unspec:MODEF
20788 [(match_operand:MODEF 1 "register_operand" "0")
20789 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20790 UNSPEC_IEEE_MAX))]
20791 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20792 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20793 [(set_attr "type" "sseadd")
20794 (set_attr "prefix" "vex")
20795 (set_attr "mode" "<MODE>")])
20796
d6023b50
UB
20797(define_insn "*ieee_smax<mode>3"
20798 [(set (match_operand:MODEF 0 "register_operand" "=x")
20799 (unspec:MODEF
20800 [(match_operand:MODEF 1 "register_operand" "0")
20801 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20802 UNSPEC_IEEE_MAX))]
20803 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20804 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
eaa49b49 20805 [(set_attr "type" "sseadd")
d6023b50 20806 (set_attr "mode" "<MODE>")])
7ada6625 20807
bab1de0a
PB
20808;; Make two stack loads independent:
20809;; fld aa fld aa
20810;; fld %st(0) -> fld bb
20811;; fmul bb fmul %st(1), %st
20812;;
20813;; Actually we only match the last two instructions for simplicity.
20814(define_peephole2
20815 [(set (match_operand 0 "fp_register_operand" "")
20816 (match_operand 1 "fp_register_operand" ""))
20817 (set (match_dup 0)
20818 (match_operator 2 "binary_fp_operator"
20819 [(match_dup 0)
20820 (match_operand 3 "memory_operand" "")]))]
20821 "REGNO (operands[0]) != REGNO (operands[1])"
20822 [(set (match_dup 0) (match_dup 3))
20823 (set (match_dup 0) (match_dup 4))]
20824
20825 ;; The % modifier is not operational anymore in peephole2's, so we have to
20826 ;; swap the operands manually in the case of addition and multiplication.
20827 "if (COMMUTATIVE_ARITH_P (operands[2]))
20828 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20829 operands[0], operands[1]);
20830 else
20831 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20832 operands[1], operands[0]);")
20833
7b52eede 20834;; Conditional addition patterns
62d2739a
UB
20835(define_expand "add<mode>cc"
20836 [(match_operand:SWI 0 "register_operand" "")
7b52eede 20837 (match_operand 1 "comparison_operator" "")
62d2739a
UB
20838 (match_operand:SWI 2 "register_operand" "")
20839 (match_operand:SWI 3 "const_int_operand" "")]
7b52eede 20840 ""
85845bb9 20841 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
7b52eede 20842
e075ae69
RH
20843\f
20844;; Misc patterns (?)
726e2d54 20845
f5143c46 20846;; This pattern exists to put a dependency on all ebp-based memory accesses.
e075ae69 20847;; Otherwise there will be nothing to keep
6300f037 20848;;
e075ae69
RH
20849;; [(set (reg ebp) (reg esp))]
20850;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20851;; (clobber (eflags)]
20852;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20853;;
20854;; in proper program order.
b19ee4bd 20855(define_insn "pro_epilogue_adjust_stack_1"
1c71e60e
JH
20856 [(set (match_operand:SI 0 "register_operand" "=r,r")
20857 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20858 (match_operand:SI 2 "immediate_operand" "i,i")))
8bc527af 20859 (clobber (reg:CC FLAGS_REG))
f2042df3 20860 (clobber (mem:BLK (scratch)))]
8362f420 20861 "!TARGET_64BIT"
e075ae69 20862{
1c71e60e 20863 switch (get_attr_type (insn))
e075ae69 20864 {
1c71e60e 20865 case TYPE_IMOV:
0f40f9f7 20866 return "mov{l}\t{%1, %0|%0, %1}";
1c71e60e
JH
20867
20868 case TYPE_ALU:
7656aee4 20869 if (CONST_INT_P (operands[2])
1c71e60e
JH
20870 && (INTVAL (operands[2]) == 128
20871 || (INTVAL (operands[2]) < 0
20872 && INTVAL (operands[2]) != -128)))
20873 {
20874 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 20875 return "sub{l}\t{%2, %0|%0, %2}";
1c71e60e 20876 }
0f40f9f7 20877 return "add{l}\t{%2, %0|%0, %2}";
1c71e60e
JH
20878
20879 case TYPE_LEA:
20880 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 20881 return "lea{l}\t{%a2, %0|%0, %a2}";
1c71e60e
JH
20882
20883 default:
7637e42c 20884 gcc_unreachable ();
e075ae69 20885 }
0f40f9f7 20886}
1c71e60e 20887 [(set (attr "type")
b6837b94
JY
20888 (cond [(and (eq_attr "alternative" "0")
20889 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
1c71e60e
JH
20890 (const_string "alu")
20891 (match_operand:SI 2 "const0_operand" "")
20892 (const_string "imov")
20893 ]
6ef67412 20894 (const_string "lea")))
a952487c
JJ
20895 (set (attr "length_immediate")
20896 (cond [(eq_attr "type" "imov")
20897 (const_string "0")
20898 (and (eq_attr "type" "alu")
20899 (match_operand 2 "const128_operand" ""))
20900 (const_string "1")
20901 ]
20902 (const_string "*")))
6ef67412 20903 (set_attr "mode" "SI")])
578b58f5 20904
8362f420
JH
20905(define_insn "pro_epilogue_adjust_stack_rex64"
20906 [(set (match_operand:DI 0 "register_operand" "=r,r")
20907 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20908 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
8bc527af 20909 (clobber (reg:CC FLAGS_REG))
f2042df3 20910 (clobber (mem:BLK (scratch)))]
8362f420 20911 "TARGET_64BIT"
8362f420
JH
20912{
20913 switch (get_attr_type (insn))
20914 {
20915 case TYPE_IMOV:
0f40f9f7 20916 return "mov{q}\t{%1, %0|%0, %1}";
8362f420
JH
20917
20918 case TYPE_ALU:
7656aee4 20919 if (CONST_INT_P (operands[2])
b19ee4bd
JJ
20920 /* Avoid overflows. */
20921 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
8362f420
JH
20922 && (INTVAL (operands[2]) == 128
20923 || (INTVAL (operands[2]) < 0
20924 && INTVAL (operands[2]) != -128)))
20925 {
20926 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 20927 return "sub{q}\t{%2, %0|%0, %2}";
8362f420 20928 }
0f40f9f7 20929 return "add{q}\t{%2, %0|%0, %2}";
8362f420
JH
20930
20931 case TYPE_LEA:
20932 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 20933 return "lea{q}\t{%a2, %0|%0, %a2}";
8362f420
JH
20934
20935 default:
7637e42c 20936 gcc_unreachable ();
8362f420 20937 }
0f40f9f7 20938}
8362f420 20939 [(set (attr "type")
b6837b94
JY
20940 (cond [(and (eq_attr "alternative" "0")
20941 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
8362f420
JH
20942 (const_string "alu")
20943 (match_operand:DI 2 "const0_operand" "")
20944 (const_string "imov")
20945 ]
20946 (const_string "lea")))
a952487c
JJ
20947 (set (attr "length_immediate")
20948 (cond [(eq_attr "type" "imov")
20949 (const_string "0")
20950 (and (eq_attr "type" "alu")
20951 (match_operand 2 "const128_operand" ""))
20952 (const_string "1")
20953 ]
20954 (const_string "*")))
8362f420
JH
20955 (set_attr "mode" "DI")])
20956
b19ee4bd
JJ
20957(define_insn "pro_epilogue_adjust_stack_rex64_2"
20958 [(set (match_operand:DI 0 "register_operand" "=r,r")
20959 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20960 (match_operand:DI 3 "immediate_operand" "i,i")))
20961 (use (match_operand:DI 2 "register_operand" "r,r"))
8bc527af 20962 (clobber (reg:CC FLAGS_REG))
b19ee4bd
JJ
20963 (clobber (mem:BLK (scratch)))]
20964 "TARGET_64BIT"
20965{
20966 switch (get_attr_type (insn))
20967 {
20968 case TYPE_ALU:
20969 return "add{q}\t{%2, %0|%0, %2}";
20970
20971 case TYPE_LEA:
20972 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20973 return "lea{q}\t{%a2, %0|%0, %a2}";
20974
20975 default:
7637e42c 20976 gcc_unreachable ();
b19ee4bd
JJ
20977 }
20978}
20979 [(set_attr "type" "alu,lea")
20980 (set_attr "mode" "DI")])
8362f420 20981
ccf8e764 20982(define_insn "allocate_stack_worker_32"
6ea90eb7
JJ
20983 [(set (match_operand:SI 0 "register_operand" "=a")
20984 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20985 UNSPECV_STACK_PROBE))
20986 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
8bc527af 20987 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 20988 "!TARGET_64BIT && TARGET_STACK_PROBE"
ab65b56b 20989 "call\t___chkstk"
885a70fd
JH
20990 [(set_attr "type" "multi")
20991 (set_attr "length" "5")])
20992
ccf8e764 20993(define_insn "allocate_stack_worker_64"
6ea90eb7
JJ
20994 [(set (match_operand:DI 0 "register_operand" "=a")
20995 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20996 UNSPECV_STACK_PROBE))
20997 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
ccf8e764
RH
20998 (clobber (reg:DI R10_REG))
20999 (clobber (reg:DI R11_REG))
8bc527af 21000 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 21001 "TARGET_64BIT && TARGET_STACK_PROBE"
ccf8e764 21002 "call\t___chkstk"
e075ae69
RH
21003 [(set_attr "type" "multi")
21004 (set_attr "length" "5")])
578b58f5
RK
21005
21006(define_expand "allocate_stack"
ccf8e764
RH
21007 [(match_operand 0 "register_operand" "")
21008 (match_operand 1 "general_operand" "")]
e075ae69 21009 "TARGET_STACK_PROBE"
578b58f5 21010{
ccf8e764
RH
21011 rtx x;
21012
21013#ifndef CHECK_STACK_LIMIT
21014#define CHECK_STACK_LIMIT 0
21015#endif
21016
21017 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
e9a25f70 21018 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
ccf8e764
RH
21019 {
21020 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
21021 stack_pointer_rtx, 0, OPTAB_DIRECT);
21022 if (x != stack_pointer_rtx)
21023 emit_move_insn (stack_pointer_rtx, x);
21024 }
6300f037 21025 else
ccf8e764
RH
21026 {
21027 x = copy_to_mode_reg (Pmode, operands[1]);
21028 if (TARGET_64BIT)
6ea90eb7 21029 x = gen_allocate_stack_worker_64 (x, x);
ccf8e764 21030 else
6ea90eb7 21031 x = gen_allocate_stack_worker_32 (x, x);
ccf8e764
RH
21032 emit_insn (x);
21033 }
578b58f5 21034
e9a25f70
JL
21035 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
21036 DONE;
0f40f9f7 21037})
e31ca113 21038
fb754025
AG
21039(define_expand "builtin_setjmp_receiver"
21040 [(label_ref (match_operand 0 "" ""))]
1b0c37d7 21041 "!TARGET_64BIT && flag_pic"
fb754025 21042{
08a6a74b 21043#if TARGET_MACHO
7d072037
SH
21044 if (TARGET_MACHO)
21045 {
21046 rtx xops[3];
21047 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
21048 rtx label_rtx = gen_label_rtx ();
21049 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
7d072037 21050 xops[0] = xops[1] = picreg;
08a6a74b 21051 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
7d072037
SH
21052 ix86_expand_binary_operator (MINUS, SImode, xops);
21053 }
21054 else
08a6a74b 21055#endif
7d072037 21056 emit_insn (gen_set_got (pic_offset_table_rtx));
fb754025 21057 DONE;
0f40f9f7 21058})
e9e80858
JH
21059\f
21060;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
21061
21062(define_split
21063 [(set (match_operand 0 "register_operand" "")
21064 (match_operator 3 "promotable_binary_operator"
21065 [(match_operand 1 "register_operand" "")
2247f6ed 21066 (match_operand 2 "aligned_operand" "")]))
8bc527af 21067 (clobber (reg:CC FLAGS_REG))]
e9e80858 21068 "! TARGET_PARTIAL_REG_STALL && reload_completed
6300f037 21069 && ((GET_MODE (operands[0]) == HImode
3debdc1e 21070 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
f38840db 21071 /* ??? next two lines just !satisfies_constraint_K (...) */
7656aee4 21072 || !CONST_INT_P (operands[2])
f38840db 21073 || satisfies_constraint_K (operands[2])))
6300f037 21074 || (GET_MODE (operands[0]) == QImode
3debdc1e 21075 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
e9e80858
JH
21076 [(parallel [(set (match_dup 0)
21077 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8bc527af 21078 (clobber (reg:CC FLAGS_REG))])]
e9e80858
JH
21079 "operands[0] = gen_lowpart (SImode, operands[0]);
21080 operands[1] = gen_lowpart (SImode, operands[1]);
21081 if (GET_CODE (operands[3]) != ASHIFT)
21082 operands[2] = gen_lowpart (SImode, operands[2]);
dbbbbf3b 21083 PUT_MODE (operands[3], SImode);")
e9e80858 21084
d2fc7725
EB
21085; Promote the QImode tests, as i386 has encoding of the AND
21086; instruction with 32-bit sign-extended immediate and thus the
21087; instruction size is unchanged, except in the %eax case for
21088; which it is increased by one byte, hence the ! optimize_size.
e9e80858 21089(define_split
25da5dc7
RH
21090 [(set (match_operand 0 "flags_reg_operand" "")
21091 (match_operator 2 "compare_operator"
21092 [(and (match_operand 3 "aligned_operand" "")
21093 (match_operand 4 "const_int_operand" ""))
21094 (const_int 0)]))
21095 (set (match_operand 1 "register_operand" "")
21096 (and (match_dup 3) (match_dup 4)))]
e9e80858 21097 "! TARGET_PARTIAL_REG_STALL && reload_completed
3debdc1e 21098 && optimize_insn_for_speed_p ()
25da5dc7 21099 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
d5d5d289
L
21100 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
21101 /* Ensure that the operand will remain sign-extended immediate. */
21102 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
25da5dc7
RH
21103 [(parallel [(set (match_dup 0)
21104 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
21105 (const_int 0)]))
21106 (set (match_dup 1)
21107 (and:SI (match_dup 3) (match_dup 4)))])]
21108{
21109 operands[4]
21110 = gen_int_mode (INTVAL (operands[4])
21111 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
21112 operands[1] = gen_lowpart (SImode, operands[1]);
21113 operands[3] = gen_lowpart (SImode, operands[3]);
21114})
e9e80858 21115
d2fc7725
EB
21116; Don't promote the QImode tests, as i386 doesn't have encoding of
21117; the TEST instruction with 32-bit sign-extended immediate and thus
21118; the instruction size would at least double, which is not what we
21119; want even with ! optimize_size.
e9e80858 21120(define_split
25da5dc7
RH
21121 [(set (match_operand 0 "flags_reg_operand" "")
21122 (match_operator 1 "compare_operator"
21123 [(and (match_operand:HI 2 "aligned_operand" "")
21124 (match_operand:HI 3 "const_int_operand" ""))
21125 (const_int 0)]))]
e9e80858 21126 "! TARGET_PARTIAL_REG_STALL && reload_completed
d2fc7725 21127 && ! TARGET_FAST_PREFIX
b2077fd2 21128 && optimize_insn_for_speed_p ()
d5d5d289
L
21129 /* Ensure that the operand will remain sign-extended immediate. */
21130 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
25da5dc7
RH
21131 [(set (match_dup 0)
21132 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21133 (const_int 0)]))]
21134{
21135 operands[3]
21136 = gen_int_mode (INTVAL (operands[3])
21137 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
21138 operands[2] = gen_lowpart (SImode, operands[2]);
21139})
e9e80858
JH
21140
21141(define_split
21142 [(set (match_operand 0 "register_operand" "")
21143 (neg (match_operand 1 "register_operand" "")))
8bc527af 21144 (clobber (reg:CC FLAGS_REG))]
e9e80858
JH
21145 "! TARGET_PARTIAL_REG_STALL && reload_completed
21146 && (GET_MODE (operands[0]) == HImode
6300f037 21147 || (GET_MODE (operands[0]) == QImode
b2077fd2
JH
21148 && (TARGET_PROMOTE_QImode
21149 || optimize_insn_for_size_p ())))"
e9e80858
JH
21150 [(parallel [(set (match_dup 0)
21151 (neg:SI (match_dup 1)))
8bc527af 21152 (clobber (reg:CC FLAGS_REG))])]
e9e80858
JH
21153 "operands[0] = gen_lowpart (SImode, operands[0]);
21154 operands[1] = gen_lowpart (SImode, operands[1]);")
21155
21156(define_split
21157 [(set (match_operand 0 "register_operand" "")
21158 (not (match_operand 1 "register_operand" "")))]
21159 "! TARGET_PARTIAL_REG_STALL && reload_completed
21160 && (GET_MODE (operands[0]) == HImode
6300f037 21161 || (GET_MODE (operands[0]) == QImode
b2077fd2
JH
21162 && (TARGET_PROMOTE_QImode
21163 || optimize_insn_for_size_p ())))"
e9e80858
JH
21164 [(set (match_dup 0)
21165 (not:SI (match_dup 1)))]
21166 "operands[0] = gen_lowpart (SImode, operands[0]);
21167 operands[1] = gen_lowpart (SImode, operands[1]);")
21168
6300f037 21169(define_split
e9e80858 21170 [(set (match_operand 0 "register_operand" "")
6300f037 21171 (if_then_else (match_operator 1 "comparison_operator"
42fabf21 21172 [(reg FLAGS_REG) (const_int 0)])
e9e80858
JH
21173 (match_operand 2 "register_operand" "")
21174 (match_operand 3 "register_operand" "")))]
21175 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
21176 && (GET_MODE (operands[0]) == HImode
6300f037 21177 || (GET_MODE (operands[0]) == QImode
b2077fd2
JH
21178 && (TARGET_PROMOTE_QImode
21179 || optimize_insn_for_size_p ())))"
e9e80858
JH
21180 [(set (match_dup 0)
21181 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
21182 "operands[0] = gen_lowpart (SImode, operands[0]);
21183 operands[2] = gen_lowpart (SImode, operands[2]);
21184 operands[3] = gen_lowpart (SImode, operands[3]);")
6300f037 21185
e075ae69
RH
21186\f
21187;; RTL Peephole optimizations, run before sched2. These primarily look to
21188;; transform a complex memory operation into two memory to register operations.
21189
21190;; Don't push memory operands
21191(define_peephole2
3071fab5
RH
21192 [(set (match_operand:SI 0 "push_operand" "")
21193 (match_operand:SI 1 "memory_operand" ""))
21194 (match_scratch:SI 2 "r")]
b2077fd2 21195 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
150cdc9e 21196 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
e075ae69
RH
21197 [(set (match_dup 2) (match_dup 1))
21198 (set (match_dup 0) (match_dup 2))]
21199 "")
21200
cc2e591b
JH
21201(define_peephole2
21202 [(set (match_operand:DI 0 "push_operand" "")
21203 (match_operand:DI 1 "memory_operand" ""))
21204 (match_scratch:DI 2 "r")]
b2077fd2 21205 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
150cdc9e 21206 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
cc2e591b
JH
21207 [(set (match_dup 2) (match_dup 1))
21208 (set (match_dup 0) (match_dup 2))]
21209 "")
21210
e9e80858
JH
21211;; We need to handle SFmode only, because DFmode and XFmode is split to
21212;; SImode pushes.
21213(define_peephole2
21214 [(set (match_operand:SF 0 "push_operand" "")
21215 (match_operand:SF 1 "memory_operand" ""))
21216 (match_scratch:SF 2 "r")]
b2077fd2 21217 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
150cdc9e 21218 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
e9e80858
JH
21219 [(set (match_dup 2) (match_dup 1))
21220 (set (match_dup 0) (match_dup 2))]
21221 "")
21222
e075ae69 21223(define_peephole2
3071fab5
RH
21224 [(set (match_operand:HI 0 "push_operand" "")
21225 (match_operand:HI 1 "memory_operand" ""))
21226 (match_scratch:HI 2 "r")]
b2077fd2 21227 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
150cdc9e 21228 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
e075ae69
RH
21229 [(set (match_dup 2) (match_dup 1))
21230 (set (match_dup 0) (match_dup 2))]
21231 "")
21232
21233(define_peephole2
3071fab5
RH
21234 [(set (match_operand:QI 0 "push_operand" "")
21235 (match_operand:QI 1 "memory_operand" ""))
21236 (match_scratch:QI 2 "q")]
b2077fd2 21237 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
150cdc9e 21238 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
e075ae69
RH
21239 [(set (match_dup 2) (match_dup 1))
21240 (set (match_dup 0) (match_dup 2))]
21241 "")
21242
21243;; Don't move an immediate directly to memory when the instruction
21244;; gets too big.
21245(define_peephole2
21246 [(match_scratch:SI 1 "r")
21247 (set (match_operand:SI 0 "memory_operand" "")
21248 (const_int 0))]
b2077fd2 21249 "optimize_insn_for_speed_p ()
591702de 21250 && ! TARGET_USE_MOV0
23280139 21251 && TARGET_SPLIT_LONG_MOVES
b2077fd2 21252 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
23280139 21253 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69 21254 [(parallel [(set (match_dup 1) (const_int 0))
8bc527af 21255 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
21256 (set (match_dup 0) (match_dup 1))]
21257 "")
21258
21259(define_peephole2
21260 [(match_scratch:HI 1 "r")
21261 (set (match_operand:HI 0 "memory_operand" "")
21262 (const_int 0))]
b2077fd2 21263 "optimize_insn_for_speed_p ()
591702de 21264 && ! TARGET_USE_MOV0
23280139 21265 && TARGET_SPLIT_LONG_MOVES
b2077fd2 21266 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
23280139 21267 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 21268 [(parallel [(set (match_dup 2) (const_int 0))
8bc527af 21269 (clobber (reg:CC FLAGS_REG))])
e075ae69 21270 (set (match_dup 0) (match_dup 1))]
1e2115dc 21271 "operands[2] = gen_lowpart (SImode, operands[1]);")
e075ae69
RH
21272
21273(define_peephole2
21274 [(match_scratch:QI 1 "q")
21275 (set (match_operand:QI 0 "memory_operand" "")
21276 (const_int 0))]
b2077fd2 21277 "optimize_insn_for_speed_p ()
591702de 21278 && ! TARGET_USE_MOV0
23280139 21279 && TARGET_SPLIT_LONG_MOVES
b2077fd2 21280 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
23280139 21281 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 21282 [(parallel [(set (match_dup 2) (const_int 0))
8bc527af 21283 (clobber (reg:CC FLAGS_REG))])
e075ae69 21284 (set (match_dup 0) (match_dup 1))]
1e2115dc 21285 "operands[2] = gen_lowpart (SImode, operands[1]);")
e075ae69
RH
21286
21287(define_peephole2
21288 [(match_scratch:SI 2 "r")
21289 (set (match_operand:SI 0 "memory_operand" "")
21290 (match_operand:SI 1 "immediate_operand" ""))]
b2077fd2 21291 "optimize_insn_for_speed_p ()
d5d5d289 21292 && TARGET_SPLIT_LONG_MOVES
b2077fd2 21293 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
e075ae69
RH
21294 [(set (match_dup 2) (match_dup 1))
21295 (set (match_dup 0) (match_dup 2))]
21296 "")
21297
21298(define_peephole2
21299 [(match_scratch:HI 2 "r")
21300 (set (match_operand:HI 0 "memory_operand" "")
21301 (match_operand:HI 1 "immediate_operand" ""))]
b2077fd2 21302 "optimize_insn_for_speed_p ()
d5d5d289 21303 && TARGET_SPLIT_LONG_MOVES
b2077fd2 21304 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
e075ae69
RH
21305 [(set (match_dup 2) (match_dup 1))
21306 (set (match_dup 0) (match_dup 2))]
21307 "")
21308
21309(define_peephole2
21310 [(match_scratch:QI 2 "q")
21311 (set (match_operand:QI 0 "memory_operand" "")
21312 (match_operand:QI 1 "immediate_operand" ""))]
b2077fd2 21313 "optimize_insn_for_speed_p ()
d5d5d289 21314 && TARGET_SPLIT_LONG_MOVES
b2077fd2 21315 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
e075ae69
RH
21316 [(set (match_dup 2) (match_dup 1))
21317 (set (match_dup 0) (match_dup 2))]
21318 "")
21319
21320;; Don't compare memory with zero, load and use a test instead.
21321(define_peephole2
25da5dc7
RH
21322 [(set (match_operand 0 "flags_reg_operand" "")
21323 (match_operator 1 "compare_operator"
21324 [(match_operand:SI 2 "memory_operand" "")
21325 (const_int 0)]))
3071fab5 21326 (match_scratch:SI 3 "r")]
b2077fd2 21327 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
21328 [(set (match_dup 3) (match_dup 2))
21329 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
e075ae69
RH
21330 "")
21331
6300f037 21332;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
e075ae69 21333;; Don't split NOTs with a displacement operand, because resulting XOR
d1f87653 21334;; will not be pairable anyway.
e075ae69 21335;;
1e5f1716 21336;; On AMD K6, NOT is vector decoded with memory operand that cannot be
e075ae69
RH
21337;; represented using a modRM byte. The XOR replacement is long decoded,
21338;; so this split helps here as well.
21339;;
23280139
RH
21340;; Note: Can't do this as a regular split because we can't get proper
21341;; lifetime information then.
e075ae69
RH
21342
21343(define_peephole2
d5d6a58b
RH
21344 [(set (match_operand:SI 0 "nonimmediate_operand" "")
21345 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
b2077fd2 21346 "optimize_insn_for_speed_p ()
ddff69b9 21347 && ((TARGET_NOT_UNPAIRABLE
7656aee4 21348 && (!MEM_P (operands[0])
e075ae69 21349 || !memory_displacement_operand (operands[0], SImode)))
d5d5d289
L
21350 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
21351 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69
RH
21352 [(parallel [(set (match_dup 0)
21353 (xor:SI (match_dup 1) (const_int -1)))
8bc527af 21354 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
21355 "")
21356
21357(define_peephole2
d5d6a58b
RH
21358 [(set (match_operand:HI 0 "nonimmediate_operand" "")
21359 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
b2077fd2 21360 "optimize_insn_for_speed_p ()
ddff69b9 21361 && ((TARGET_NOT_UNPAIRABLE
7656aee4 21362 && (!MEM_P (operands[0])
e075ae69 21363 || !memory_displacement_operand (operands[0], HImode)))
d5d5d289
L
21364 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
21365 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69
RH
21366 [(parallel [(set (match_dup 0)
21367 (xor:HI (match_dup 1) (const_int -1)))
8bc527af 21368 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
21369 "")
21370
21371(define_peephole2
d5d6a58b
RH
21372 [(set (match_operand:QI 0 "nonimmediate_operand" "")
21373 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
b2077fd2 21374 "optimize_insn_for_speed_p ()
ddff69b9 21375 && ((TARGET_NOT_UNPAIRABLE
7656aee4 21376 && (!MEM_P (operands[0])
e075ae69 21377 || !memory_displacement_operand (operands[0], QImode)))
d5d5d289
L
21378 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
21379 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69
RH
21380 [(parallel [(set (match_dup 0)
21381 (xor:QI (match_dup 1) (const_int -1)))
8bc527af 21382 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
21383 "")
21384
21385;; Non pairable "test imm, reg" instructions can be translated to
21386;; "and imm, reg" if reg dies. The "and" form is also shorter (one
21387;; byte opcode instead of two, have a short form for byte operands),
21388;; so do it for other CPUs as well. Given that the value was dead,
f5143c46 21389;; this should not create any new dependencies. Pass on the sub-word
e075ae69
RH
21390;; versions if we're concerned about partial register stalls.
21391
21392(define_peephole2
25da5dc7
RH
21393 [(set (match_operand 0 "flags_reg_operand" "")
21394 (match_operator 1 "compare_operator"
21395 [(and:SI (match_operand:SI 2 "register_operand" "")
21396 (match_operand:SI 3 "immediate_operand" ""))
21397 (const_int 0)]))]
16189740 21398 "ix86_match_ccmode (insn, CCNOmode)
29b74761 21399 && (true_regnum (operands[2]) != AX_REG
f38840db 21400 || satisfies_constraint_K (operands[3]))
25da5dc7 21401 && peep2_reg_dead_p (1, operands[2])"
e075ae69 21402 [(parallel
25da5dc7
RH
21403 [(set (match_dup 0)
21404 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21405 (const_int 0)]))
21406 (set (match_dup 2)
21407 (and:SI (match_dup 2) (match_dup 3)))])]
e075ae69
RH
21408 "")
21409
e9e80858
JH
21410;; We don't need to handle HImode case, because it will be promoted to SImode
21411;; on ! TARGET_PARTIAL_REG_STALL
e075ae69
RH
21412
21413(define_peephole2
25da5dc7
RH
21414 [(set (match_operand 0 "flags_reg_operand" "")
21415 (match_operator 1 "compare_operator"
21416 [(and:QI (match_operand:QI 2 "register_operand" "")
21417 (match_operand:QI 3 "immediate_operand" ""))
21418 (const_int 0)]))]
e075ae69 21419 "! TARGET_PARTIAL_REG_STALL
16189740 21420 && ix86_match_ccmode (insn, CCNOmode)
29b74761 21421 && true_regnum (operands[2]) != AX_REG
25da5dc7 21422 && peep2_reg_dead_p (1, operands[2])"
e075ae69 21423 [(parallel
25da5dc7
RH
21424 [(set (match_dup 0)
21425 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
21426 (const_int 0)]))
21427 (set (match_dup 2)
21428 (and:QI (match_dup 2) (match_dup 3)))])]
e075ae69
RH
21429 "")
21430
21431(define_peephole2
25da5dc7
RH
21432 [(set (match_operand 0 "flags_reg_operand" "")
21433 (match_operator 1 "compare_operator"
21434 [(and:SI
21435 (zero_extract:SI
21436 (match_operand 2 "ext_register_operand" "")
21437 (const_int 8)
21438 (const_int 8))
21439 (match_operand 3 "const_int_operand" ""))
21440 (const_int 0)]))]
e075ae69 21441 "! TARGET_PARTIAL_REG_STALL
16189740 21442 && ix86_match_ccmode (insn, CCNOmode)
29b74761 21443 && true_regnum (operands[2]) != AX_REG
25da5dc7
RH
21444 && peep2_reg_dead_p (1, operands[2])"
21445 [(parallel [(set (match_dup 0)
21446 (match_op_dup 1
21447 [(and:SI
21448 (zero_extract:SI
21449 (match_dup 2)
21450 (const_int 8)
21451 (const_int 8))
21452 (match_dup 3))
21453 (const_int 0)]))
21454 (set (zero_extract:SI (match_dup 2)
e075ae69
RH
21455 (const_int 8)
21456 (const_int 8))
6300f037 21457 (and:SI
e075ae69 21458 (zero_extract:SI
25da5dc7 21459 (match_dup 2)
e075ae69
RH
21460 (const_int 8)
21461 (const_int 8))
25da5dc7 21462 (match_dup 3)))])]
e075ae69
RH
21463 "")
21464
21465;; Don't do logical operations with memory inputs.
21466(define_peephole2
21467 [(match_scratch:SI 2 "r")
21468 (parallel [(set (match_operand:SI 0 "register_operand" "")
21469 (match_operator:SI 3 "arith_or_logical_operator"
21470 [(match_dup 0)
21471 (match_operand:SI 1 "memory_operand" "")]))
8bc527af 21472 (clobber (reg:CC FLAGS_REG))])]
3cdf0c62 21473 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
e075ae69
RH
21474 [(set (match_dup 2) (match_dup 1))
21475 (parallel [(set (match_dup 0)
21476 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
8bc527af 21477 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
21478 "")
21479
21480(define_peephole2
21481 [(match_scratch:SI 2 "r")
21482 (parallel [(set (match_operand:SI 0 "register_operand" "")
21483 (match_operator:SI 3 "arith_or_logical_operator"
21484 [(match_operand:SI 1 "memory_operand" "")
21485 (match_dup 0)]))
8bc527af 21486 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 21487 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
e075ae69
RH
21488 [(set (match_dup 2) (match_dup 1))
21489 (parallel [(set (match_dup 0)
21490 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
8bc527af 21491 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
21492 "")
21493
bab64f23
PB
21494;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
21495;; refers to the destination of the load!
21496
21497(define_peephole2
21498 [(set (match_operand:SI 0 "register_operand" "")
21499 (match_operand:SI 1 "register_operand" ""))
21500 (parallel [(set (match_dup 0)
21501 (match_operator:SI 3 "commutative_operator"
21502 [(match_dup 0)
21503 (match_operand:SI 2 "memory_operand" "")]))
21504 (clobber (reg:CC FLAGS_REG))])]
bbb52802 21505 "REGNO (operands[0]) != REGNO (operands[1])
72f4e3a7
L
21506 && GENERAL_REGNO_P (REGNO (operands[0]))
21507 && GENERAL_REGNO_P (REGNO (operands[1]))"
bab64f23
PB
21508 [(set (match_dup 0) (match_dup 4))
21509 (parallel [(set (match_dup 0)
21510 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
21511 (clobber (reg:CC FLAGS_REG))])]
12019aec 21512 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
bab64f23
PB
21513
21514(define_peephole2
21515 [(set (match_operand 0 "register_operand" "")
21516 (match_operand 1 "register_operand" ""))
21517 (set (match_dup 0)
21518 (match_operator 3 "commutative_operator"
21519 [(match_dup 0)
21520 (match_operand 2 "memory_operand" "")]))]
bbb52802 21521 "REGNO (operands[0]) != REGNO (operands[1])
47f5a48f
L
21522 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
21523 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
bab64f23
PB
21524 [(set (match_dup 0) (match_dup 2))
21525 (set (match_dup 0)
21526 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
21527 "")
21528
e075ae69
RH
21529; Don't do logical operations with memory outputs
21530;
21531; These two don't make sense for PPro/PII -- we're expanding a 4-uop
21532; instruction into two 1-uop insns plus a 2-uop insn. That last has
21533; the same decoder scheduling characteristics as the original.
21534
21535(define_peephole2
21536 [(match_scratch:SI 2 "r")
21537 (parallel [(set (match_operand:SI 0 "memory_operand" "")
21538 (match_operator:SI 3 "arith_or_logical_operator"
21539 [(match_dup 0)
21540 (match_operand:SI 1 "nonmemory_operand" "")]))
8bc527af 21541 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 21542 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
e075ae69
RH
21543 [(set (match_dup 2) (match_dup 0))
21544 (parallel [(set (match_dup 2)
21545 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
8bc527af 21546 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
21547 (set (match_dup 0) (match_dup 2))]
21548 "")
21549
21550(define_peephole2
21551 [(match_scratch:SI 2 "r")
21552 (parallel [(set (match_operand:SI 0 "memory_operand" "")
21553 (match_operator:SI 3 "arith_or_logical_operator"
21554 [(match_operand:SI 1 "nonmemory_operand" "")
21555 (match_dup 0)]))
8bc527af 21556 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 21557 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
e075ae69
RH
21558 [(set (match_dup 2) (match_dup 0))
21559 (parallel [(set (match_dup 2)
21560 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8bc527af 21561 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
21562 (set (match_dup 0) (match_dup 2))]
21563 "")
21564
21565;; Attempt to always use XOR for zeroing registers.
21566(define_peephole2
21567 [(set (match_operand 0 "register_operand" "")
b4e82619
RH
21568 (match_operand 1 "const0_operand" ""))]
21569 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
b2077fd2 21570 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
f75959a6 21571 && GENERAL_REG_P (operands[0])
23280139 21572 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69 21573 [(parallel [(set (match_dup 0) (const_int 0))
8bc527af 21574 (clobber (reg:CC FLAGS_REG))])]
b4e82619
RH
21575{
21576 operands[0] = gen_lowpart (word_mode, operands[0]);
21577})
d3a923ee 21578
6ef67412
JH
21579(define_peephole2
21580 [(set (strict_low_part (match_operand 0 "register_operand" ""))
21581 (const_int 0))]
21582 "(GET_MODE (operands[0]) == QImode
21583 || GET_MODE (operands[0]) == HImode)
b2077fd2 21584 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
6ef67412
JH
21585 && peep2_regno_dead_p (0, FLAGS_REG)"
21586 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
8bc527af 21587 (clobber (reg:CC FLAGS_REG))])])
6ef67412 21588
e075ae69
RH
21589;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21590(define_peephole2
591702de 21591 [(set (match_operand 0 "register_operand" "")
e075ae69 21592 (const_int -1))]
591702de 21593 "(GET_MODE (operands[0]) == HImode
6300f037 21594 || GET_MODE (operands[0]) == SImode
cc2e591b 21595 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
b2077fd2 21596 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
23280139 21597 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 21598 [(parallel [(set (match_dup 0) (const_int -1))
8bc527af 21599 (clobber (reg:CC FLAGS_REG))])]
1e2115dc
JZ
21600 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21601 operands[0]);")
1c27d4b2
JH
21602
21603;; Attempt to convert simple leas to adds. These can be created by
21604;; move expanders.
21605(define_peephole2
21606 [(set (match_operand:SI 0 "register_operand" "")
21607 (plus:SI (match_dup 0)
21608 (match_operand:SI 1 "nonmemory_operand" "")))]
23280139 21609 "peep2_regno_dead_p (0, FLAGS_REG)"
1c27d4b2 21610 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
8bc527af 21611 (clobber (reg:CC FLAGS_REG))])]
1c27d4b2
JH
21612 "")
21613
cc2e591b
JH
21614(define_peephole2
21615 [(set (match_operand:SI 0 "register_operand" "")
21616 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21617 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21618 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21619 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
8bc527af 21620 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
21621 "operands[2] = gen_lowpart (SImode, operands[2]);")
21622
21623(define_peephole2
21624 [(set (match_operand:DI 0 "register_operand" "")
21625 (plus:DI (match_dup 0)
21626 (match_operand:DI 1 "x86_64_general_operand" "")))]
21627 "peep2_regno_dead_p (0, FLAGS_REG)"
21628 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
8bc527af 21629 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
21630 "")
21631
1c27d4b2
JH
21632(define_peephole2
21633 [(set (match_operand:SI 0 "register_operand" "")
21634 (mult:SI (match_dup 0)
cc2e591b 21635 (match_operand:SI 1 "const_int_operand" "")))]
23280139
RH
21636 "exact_log2 (INTVAL (operands[1])) >= 0
21637 && peep2_regno_dead_p (0, FLAGS_REG)"
1c27d4b2 21638 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
8bc527af 21639 (clobber (reg:CC FLAGS_REG))])]
1c27d4b2 21640 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
bdeb029c 21641
cc2e591b
JH
21642(define_peephole2
21643 [(set (match_operand:DI 0 "register_operand" "")
21644 (mult:DI (match_dup 0)
21645 (match_operand:DI 1 "const_int_operand" "")))]
21646 "exact_log2 (INTVAL (operands[1])) >= 0
21647 && peep2_regno_dead_p (0, FLAGS_REG)"
21648 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
8bc527af 21649 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
21650 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21651
21652(define_peephole2
21653 [(set (match_operand:SI 0 "register_operand" "")
21654 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21655 (match_operand:DI 2 "const_int_operand" "")) 0))]
4c9c9a3d 21656 "exact_log2 (INTVAL (operands[2])) >= 0
cc2e591b
JH
21657 && REGNO (operands[0]) == REGNO (operands[1])
21658 && peep2_regno_dead_p (0, FLAGS_REG)"
21659 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
8bc527af 21660 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
21661 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21662
bdeb029c
JH
21663;; The ESP adjustments can be done by the push and pop instructions. Resulting
21664;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
21665;; many CPUs it is also faster, since special hardware to avoid esp
f5143c46 21666;; dependencies is present.
bdeb029c 21667
d6a7951f 21668;; While some of these conversions may be done using splitters, we use peepholes
bdeb029c
JH
21669;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21670
f5143c46 21671;; Convert prologue esp subtractions to push.
bdeb029c
JH
21672;; We need register to push. In order to keep verify_flow_info happy we have
21673;; two choices
21674;; - use scratch and clobber it in order to avoid dependencies
21675;; - use already live register
21676;; We can't use the second way right now, since there is no reliable way how to
21677;; verify that given register is live. First choice will also most likely in
21678;; fewer dependencies. On the place of esp adjustments it is very likely that
21679;; call clobbered registers are dead. We may want to use base pointer as an
21680;; alternative when no register is available later.
21681
21682(define_peephole2
21683 [(match_scratch:SI 0 "r")
8bc527af
SB
21684 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21685 (clobber (reg:CC FLAGS_REG))
f2042df3 21686 (clobber (mem:BLK (scratch)))])]
b2077fd2 21687 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
bdeb029c 21688 [(clobber (match_dup 0))
8bc527af 21689 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
f2042df3 21690 (clobber (mem:BLK (scratch)))])])
bdeb029c
JH
21691
21692(define_peephole2
21693 [(match_scratch:SI 0 "r")
8bc527af
SB
21694 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21695 (clobber (reg:CC FLAGS_REG))
f2042df3 21696 (clobber (mem:BLK (scratch)))])]
b2077fd2 21697 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
bdeb029c 21698 [(clobber (match_dup 0))
8bc527af
SB
21699 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21700 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
f2042df3 21701 (clobber (mem:BLK (scratch)))])])
bdeb029c 21702
f5143c46 21703;; Convert esp subtractions to push.
bdeb029c
JH
21704(define_peephole2
21705 [(match_scratch:SI 0 "r")
8bc527af
SB
21706 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21707 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 21708 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
bdeb029c 21709 [(clobber (match_dup 0))
8bc527af 21710 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
bdeb029c
JH
21711
21712(define_peephole2
21713 [(match_scratch:SI 0 "r")
8bc527af
SB
21714 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21715 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 21716 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
bdeb029c 21717 [(clobber (match_dup 0))
8bc527af
SB
21718 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21719 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
bdeb029c
JH
21720
21721;; Convert epilogue deallocator to pop.
21722(define_peephole2
21723 [(match_scratch:SI 0 "r")
8bc527af
SB
21724 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21725 (clobber (reg:CC FLAGS_REG))
f2042df3 21726 (clobber (mem:BLK (scratch)))])]
b2077fd2 21727 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
8bc527af
SB
21728 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21729 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 21730 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
21731 "")
21732
21733;; Two pops case is tricky, since pop causes dependency on destination register.
21734;; We use two registers if available.
21735(define_peephole2
21736 [(match_scratch:SI 0 "r")
21737 (match_scratch:SI 1 "r")
8bc527af
SB
21738 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21739 (clobber (reg:CC FLAGS_REG))
f2042df3 21740 (clobber (mem:BLK (scratch)))])]
b2077fd2 21741 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
8bc527af
SB
21742 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21743 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 21744 (clobber (mem:BLK (scratch)))])
8bc527af
SB
21745 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21746 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
21747 "")
21748
21749(define_peephole2
21750 [(match_scratch:SI 0 "r")
8bc527af
SB
21751 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21752 (clobber (reg:CC FLAGS_REG))
f2042df3 21753 (clobber (mem:BLK (scratch)))])]
b2077fd2 21754 "optimize_insn_for_size_p ()"
8bc527af
SB
21755 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21756 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 21757 (clobber (mem:BLK (scratch)))])
8bc527af
SB
21758 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21759 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
21760 "")
21761
21762;; Convert esp additions to pop.
21763(define_peephole2
21764 [(match_scratch:SI 0 "r")
8bc527af
SB
21765 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21766 (clobber (reg:CC FLAGS_REG))])]
bdeb029c 21767 ""
8bc527af
SB
21768 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21769 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
21770 "")
21771
21772;; Two pops case is tricky, since pop causes dependency on destination register.
21773;; We use two registers if available.
21774(define_peephole2
21775 [(match_scratch:SI 0 "r")
21776 (match_scratch:SI 1 "r")
8bc527af
SB
21777 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21778 (clobber (reg:CC FLAGS_REG))])]
bdeb029c 21779 ""
8bc527af
SB
21780 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21781 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21782 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21783 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
21784 "")
21785
21786(define_peephole2
21787 [(match_scratch:SI 0 "r")
8bc527af
SB
21788 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21789 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 21790 "optimize_insn_for_size_p ()"
8bc527af
SB
21791 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21792 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21793 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21794 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c 21795 "")
69404d6f 21796\f
9dcbdc7e 21797;; Convert compares with 1 to shorter inc/dec operations when CF is not
6396547e 21798;; required and register dies. Similarly for 128 to -128.
9dcbdc7e 21799(define_peephole2
25da5dc7
RH
21800 [(set (match_operand 0 "flags_reg_operand" "")
21801 (match_operator 1 "compare_operator"
21802 [(match_operand 2 "register_operand" "")
21803 (match_operand 3 "const_int_operand" "")]))]
700ae70c 21804 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
6396547e
L
21805 && incdec_operand (operands[3], GET_MODE (operands[3])))
21806 || (!TARGET_FUSE_CMP_AND_BRANCH
21807 && INTVAL (operands[3]) == 128))
25da5dc7
RH
21808 && ix86_match_ccmode (insn, CCGCmode)
21809 && peep2_reg_dead_p (1, operands[2])"
21810 [(parallel [(set (match_dup 0)
21811 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21812 (clobber (match_dup 2))])]
9dcbdc7e
JH
21813 "")
21814\f
cc2e591b
JH
21815(define_peephole2
21816 [(match_scratch:DI 0 "r")
8bc527af
SB
21817 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21818 (clobber (reg:CC FLAGS_REG))
f2042df3 21819 (clobber (mem:BLK (scratch)))])]
b2077fd2 21820 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
cc2e591b 21821 [(clobber (match_dup 0))
8bc527af 21822 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
f2042df3 21823 (clobber (mem:BLK (scratch)))])])
cc2e591b
JH
21824
21825(define_peephole2
21826 [(match_scratch:DI 0 "r")
8bc527af
SB
21827 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21828 (clobber (reg:CC FLAGS_REG))
f2042df3 21829 (clobber (mem:BLK (scratch)))])]
b2077fd2 21830 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
cc2e591b 21831 [(clobber (match_dup 0))
8bc527af
SB
21832 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21833 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
f2042df3 21834 (clobber (mem:BLK (scratch)))])])
cc2e591b 21835
f5143c46 21836;; Convert esp subtractions to push.
cc2e591b
JH
21837(define_peephole2
21838 [(match_scratch:DI 0 "r")
8bc527af
SB
21839 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21840 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 21841 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
cc2e591b 21842 [(clobber (match_dup 0))
8bc527af 21843 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
cc2e591b
JH
21844
21845(define_peephole2
21846 [(match_scratch:DI 0 "r")
8bc527af
SB
21847 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21848 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 21849 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
cc2e591b 21850 [(clobber (match_dup 0))
8bc527af
SB
21851 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21852 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
cc2e591b
JH
21853
21854;; Convert epilogue deallocator to pop.
21855(define_peephole2
21856 [(match_scratch:DI 0 "r")
8bc527af
SB
21857 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21858 (clobber (reg:CC FLAGS_REG))
f2042df3 21859 (clobber (mem:BLK (scratch)))])]
b2077fd2 21860 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
8bc527af
SB
21861 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21862 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 21863 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
21864 "")
21865
21866;; Two pops case is tricky, since pop causes dependency on destination register.
21867;; We use two registers if available.
21868(define_peephole2
21869 [(match_scratch:DI 0 "r")
21870 (match_scratch:DI 1 "r")
8bc527af
SB
21871 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21872 (clobber (reg:CC FLAGS_REG))
f2042df3 21873 (clobber (mem:BLK (scratch)))])]
b2077fd2 21874 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
8bc527af
SB
21875 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21876 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 21877 (clobber (mem:BLK (scratch)))])
8bc527af
SB
21878 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21879 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
21880 "")
21881
21882(define_peephole2
21883 [(match_scratch:DI 0 "r")
8bc527af
SB
21884 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21885 (clobber (reg:CC FLAGS_REG))
f2042df3 21886 (clobber (mem:BLK (scratch)))])]
b2077fd2 21887 "optimize_insn_for_size_p ()"
8bc527af
SB
21888 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21889 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 21890 (clobber (mem:BLK (scratch)))])
8bc527af
SB
21891 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21892 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
21893 "")
21894
21895;; Convert esp additions to pop.
21896(define_peephole2
21897 [(match_scratch:DI 0 "r")
8bc527af
SB
21898 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21899 (clobber (reg:CC FLAGS_REG))])]
cc2e591b 21900 ""
8bc527af
SB
21901 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21902 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
21903 "")
21904
21905;; Two pops case is tricky, since pop causes dependency on destination register.
21906;; We use two registers if available.
21907(define_peephole2
21908 [(match_scratch:DI 0 "r")
21909 (match_scratch:DI 1 "r")
8bc527af
SB
21910 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21911 (clobber (reg:CC FLAGS_REG))])]
cc2e591b 21912 ""
8bc527af
SB
21913 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21914 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21915 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21916 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
21917 "")
21918
21919(define_peephole2
21920 [(match_scratch:DI 0 "r")
8bc527af
SB
21921 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21922 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 21923 "optimize_insn_for_size_p ()"
8bc527af
SB
21924 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21925 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21926 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21927 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
21928 "")
21929\f
cf14e33d
RS
21930;; Convert imul by three, five and nine into lea
21931(define_peephole2
21932 [(parallel
21933 [(set (match_operand:SI 0 "register_operand" "")
21934 (mult:SI (match_operand:SI 1 "register_operand" "")
21935 (match_operand:SI 2 "const_int_operand" "")))
21936 (clobber (reg:CC FLAGS_REG))])]
21937 "INTVAL (operands[2]) == 3
21938 || INTVAL (operands[2]) == 5
21939 || INTVAL (operands[2]) == 9"
21940 [(set (match_dup 0)
21941 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21942 (match_dup 1)))]
21943 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21944
21945(define_peephole2
21946 [(parallel
21947 [(set (match_operand:SI 0 "register_operand" "")
21948 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21949 (match_operand:SI 2 "const_int_operand" "")))
21950 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 21951 "optimize_insn_for_speed_p ()
cf14e33d
RS
21952 && (INTVAL (operands[2]) == 3
21953 || INTVAL (operands[2]) == 5
21954 || INTVAL (operands[2]) == 9)"
21955 [(set (match_dup 0) (match_dup 1))
21956 (set (match_dup 0)
21957 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21958 (match_dup 0)))]
21959 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21960
21961(define_peephole2
21962 [(parallel
21963 [(set (match_operand:DI 0 "register_operand" "")
21964 (mult:DI (match_operand:DI 1 "register_operand" "")
21965 (match_operand:DI 2 "const_int_operand" "")))
21966 (clobber (reg:CC FLAGS_REG))])]
21967 "TARGET_64BIT
21968 && (INTVAL (operands[2]) == 3
21969 || INTVAL (operands[2]) == 5
21970 || INTVAL (operands[2]) == 9)"
21971 [(set (match_dup 0)
21972 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21973 (match_dup 1)))]
21974 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21975
21976(define_peephole2
21977 [(parallel
21978 [(set (match_operand:DI 0 "register_operand" "")
21979 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21980 (match_operand:DI 2 "const_int_operand" "")))
21981 (clobber (reg:CC FLAGS_REG))])]
21982 "TARGET_64BIT
b2077fd2 21983 && optimize_insn_for_speed_p ()
cf14e33d
RS
21984 && (INTVAL (operands[2]) == 3
21985 || INTVAL (operands[2]) == 5
21986 || INTVAL (operands[2]) == 9)"
21987 [(set (match_dup 0) (match_dup 1))
21988 (set (match_dup 0)
21989 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21990 (match_dup 0)))]
21991 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21992
f56e86bd
JH
21993;; Imul $32bit_imm, mem, reg is vector decoded, while
21994;; imul $32bit_imm, reg, reg is direct decoded.
21995(define_peephole2
21996 [(match_scratch:DI 3 "r")
21997 (parallel [(set (match_operand:DI 0 "register_operand" "")
21998 (mult:DI (match_operand:DI 1 "memory_operand" "")
21999 (match_operand:DI 2 "immediate_operand" "")))
8bc527af 22000 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 22001 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
f38840db 22002 && !satisfies_constraint_K (operands[2])"
f56e86bd
JH
22003 [(set (match_dup 3) (match_dup 1))
22004 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
8bc527af 22005 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
22006"")
22007
22008(define_peephole2
22009 [(match_scratch:SI 3 "r")
22010 (parallel [(set (match_operand:SI 0 "register_operand" "")
22011 (mult:SI (match_operand:SI 1 "memory_operand" "")
22012 (match_operand:SI 2 "immediate_operand" "")))
8bc527af 22013 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 22014 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
f38840db 22015 && !satisfies_constraint_K (operands[2])"
f56e86bd
JH
22016 [(set (match_dup 3) (match_dup 1))
22017 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
8bc527af 22018 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
22019"")
22020
22021(define_peephole2
22022 [(match_scratch:SI 3 "r")
22023 (parallel [(set (match_operand:DI 0 "register_operand" "")
22024 (zero_extend:DI
22025 (mult:SI (match_operand:SI 1 "memory_operand" "")
22026 (match_operand:SI 2 "immediate_operand" ""))))
8bc527af 22027 (clobber (reg:CC FLAGS_REG))])]
b2077fd2 22028 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
f38840db 22029 && !satisfies_constraint_K (operands[2])"
f56e86bd
JH
22030 [(set (match_dup 3) (match_dup 1))
22031 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
8bc527af 22032 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
22033"")
22034
22035;; imul $8/16bit_imm, regmem, reg is vector decoded.
22036;; Convert it into imul reg, reg
22037;; It would be better to force assembler to encode instruction using long
22038;; immediate, but there is apparently no way to do so.
22039(define_peephole2
22040 [(parallel [(set (match_operand:DI 0 "register_operand" "")
22041 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
22042 (match_operand:DI 2 "const_int_operand" "")))
8bc527af 22043 (clobber (reg:CC FLAGS_REG))])
f56e86bd 22044 (match_scratch:DI 3 "r")]
b2077fd2 22045 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
f38840db 22046 && satisfies_constraint_K (operands[2])"
f56e86bd
JH
22047 [(set (match_dup 3) (match_dup 2))
22048 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
8bc527af 22049 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
22050{
22051 if (!rtx_equal_p (operands[0], operands[1]))
22052 emit_move_insn (operands[0], operands[1]);
22053})
22054
22055(define_peephole2
22056 [(parallel [(set (match_operand:SI 0 "register_operand" "")
22057 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
22058 (match_operand:SI 2 "const_int_operand" "")))
8bc527af 22059 (clobber (reg:CC FLAGS_REG))])
f56e86bd 22060 (match_scratch:SI 3 "r")]
b2077fd2 22061 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
f38840db 22062 && satisfies_constraint_K (operands[2])"
f56e86bd
JH
22063 [(set (match_dup 3) (match_dup 2))
22064 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
8bc527af 22065 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
22066{
22067 if (!rtx_equal_p (operands[0], operands[1]))
22068 emit_move_insn (operands[0], operands[1]);
22069})
22070
22071(define_peephole2
22072 [(parallel [(set (match_operand:HI 0 "register_operand" "")
22073 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
22074 (match_operand:HI 2 "immediate_operand" "")))
8bc527af 22075 (clobber (reg:CC FLAGS_REG))])
f56e86bd 22076 (match_scratch:HI 3 "r")]
b2077fd2 22077 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
f56e86bd
JH
22078 [(set (match_dup 3) (match_dup 2))
22079 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
8bc527af 22080 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
22081{
22082 if (!rtx_equal_p (operands[0], operands[1]))
22083 emit_move_insn (operands[0], operands[1]);
22084})
fb530c72
JH
22085
22086;; After splitting up read-modify operations, array accesses with memory
22087;; operands might end up in form:
22088;; sall $2, %eax
22089;; movl 4(%esp), %edx
22090;; addl %edx, %eax
22091;; instead of pre-splitting:
22092;; sall $2, %eax
22093;; addl 4(%esp), %eax
22094;; Turn it into:
22095;; movl 4(%esp), %edx
22096;; leal (%edx,%eax,4), %eax
22097
22098(define_peephole2
22099 [(parallel [(set (match_operand 0 "register_operand" "")
22100 (ashift (match_operand 1 "register_operand" "")
22101 (match_operand 2 "const_int_operand" "")))
22102 (clobber (reg:CC FLAGS_REG))])
22103 (set (match_operand 3 "register_operand")
22104 (match_operand 4 "x86_64_general_operand" ""))
22105 (parallel [(set (match_operand 5 "register_operand" "")
22106 (plus (match_operand 6 "register_operand" "")
22107 (match_operand 7 "register_operand" "")))
22108 (clobber (reg:CC FLAGS_REG))])]
22109 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
22110 /* Validate MODE for lea. */
22111 && ((!TARGET_PARTIAL_REG_STALL
22112 && (GET_MODE (operands[0]) == QImode
22113 || GET_MODE (operands[0]) == HImode))
6300f037 22114 || GET_MODE (operands[0]) == SImode
fb530c72
JH
22115 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
22116 /* We reorder load and the shift. */
22117 && !rtx_equal_p (operands[1], operands[3])
22118 && !reg_overlap_mentioned_p (operands[0], operands[4])
22119 /* Last PLUS must consist of operand 0 and 3. */
22120 && !rtx_equal_p (operands[0], operands[3])
22121 && (rtx_equal_p (operands[3], operands[6])
22122 || rtx_equal_p (operands[3], operands[7]))
22123 && (rtx_equal_p (operands[0], operands[6])
22124 || rtx_equal_p (operands[0], operands[7]))
22125 /* The intermediate operand 0 must die or be same as output. */
22126 && (rtx_equal_p (operands[0], operands[5])
22127 || peep2_reg_dead_p (3, operands[0]))"
22128 [(set (match_dup 3) (match_dup 4))
22129 (set (match_dup 0) (match_dup 1))]
22130{
22131 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
22132 int scale = 1 << INTVAL (operands[2]);
22133 rtx index = gen_lowpart (Pmode, operands[1]);
22134 rtx base = gen_lowpart (Pmode, operands[3]);
22135 rtx dest = gen_lowpart (mode, operands[5]);
22136
22137 operands[1] = gen_rtx_PLUS (Pmode, base,
22138 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
22139 if (mode != Pmode)
22140 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
22141 operands[0] = dest;
22142})
f56e86bd 22143\f
69404d6f
RH
22144;; Call-value patterns last so that the wildcard operand does not
22145;; disrupt insn-recog's switch tables.
22146
94bb5d0c
RH
22147(define_insn "*call_value_pop_0"
22148 [(set (match_operand 0 "" "")
e1ff012c 22149 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c 22150 (match_operand:SI 2 "" "")))
8bc527af 22151 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 22152 (match_operand:SI 3 "immediate_operand" "")))]
1e07edd3 22153 "!TARGET_64BIT"
94bb5d0c
RH
22154{
22155 if (SIBLING_CALL_P (insn))
0f40f9f7 22156 return "jmp\t%P1";
94bb5d0c 22157 else
0f40f9f7
ZW
22158 return "call\t%P1";
22159}
94bb5d0c
RH
22160 [(set_attr "type" "callv")])
22161
69404d6f
RH
22162(define_insn "*call_value_pop_1"
22163 [(set (match_operand 0 "" "")
e1ff012c 22164 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
94bb5d0c 22165 (match_operand:SI 2 "" "")))
8bc527af 22166 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 22167 (match_operand:SI 3 "immediate_operand" "i")))]
1e07edd3 22168 "!TARGET_64BIT"
69404d6f 22169{
e427abbf 22170 if (constant_call_address_operand (operands[1], Pmode))
94bb5d0c
RH
22171 {
22172 if (SIBLING_CALL_P (insn))
0f40f9f7 22173 return "jmp\t%P1";
94bb5d0c 22174 else
0f40f9f7 22175 return "call\t%P1";
94bb5d0c 22176 }
94bb5d0c 22177 if (SIBLING_CALL_P (insn))
0f40f9f7 22178 return "jmp\t%A1";
94bb5d0c 22179 else
0f40f9f7
ZW
22180 return "call\t%A1";
22181}
94bb5d0c
RH
22182 [(set_attr "type" "callv")])
22183
22184(define_insn "*call_value_0"
22185 [(set (match_operand 0 "" "")
e1ff012c 22186 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c 22187 (match_operand:SI 2 "" "")))]
32ee7d1d 22188 "!TARGET_64BIT"
32ee7d1d
JH
22189{
22190 if (SIBLING_CALL_P (insn))
0f40f9f7 22191 return "jmp\t%P1";
32ee7d1d 22192 else
0f40f9f7
ZW
22193 return "call\t%P1";
22194}
32ee7d1d
JH
22195 [(set_attr "type" "callv")])
22196
22197(define_insn "*call_value_0_rex64"
22198 [(set (match_operand 0 "" "")
22199 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22200 (match_operand:DI 2 "const_int_operand" "")))]
22201 "TARGET_64BIT"
94bb5d0c
RH
22202{
22203 if (SIBLING_CALL_P (insn))
0f40f9f7 22204 return "jmp\t%P1";
94bb5d0c 22205 else
0f40f9f7
ZW
22206 return "call\t%P1";
22207}
69404d6f
RH
22208 [(set_attr "type" "callv")])
22209
924eabec
JH
22210(define_insn "*call_value_0_rex64_ms_sysv"
22211 [(set (match_operand 0 "" "")
22212 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22213 (match_operand:DI 2 "const_int_operand" "")))
22214 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
78168632
UB
22215 (clobber (reg:TI XMM6_REG))
22216 (clobber (reg:TI XMM7_REG))
22217 (clobber (reg:TI XMM8_REG))
22218 (clobber (reg:TI XMM9_REG))
22219 (clobber (reg:TI XMM10_REG))
22220 (clobber (reg:TI XMM11_REG))
22221 (clobber (reg:TI XMM12_REG))
22222 (clobber (reg:TI XMM13_REG))
22223 (clobber (reg:TI XMM14_REG))
22224 (clobber (reg:TI XMM15_REG))
924eabec
JH
22225 (clobber (reg:DI SI_REG))
22226 (clobber (reg:DI DI_REG))]
22227 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22228{
22229 if (SIBLING_CALL_P (insn))
22230 return "jmp\t%P1";
22231 else
22232 return "call\t%P1";
22233}
22234 [(set_attr "type" "callv")])
22235
69404d6f
RH
22236(define_insn "*call_value_1"
22237 [(set (match_operand 0 "" "")
e1ff012c 22238 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
94bb5d0c 22239 (match_operand:SI 2 "" "")))]
4977bab6 22240 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
32ee7d1d 22241{
e427abbf 22242 if (constant_call_address_operand (operands[1], Pmode))
4977bab6 22243 return "call\t%P1";
6a46f71d 22244 return "call\t%A1";
4977bab6
ZW
22245}
22246 [(set_attr "type" "callv")])
22247
22248(define_insn "*sibcall_value_1"
22249 [(set (match_operand 0 "" "")
22250 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
22251 (match_operand:SI 2 "" "")))]
22252 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
22253{
e427abbf 22254 if (constant_call_address_operand (operands[1], Pmode))
4977bab6 22255 return "jmp\t%P1";
6a46f71d 22256 return "jmp\t%A1";
0f40f9f7 22257}
32ee7d1d
JH
22258 [(set_attr "type" "callv")])
22259
22260(define_insn "*call_value_1_rex64"
22261 [(set (match_operand 0 "" "")
22262 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22263 (match_operand:DI 2 "" "")))]
dc4d7240
JH
22264 "!SIBLING_CALL_P (insn) && TARGET_64BIT
22265 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
924eabec
JH
22266{
22267 if (constant_call_address_operand (operands[1], Pmode))
22268 return "call\t%P1";
22269 return "call\t%A1";
22270}
22271 [(set_attr "type" "callv")])
22272
22273(define_insn "*call_value_1_rex64_ms_sysv"
22274 [(set (match_operand 0 "" "")
22275 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22276 (match_operand:DI 2 "" "")))
22277 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
64e4c301
JH
22278 (clobber (reg:TI 27))
22279 (clobber (reg:TI 28))
22280 (clobber (reg:TI 45))
22281 (clobber (reg:TI 46))
22282 (clobber (reg:TI 47))
22283 (clobber (reg:TI 48))
22284 (clobber (reg:TI 49))
22285 (clobber (reg:TI 50))
22286 (clobber (reg:TI 51))
22287 (clobber (reg:TI 52))
924eabec
JH
22288 (clobber (reg:DI SI_REG))
22289 (clobber (reg:DI DI_REG))]
22290 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
69404d6f 22291{
e427abbf 22292 if (constant_call_address_operand (operands[1], Pmode))
4977bab6
ZW
22293 return "call\t%P1";
22294 return "call\t%A1";
0f40f9f7 22295}
69404d6f 22296 [(set_attr "type" "callv")])
4977bab6 22297
dc4d7240
JH
22298(define_insn "*call_value_1_rex64_large"
22299 [(set (match_operand 0 "" "")
22300 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
22301 (match_operand:DI 2 "" "")))]
22302 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22303 "call\t%A1"
22304 [(set_attr "type" "callv")])
22305
4977bab6
ZW
22306(define_insn "*sibcall_value_1_rex64"
22307 [(set (match_operand 0 "" "")
22308 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22309 (match_operand:DI 2 "" "")))]
22310 "SIBLING_CALL_P (insn) && TARGET_64BIT"
22311 "jmp\t%P1"
22312 [(set_attr "type" "callv")])
22313
22314(define_insn "*sibcall_value_1_rex64_v"
22315 [(set (match_operand 0 "" "")
03c259ad 22316 (call (mem:QI (reg:DI R11_REG))
4977bab6
ZW
22317 (match_operand:DI 1 "" "")))]
22318 "SIBLING_CALL_P (insn) && TARGET_64BIT"
9ad5e54f 22319 "jmp\t{*%%}r11"
4977bab6 22320 [(set_attr "type" "callv")])
9e3e266c 22321\f
7d69de61 22322;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
6300f037 22323;; That, however, is usually mapped by the OS to SIGSEGV, which is often
7d69de61
RH
22324;; caught for use by garbage collectors and the like. Using an insn that
22325;; maps to SIGILL makes it more likely the program will rightfully die.
22326;; Keeping with tradition, "6" is in honor of #UD.
9e3e266c 22327(define_insn "trap"
7d69de61 22328 [(trap_if (const_int 1) (const_int 6))]
9e3e266c 22329 ""
45050557 22330 { return ASM_SHORT "0x0b0f"; }
7d69de61 22331 [(set_attr "length" "2")])
915119a5 22332
ef719a44
RH
22333(define_expand "sse_prologue_save"
22334 [(parallel [(set (match_operand:BLK 0 "" "")
b0d95de8
UB
22335 (unspec:BLK [(reg:DI 21)
22336 (reg:DI 22)
ef719a44
RH
22337 (reg:DI 23)
22338 (reg:DI 24)
22339 (reg:DI 25)
22340 (reg:DI 26)
22341 (reg:DI 27)
b0d95de8 22342 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
ef719a44
RH
22343 (use (match_operand:DI 1 "register_operand" ""))
22344 (use (match_operand:DI 2 "immediate_operand" ""))
22345 (use (label_ref:DI (match_operand 3 "" "")))])]
22346 "TARGET_64BIT"
22347 "")
0703dceb 22348
ef719a44
RH
22349(define_insn "*sse_prologue_save_insn"
22350 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22351 (match_operand:DI 4 "const_int_operand" "n")))
b0d95de8
UB
22352 (unspec:BLK [(reg:DI 21)
22353 (reg:DI 22)
ef719a44
RH
22354 (reg:DI 23)
22355 (reg:DI 24)
22356 (reg:DI 25)
22357 (reg:DI 26)
22358 (reg:DI 27)
b0d95de8 22359 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
ef719a44
RH
22360 (use (match_operand:DI 1 "register_operand" "r"))
22361 (use (match_operand:DI 2 "const_int_operand" "i"))
22362 (use (label_ref:DI (match_operand 3 "" "X")))]
22363 "TARGET_64BIT
7c800926 22364 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
ef719a44 22365 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
0703dceb 22366{
ef719a44
RH
22367 int i;
22368 operands[0] = gen_rtx_MEM (Pmode,
22369 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
95879c72
L
22370 /* VEX instruction with a REX prefix will #UD. */
22371 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
22372 gcc_unreachable ();
22373
64ef8953 22374 output_asm_insn ("jmp\t%A1", operands);
7c800926 22375 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
ef719a44
RH
22376 {
22377 operands[4] = adjust_address (operands[0], DImode, i*16);
22378 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22379 PUT_MODE (operands[4], TImode);
22380 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
64ef8953 22381 output_asm_insn ("rex", operands);
95879c72 22382 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
ef719a44 22383 }
64ef8953
UB
22384 (*targetm.asm_out.internal_label) (asm_out_file, "L",
22385 CODE_LABEL_NUMBER (operands[3]));
22386 return "";
0703dceb 22387}
ef719a44
RH
22388 [(set_attr "type" "other")
22389 (set_attr "length_immediate" "0")
22390 (set_attr "length_address" "0")
95879c72
L
22391 (set (attr "length")
22392 (if_then_else
22393 (eq (symbol_ref "TARGET_AVX") (const_int 0))
22394 (const_string "34")
22395 (const_string "42")))
ef719a44
RH
22396 (set_attr "memory" "store")
22397 (set_attr "modrm" "0")
95879c72 22398 (set_attr "prefix" "maybe_vex")
3d34cd91 22399 (set_attr "mode" "DI")])
915119a5 22400
ef719a44
RH
22401(define_expand "prefetch"
22402 [(prefetch (match_operand 0 "address_operand" "")
22403 (match_operand:SI 1 "const_int_operand" "")
22404 (match_operand:SI 2 "const_int_operand" ""))]
22405 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
1c47af84 22406{
ef719a44
RH
22407 int rw = INTVAL (operands[1]);
22408 int locality = INTVAL (operands[2]);
1c47af84 22409
7637e42c
NS
22410 gcc_assert (rw == 0 || rw == 1);
22411 gcc_assert (locality >= 0 && locality <= 3);
22412 gcc_assert (GET_MODE (operands[0]) == Pmode
22413 || GET_MODE (operands[0]) == VOIDmode);
1c47af84 22414
ef719a44 22415 /* Use 3dNOW prefetch in case we are asking for write prefetch not
aabcd309 22416 supported by SSE counterpart or the SSE prefetch is not available
ef719a44
RH
22417 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22418 of locality. */
22419 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22420 operands[2] = GEN_INT (3);
22421 else
22422 operands[1] = const0_rtx;
1c47af84
RH
22423})
22424
ef719a44
RH
22425(define_insn "*prefetch_sse"
22426 [(prefetch (match_operand:SI 0 "address_operand" "p")
22427 (const_int 0)
22428 (match_operand:SI 1 "const_int_operand" ""))]
22429 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
4977bab6 22430{
ef719a44
RH
22431 static const char * const patterns[4] = {
22432 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22433 };
fbe5eb6d 22434
ef719a44 22435 int locality = INTVAL (operands[1]);
7637e42c 22436 gcc_assert (locality >= 0 && locality <= 3);
fbe5eb6d 22437
6300f037 22438 return patterns[locality];
ef719a44 22439}
fbe5eb6d 22440 [(set_attr "type" "sse")
b6837b94 22441 (set_attr "atom_sse_attr" "prefetch")
725fd454 22442 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
ef719a44 22443 (set_attr "memory" "none")])
fbe5eb6d 22444
ef719a44
RH
22445(define_insn "*prefetch_sse_rex"
22446 [(prefetch (match_operand:DI 0 "address_operand" "p")
22447 (const_int 0)
22448 (match_operand:SI 1 "const_int_operand" ""))]
22449 "TARGET_PREFETCH_SSE && TARGET_64BIT"
fbe5eb6d 22450{
ef719a44
RH
22451 static const char * const patterns[4] = {
22452 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22453 };
22c7c85e 22454
ef719a44 22455 int locality = INTVAL (operands[1]);
7637e42c 22456 gcc_assert (locality >= 0 && locality <= 3);
22c7c85e 22457
6300f037 22458 return patterns[locality];
ef719a44 22459}
22c7c85e 22460 [(set_attr "type" "sse")
b6837b94 22461 (set_attr "atom_sse_attr" "prefetch")
725fd454 22462 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
ef719a44 22463 (set_attr "memory" "none")])
22c7c85e 22464
ef719a44
RH
22465(define_insn "*prefetch_3dnow"
22466 [(prefetch (match_operand:SI 0 "address_operand" "p")
22467 (match_operand:SI 1 "const_int_operand" "n")
22468 (const_int 3))]
22469 "TARGET_3DNOW && !TARGET_64BIT"
22470{
22471 if (INTVAL (operands[1]) == 0)
22472 return "prefetch\t%a0";
22473 else
22474 return "prefetchw\t%a0";
22475}
22476 [(set_attr "type" "mmx")
725fd454 22477 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
ef719a44 22478 (set_attr "memory" "none")])
22c7c85e 22479
ef719a44
RH
22480(define_insn "*prefetch_3dnow_rex"
22481 [(prefetch (match_operand:DI 0 "address_operand" "p")
22482 (match_operand:SI 1 "const_int_operand" "n")
22483 (const_int 3))]
22484 "TARGET_3DNOW && TARGET_64BIT"
22485{
22486 if (INTVAL (operands[1]) == 0)
22487 return "prefetch\t%a0";
22488 else
22489 return "prefetchw\t%a0";
22490}
22491 [(set_attr "type" "mmx")
725fd454 22492 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
ef719a44 22493 (set_attr "memory" "none")])
22c7c85e 22494
7d69de61
RH
22495(define_expand "stack_protect_set"
22496 [(match_operand 0 "memory_operand" "")
22497 (match_operand 1 "memory_operand" "")]
22498 ""
22499{
77008252
JJ
22500#ifdef TARGET_THREAD_SSP_OFFSET
22501 if (TARGET_64BIT)
22502 emit_insn (gen_stack_tls_protect_set_di (operands[0],
22503 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22504 else
22505 emit_insn (gen_stack_tls_protect_set_si (operands[0],
22506 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22507#else
7d69de61
RH
22508 if (TARGET_64BIT)
22509 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
22510 else
22511 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
77008252 22512#endif
7d69de61
RH
22513 DONE;
22514})
22515
22516(define_insn "stack_protect_set_si"
22517 [(set (match_operand:SI 0 "memory_operand" "=m")
22518 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7ce918c5 22519 (set (match_scratch:SI 2 "=&r") (const_int 0))
7d69de61
RH
22520 (clobber (reg:CC FLAGS_REG))]
22521 ""
22522 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22523 [(set_attr "type" "multi")])
22524
22525(define_insn "stack_protect_set_di"
22526 [(set (match_operand:DI 0 "memory_operand" "=m")
22527 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7ce918c5 22528 (set (match_scratch:DI 2 "=&r") (const_int 0))
7d69de61
RH
22529 (clobber (reg:CC FLAGS_REG))]
22530 "TARGET_64BIT"
7ce918c5 22531 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
7d69de61
RH
22532 [(set_attr "type" "multi")])
22533
77008252
JJ
22534(define_insn "stack_tls_protect_set_si"
22535 [(set (match_operand:SI 0 "memory_operand" "=m")
22536 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22537 (set (match_scratch:SI 2 "=&r") (const_int 0))
22538 (clobber (reg:CC FLAGS_REG))]
22539 ""
9ad5e54f 22540 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
77008252
JJ
22541 [(set_attr "type" "multi")])
22542
22543(define_insn "stack_tls_protect_set_di"
22544 [(set (match_operand:DI 0 "memory_operand" "=m")
22545 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22546 (set (match_scratch:DI 2 "=&r") (const_int 0))
22547 (clobber (reg:CC FLAGS_REG))]
22548 "TARGET_64BIT"
fa6adcab
AV
22549 {
22550 /* The kernel uses a different segment register for performance reasons; a
22551 system call would not have to trash the userspace segment register,
22552 which would be expensive */
22553 if (ix86_cmodel != CM_KERNEL)
9ad5e54f 22554 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
fa6adcab 22555 else
9ad5e54f 22556 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
fa6adcab 22557 }
77008252
JJ
22558 [(set_attr "type" "multi")])
22559
7d69de61
RH
22560(define_expand "stack_protect_test"
22561 [(match_operand 0 "memory_operand" "")
3aebbe5f
JJ
22562 (match_operand 1 "memory_operand" "")
22563 (match_operand 2 "" "")]
7d69de61
RH
22564 ""
22565{
22566 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
7d69de61 22567
77008252
JJ
22568#ifdef TARGET_THREAD_SSP_OFFSET
22569 if (TARGET_64BIT)
22570 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
22571 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22572 else
22573 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
22574 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22575#else
7d69de61
RH
22576 if (TARGET_64BIT)
22577 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22578 else
22579 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
77008252 22580#endif
67b8f1c1 22581
f90b7a5a
PB
22582 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
22583 flags, const0_rtx, operands[2]));
7d69de61
RH
22584 DONE;
22585})
22586
22587(define_insn "stack_protect_test_si"
22588 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22589 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22590 (match_operand:SI 2 "memory_operand" "m")]
22591 UNSPEC_SP_TEST))
4f856a3e 22592 (clobber (match_scratch:SI 3 "=&r"))]
7d69de61
RH
22593 ""
22594 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22595 [(set_attr "type" "multi")])
22596
22597(define_insn "stack_protect_test_di"
22598 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22599 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22600 (match_operand:DI 2 "memory_operand" "m")]
22601 UNSPEC_SP_TEST))
4f856a3e 22602 (clobber (match_scratch:DI 3 "=&r"))]
7d69de61
RH
22603 "TARGET_64BIT"
22604 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22605 [(set_attr "type" "multi")])
22606
77008252
JJ
22607(define_insn "stack_tls_protect_test_si"
22608 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22609 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22610 (match_operand:SI 2 "const_int_operand" "i")]
22611 UNSPEC_SP_TLS_TEST))
22612 (clobber (match_scratch:SI 3 "=r"))]
22613 ""
9ad5e54f 22614 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
77008252
JJ
22615 [(set_attr "type" "multi")])
22616
22617(define_insn "stack_tls_protect_test_di"
22618 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22619 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22620 (match_operand:DI 2 "const_int_operand" "i")]
22621 UNSPEC_SP_TLS_TEST))
22622 (clobber (match_scratch:DI 3 "=r"))]
22623 "TARGET_64BIT"
fa6adcab
AV
22624 {
22625 /* The kernel uses a different segment register for performance reasons; a
22626 system call would not have to trash the userspace segment register,
22627 which would be expensive */
22628 if (ix86_cmodel != CM_KERNEL)
9ad5e54f 22629 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
fa6adcab 22630 else
9ad5e54f 22631 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
fa6adcab 22632 }
77008252
JJ
22633 [(set_attr "type" "multi")])
22634
3abcb3a7 22635(define_mode_iterator CRC32MODE [QI HI SI])
3b8dd071
L
22636(define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22637(define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22638
22639(define_insn "sse4_2_crc32<mode>"
22640 [(set (match_operand:SI 0 "register_operand" "=r")
22641 (unspec:SI
22642 [(match_operand:SI 1 "register_operand" "0")
22643 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22644 UNSPEC_CRC32))]
22645 "TARGET_SSE4_2"
22646 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22647 [(set_attr "type" "sselog1")
22648 (set_attr "prefix_rep" "1")
22649 (set_attr "prefix_extra" "1")
725fd454
JJ
22650 (set (attr "prefix_data16")
22651 (if_then_else (match_operand:HI 2 "" "")
22652 (const_string "1")
22653 (const_string "*")))
22654 (set (attr "prefix_rex")
22655 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
22656 (const_string "1")
22657 (const_string "*")))
3b8dd071
L
22658 (set_attr "mode" "SI")])
22659
22660(define_insn "sse4_2_crc32di"
22661 [(set (match_operand:DI 0 "register_operand" "=r")
22662 (unspec:DI
22663 [(match_operand:DI 1 "register_operand" "0")
22664 (match_operand:DI 2 "nonimmediate_operand" "rm")]
22665 UNSPEC_CRC32))]
22666 "TARGET_SSE4_2 && TARGET_64BIT"
22667 "crc32q\t{%2, %0|%0, %2}"
22668 [(set_attr "type" "sselog1")
22669 (set_attr "prefix_rep" "1")
22670 (set_attr "prefix_extra" "1")
22671 (set_attr "mode" "DI")])
22672
80e8bb90 22673(include "mmx.md")
b1875f52 22674(include "sse.md")
1ef45b77 22675(include "sync.md")
This page took 8.865149 seconds and 5 git commands to generate.