]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.md
* config/i386/i386.md: Fix missing modes on cmove splitters.
[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,
b87cfcfb 3;; 2001, 2002, 2003, 2004
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
JVA
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
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
188fc5b5 21;; along with GCC; see the file COPYING. If not, write to
3f63df56 22;; the Free Software Foundation, 59 Temple Place - Suite 330,
892a2d68 23;; Boston, MA 02111-1307, USA. */
e075ae69 24;;
4af3895e
JVA
25;; The original PO technology requires these to be ordered by speed,
26;; so that assigner will pick the fastest.
e075ae69 27;;
4af3895e 28;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
e075ae69 29;;
4af3895e
JVA
30;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31;; constraint letters.
e075ae69
RH
32;;
33;; The special asm out single letter directives following a '%' are:
4af3895e
JVA
34;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35;; operands[1].
36;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38;; 'B' Print the opcode suffix for an 8-bit integer opcode.
4af3895e 39;; 'Q' Print the opcode suffix for a 64-bit float opcode.
56710e42 40;; 'S' Print the opcode suffix for a 32-bit float opcode.
b08de47e
MM
41;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42;; 'J' Print the appropriate jump operand.
e075ae69 43;;
4af3895e
JVA
44;; 'b' Print the QImode name of the register for the indicated operand.
45;; %b0 would print %al if operands[0] is reg 0.
46;; 'w' Likewise, print the HImode name of the register.
47;; 'k' Likewise, print the SImode name of the register.
48;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49;; 'y' Print "st(0)" instead of "st" as a register.
8ee41eaf 50
4af3895e 51;; UNSPEC usage:
8ee41eaf
RH
52
53(define_constants
f996902d
RH
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
dea73790
JJ
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
f996902d
RH
64
65 ; Prologue support
f996902d
RH
66 (UNSPEC_STACK_ALLOC 11)
67 (UNSPEC_SET_GOT 12)
8ee41eaf 68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
f996902d
RH
69
70 ; TLS support
71 (UNSPEC_TP 15)
72 (UNSPEC_TLS_GD 16)
73 (UNSPEC_TLS_LD_BASE 17)
74
75 ; Other random patterns
76 (UNSPEC_SCAS 20)
77 (UNSPEC_SIN 21)
78 (UNSPEC_COS 22)
f996902d
RH
79 (UNSPEC_FNSTSW 24)
80 (UNSPEC_SAHF 25)
81 (UNSPEC_FSTCW 26)
82 (UNSPEC_ADD_CARRY 27)
83 (UNSPEC_FLDCW 28)
8ee41eaf
RH
84
85 ; For SSE/MMX support:
86 (UNSPEC_FIX 30)
87 (UNSPEC_MASKMOV 32)
88 (UNSPEC_MOVMSK 33)
89 (UNSPEC_MOVNT 34)
90 (UNSPEC_MOVA 38)
91 (UNSPEC_MOVU 39)
92 (UNSPEC_SHUFFLE 41)
93 (UNSPEC_RCP 42)
94 (UNSPEC_RSQRT 43)
95 (UNSPEC_SFENCE 44)
96 (UNSPEC_NOP 45) ; prevents combiner cleverness
97 (UNSPEC_PAVGUSB 49)
98 (UNSPEC_PFRCP 50)
99 (UNSPEC_PFRCPIT1 51)
100 (UNSPEC_PFRCPIT2 52)
101 (UNSPEC_PFRSQRT 53)
102 (UNSPEC_PFRSQIT1 54)
103 (UNSPEC_PSHUFLW 55)
104 (UNSPEC_PSHUFHW 56)
105 (UNSPEC_MFENCE 59)
106 (UNSPEC_LFENCE 60)
107 (UNSPEC_PSADBW 61)
22c7c85e
L
108 (UNSPEC_ADDSUB 71)
109 (UNSPEC_HADD 72)
110 (UNSPEC_HSUB 73)
111 (UNSPEC_MOVSHDUP 74)
112 (UNSPEC_MOVSLDUP 75)
113 (UNSPEC_LDQQU 76)
114 (UNSPEC_MOVDDUP 77)
1fb54135
RS
115
116 ; x87 Floating point
117 (UNSPEC_FPATAN 65)
358997e2 118 (UNSPEC_FYL2X 66)
c2fcfa4f 119 (UNSPEC_FYL2XP1 67)
9d5b9dae
RS
120 (UNSPEC_FRNDINT 68)
121 (UNSPEC_F2XM1 69)
253c7a00 122
a072d43b 123 ; x87 Double output FP
6c7cf1f0
UB
124 (UNSPEC_SINCOS_COS 80)
125 (UNSPEC_SINCOS_SIN 81)
a072d43b
UB
126 (UNSPEC_TAN_ONE 82)
127 (UNSPEC_TAN_TAN 83)
88b28a31
UB
128 (UNSPEC_XTRACT_FRACT 84)
129 (UNSPEC_XTRACT_EXP 85)
f964bd29
UB
130 (UNSPEC_FSCALE_FRACT 86)
131 (UNSPEC_FSCALE_EXP 87)
5ae27cfa
UB
132 (UNSPEC_FPREM_F 88)
133 (UNSPEC_FPREM_U 89)
134 (UNSPEC_FPREM1_F 90)
135 (UNSPEC_FPREM1_U 91)
6c7cf1f0 136
edeacc14
UB
137 ; x87 Rounding
138 (UNSPEC_FRNDINT_FLOOR 96)
139 (UNSPEC_FRNDINT_CEIL 97)
140 (UNSPEC_FRNDINT_TRUNC 98)
141 (UNSPEC_FRNDINT_MASK_PM 99)
142
253c7a00 143 ; REP instruction
9d5b9dae 144 (UNSPEC_REP 75)
2e2052b1
JH
145
146 (UNSPEC_EH_RETURN 76)
8ee41eaf
RH
147 ])
148
149(define_constants
150 [(UNSPECV_BLOCKAGE 0)
8e2cd6dd 151 (UNSPECV_STACK_PROBE 10)
8ee41eaf
RH
152 (UNSPECV_EMMS 31)
153 (UNSPECV_LDMXCSR 37)
154 (UNSPECV_STMXCSR 40)
155 (UNSPECV_FEMMS 46)
156 (UNSPECV_CLFLUSH 57)
d2c49530 157 (UNSPECV_ALIGN 68)
22c7c85e
L
158 (UNSPECV_MONITOR 69)
159 (UNSPECV_MWAIT 70)
8ee41eaf 160 ])
915119a5 161
8bc527af
SB
162;; Registers by name.
163(define_constants
164 [(BP_REG 6)
165 (SP_REG 7)
166 (FLAGS_REG 17)
167 (FPSR_REG 18)
168 (DIRFLAG_REG 19)
169 ])
170
6343a50e
ZW
171;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172;; from i386.c.
173
1b0c37d7
ZW
174;; In C guard expressions, put expressions which may be compile-time
175;; constants first. This allows for better optimization. For
176;; example, write "TARGET_64BIT && reload_completed", not
177;; "reload_completed && TARGET_64BIT".
178
2ae0f82c 179\f
e075ae69
RH
180;; Processor type. This attribute must exactly match the processor_type
181;; enumeration in i386.h.
89c43c0a 182(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
9e555526 183 (const (symbol_ref "ix86_tune")))
2ae0f82c 184
e075ae69
RH
185;; A basic instruction type. Refinements due to arguments to be
186;; provided in other attributes.
a269a03c 187(define_attr "type"
9a5834ae
ZW
188 "other,multi,
189 alu,alu1,negnot,imov,imovx,lea,
1b245ade 190 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
9a5834ae 191 icmp,test,ibr,setcc,icmov,
4977bab6 192 push,pop,call,callv,leave,
9a5834ae 193 str,cld,
edeacc14 194 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
9a5834ae 195 sselog,sseiadd,sseishft,sseimul,
f56e86bd 196 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
9a5834ae 197 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
e075ae69
RH
198 (const_string "other"))
199
6ef67412 200;; Main data type used by the insn
9a5834ae 201(define_attr "mode"
4977bab6 202 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
6ef67412
JH
203 (const_string "unknown"))
204
3d34cd91
JH
205;; The CPU unit operations uses.
206(define_attr "unit" "integer,i387,sse,mmx,unknown"
edeacc14 207 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
3d34cd91 208 (const_string "i387")
9a5834ae 209 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
cb297538 210 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
3d34cd91 211 (const_string "sse")
9a5834ae 212 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
4c9c9a3d
JH
213 (const_string "mmx")
214 (eq_attr "type" "other")
215 (const_string "unknown")]
3d34cd91 216 (const_string "integer")))
6ef67412
JH
217
218;; The (bounding maximum) length of an instruction immediate.
219(define_attr "length_immediate" ""
4977bab6 220 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
6ef67412 221 (const_int 0)
3d34cd91 222 (eq_attr "unit" "i387,sse,mmx")
6ef67412 223 (const_int 0)
1b245ade
JH
224 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225 imul,icmp,push,pop")
6ef67412
JH
226 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227 (eq_attr "type" "imov,test")
228 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229 (eq_attr "type" "call")
230 (if_then_else (match_operand 0 "constant_call_address_operand" "")
231 (const_int 4)
232 (const_int 0))
233 (eq_attr "type" "callv")
234 (if_then_else (match_operand 1 "constant_call_address_operand" "")
235 (const_int 4)
236 (const_int 0))
efcc7037
JH
237 ;; We don't know the size before shorten_branches. Expect
238 ;; the instruction to fit for better scheduling.
6ef67412 239 (eq_attr "type" "ibr")
efcc7037 240 (const_int 1)
6ef67412 241 ]
9a5834ae
ZW
242 (symbol_ref "/* Update immediate_length and other attributes! */
243 abort(),1")))
e075ae69 244
6ef67412
JH
245;; The (bounding maximum) length of an instruction address.
246(define_attr "length_address" ""
247 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248 (const_int 0)
249 (and (eq_attr "type" "call")
c7375e61 250 (match_operand 0 "constant_call_address_operand" ""))
6ef67412
JH
251 (const_int 0)
252 (and (eq_attr "type" "callv")
253 (match_operand 1 "constant_call_address_operand" ""))
254 (const_int 0)
255 ]
256 (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258;; Set when length prefix is used.
259(define_attr "prefix_data16" ""
3d34cd91
JH
260 (if_then_else (ior (eq_attr "mode" "HI")
261 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
6ef67412
JH
262 (const_int 1)
263 (const_int 0)))
264
265;; Set when string REP prefix is used.
3d34cd91
JH
266(define_attr "prefix_rep" ""
267 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268 (const_int 1)
269 (const_int 0)))
6ef67412
JH
270
271;; Set when 0f opcode prefix is used.
272(define_attr "prefix_0f" ""
9a5834ae 273 (if_then_else
cb297538
JH
274 (ior (eq_attr "type" "imovx,setcc,icmov")
275 (eq_attr "unit" "sse,mmx"))
6ef67412
JH
276 (const_int 1)
277 (const_int 0)))
278
56bab446 279;; Set when REX opcode prefix is used.
4977bab6
ZW
280(define_attr "prefix_rex" ""
281 (cond [(and (eq_attr "mode" "DI")
282 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283 (const_int 1)
284 (and (eq_attr "mode" "QI")
285 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286 (const_int 0)))
287 (const_int 1)
288 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289 (const_int 0))
290 (const_int 1)
291 ]
292 (const_int 0)))
293
6ef67412
JH
294;; Set when modrm byte is used.
295(define_attr "modrm" ""
4977bab6 296 (cond [(eq_attr "type" "str,cld,leave")
6ef67412 297 (const_int 0)
3d34cd91 298 (eq_attr "unit" "i387")
6ef67412 299 (const_int 0)
e075ae69
RH
300 (and (eq_attr "type" "incdec")
301 (ior (match_operand:SI 1 "register_operand" "")
302 (match_operand:HI 1 "register_operand" "")))
6ef67412 303 (const_int 0)
e075ae69
RH
304 (and (eq_attr "type" "push")
305 (not (match_operand 1 "memory_operand" "")))
6ef67412 306 (const_int 0)
e075ae69
RH
307 (and (eq_attr "type" "pop")
308 (not (match_operand 0 "memory_operand" "")))
6ef67412 309 (const_int 0)
e075ae69
RH
310 (and (eq_attr "type" "imov")
311 (and (match_operand 0 "register_operand" "")
312 (match_operand 1 "immediate_operand" "")))
6ef67412 313 (const_int 0)
c7375e61
EB
314 (and (eq_attr "type" "call")
315 (match_operand 0 "constant_call_address_operand" ""))
316 (const_int 0)
317 (and (eq_attr "type" "callv")
318 (match_operand 1 "constant_call_address_operand" ""))
319 (const_int 0)
e075ae69 320 ]
6ef67412
JH
321 (const_int 1)))
322
323;; The (bounding maximum) length of an instruction in bytes.
edeacc14
UB
324;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325;; Later we may want to split them and compute proper length as for
326;; other insns.
6ef67412 327(define_attr "length" ""
edeacc14 328 (cond [(eq_attr "type" "other,multi,fistp,frndint")
6ef67412 329 (const_int 16)
a3033f34
EB
330 (eq_attr "type" "fcmp")
331 (const_int 4)
3d34cd91
JH
332 (eq_attr "unit" "i387")
333 (plus (const_int 2)
334 (plus (attr "prefix_data16")
335 (attr "length_address")))]
6ef67412
JH
336 (plus (plus (attr "modrm")
337 (plus (attr "prefix_0f")
4977bab6
ZW
338 (plus (attr "prefix_rex")
339 (const_int 1))))
6ef67412
JH
340 (plus (attr "prefix_rep")
341 (plus (attr "prefix_data16")
342 (plus (attr "length_immediate")
343 (attr "length_address")))))))
e075ae69
RH
344
345;; The `memory' attribute is `none' if no memory is referenced, `load' or
346;; `store' if there is a simple memory reference therein, or `unknown'
347;; if the instruction is complex.
348
349(define_attr "memory" "none,load,store,both,unknown"
7c7ef435 350 (cond [(eq_attr "type" "other,multi,str")
e075ae69 351 (const_string "unknown")
7c7ef435 352 (eq_attr "type" "lea,fcmov,fpspc,cld")
e075ae69 353 (const_string "none")
4977bab6 354 (eq_attr "type" "fistp,leave")
22fb740d 355 (const_string "both")
edeacc14
UB
356 (eq_attr "type" "frndint")
357 (const_string "load")
e075ae69
RH
358 (eq_attr "type" "push")
359 (if_then_else (match_operand 1 "memory_operand" "")
360 (const_string "both")
361 (const_string "store"))
abd2dd6d 362 (eq_attr "type" "pop")
e075ae69
RH
363 (if_then_else (match_operand 0 "memory_operand" "")
364 (const_string "both")
365 (const_string "load"))
abd2dd6d
JH
366 (eq_attr "type" "setcc")
367 (if_then_else (match_operand 0 "memory_operand" "")
368 (const_string "store")
369 (const_string "none"))
f56e86bd 370 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
e075ae69
RH
371 (if_then_else (ior (match_operand 0 "memory_operand" "")
372 (match_operand 1 "memory_operand" ""))
373 (const_string "load")
374 (const_string "none"))
375 (eq_attr "type" "ibr")
376 (if_then_else (match_operand 0 "memory_operand" "")
377 (const_string "load")
378 (const_string "none"))
379 (eq_attr "type" "call")
380 (if_then_else (match_operand 0 "constant_call_address_operand" "")
381 (const_string "none")
382 (const_string "load"))
383 (eq_attr "type" "callv")
384 (if_then_else (match_operand 1 "constant_call_address_operand" "")
385 (const_string "none")
386 (const_string "load"))
f527d196 387 (and (eq_attr "type" "alu1,negnot,ishift1")
a269a03c 388 (match_operand 1 "memory_operand" ""))
e075ae69
RH
389 (const_string "both")
390 (and (match_operand 0 "memory_operand" "")
391 (match_operand 1 "memory_operand" ""))
392 (const_string "both")
393 (match_operand 0 "memory_operand" "")
394 (const_string "store")
395 (match_operand 1 "memory_operand" "")
396 (const_string "load")
9a5834ae 397 (and (eq_attr "type"
f527d196 398 "!alu1,negnot,ishift1,
9a5834ae
ZW
399 imov,imovx,icmp,test,
400 fmov,fcmp,fsgn,
cb297538 401 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
9a5834ae 402 mmx,mmxmov,mmxcmp,mmxcvt")
e075ae69
RH
403 (match_operand 2 "memory_operand" ""))
404 (const_string "load")
405 (and (eq_attr "type" "icmov")
406 (match_operand 3 "memory_operand" ""))
407 (const_string "load")
408 ]
a269a03c
JC
409 (const_string "none")))
410
e075ae69
RH
411;; Indicates if an instruction has both an immediate and a displacement.
412
413(define_attr "imm_disp" "false,true,unknown"
414 (cond [(eq_attr "type" "other,multi")
415 (const_string "unknown")
1b245ade 416 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
e075ae69
RH
417 (and (match_operand 0 "memory_displacement_operand" "")
418 (match_operand 1 "immediate_operand" "")))
419 (const_string "true")
890d52e8 420 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
e075ae69
RH
421 (and (match_operand 0 "memory_displacement_operand" "")
422 (match_operand 2 "immediate_operand" "")))
423 (const_string "true")
424 ]
425 (const_string "false")))
426
427;; Indicates if an FP operation has an integer source.
428
429(define_attr "fp_int_src" "false,true"
430 (const_string "false"))
431
edeacc14
UB
432;; Defines rounding mode of an FP operation.
433
1d1df0df 434(define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
edeacc14
UB
435 (const_string "any"))
436
e075ae69
RH
437;; Describe a user's asm statement.
438(define_asm_attributes
439 [(set_attr "length" "128")
440 (set_attr "type" "multi")])
441\f
8fe75e43
RH
442;; Scheduling descriptions
443
af2728a4
JL
444(include "pentium.md")
445(include "ppro.md")
446(include "k6.md")
447(include "athlon.md")
8fe75e43
RH
448
449\f
450;; Operand and operator predicates
451
452(include "predicates.md")
453
309ada50 454\f
e075ae69 455;; Compare instructions.
886c62d1 456
e075ae69 457;; All compare insns have expanders that save the operands away without
c572e5ba 458;; actually generating RTL. The bCOND or sCOND (emitted immediately
e075ae69 459;; after the cmp) will actually emit the cmpM.
886c62d1 460
e075ae69 461(define_expand "cmpdi"
8bc527af 462 [(set (reg:CC FLAGS_REG)
b9b2c339 463 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
9b70259d 464 (match_operand:DI 1 "x86_64_general_operand" "")))]
c572e5ba 465 ""
c572e5ba 466{
b9b2c339 467 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
468 operands[0] = force_reg (DImode, operands[0]);
469 ix86_compare_op0 = operands[0];
470 ix86_compare_op1 = operands[1];
c572e5ba 471 DONE;
0f40f9f7 472})
c572e5ba 473
e075ae69 474(define_expand "cmpsi"
8bc527af 475 [(set (reg:CC FLAGS_REG)
e075ae69
RH
476 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477 (match_operand:SI 1 "general_operand" "")))]
c572e5ba 478 ""
c572e5ba 479{
b9b2c339 480 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
481 operands[0] = force_reg (SImode, operands[0]);
482 ix86_compare_op0 = operands[0];
483 ix86_compare_op1 = operands[1];
c572e5ba 484 DONE;
0f40f9f7 485})
c572e5ba 486
e075ae69 487(define_expand "cmphi"
8bc527af 488 [(set (reg:CC FLAGS_REG)
b9b2c339 489 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
e075ae69 490 (match_operand:HI 1 "general_operand" "")))]
c572e5ba 491 ""
c572e5ba 492{
b9b2c339 493 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
494 operands[0] = force_reg (HImode, operands[0]);
495 ix86_compare_op0 = operands[0];
496 ix86_compare_op1 = operands[1];
c572e5ba 497 DONE;
0f40f9f7 498})
c572e5ba 499
e075ae69 500(define_expand "cmpqi"
8bc527af 501 [(set (reg:CC FLAGS_REG)
b9b2c339 502 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
e075ae69 503 (match_operand:QI 1 "general_operand" "")))]
d9f32422 504 "TARGET_QIMODE_MATH"
c572e5ba 505{
b9b2c339 506 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
507 operands[0] = force_reg (QImode, operands[0]);
508 ix86_compare_op0 = operands[0];
509 ix86_compare_op1 = operands[1];
c572e5ba 510 DONE;
0f40f9f7 511})
886c62d1 512
9b70259d 513(define_insn "cmpdi_ccno_1_rex64"
42fabf21 514 [(set (reg FLAGS_REG)
9b70259d
JH
515 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516 (match_operand:DI 1 "const0_operand" "n,n")))]
517 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518 "@
0f40f9f7
ZW
519 test{q}\t{%0, %0|%0, %0}
520 cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
521 [(set_attr "type" "test,icmp")
522 (set_attr "length_immediate" "0,1")
523 (set_attr "mode" "DI")])
524
525(define_insn "*cmpdi_minus_1_rex64"
42fabf21 526 [(set (reg FLAGS_REG)
9b70259d
JH
527 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529 (const_int 0)))]
1b0c37d7 530 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 531 "cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
532 [(set_attr "type" "icmp")
533 (set_attr "mode" "DI")])
534
535(define_expand "cmpdi_1_rex64"
8bc527af 536 [(set (reg:CC FLAGS_REG)
9b70259d
JH
537 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538 (match_operand:DI 1 "general_operand" "")))]
1b0c37d7 539 "TARGET_64BIT"
9b70259d
JH
540 "")
541
542(define_insn "cmpdi_1_insn_rex64"
42fabf21 543 [(set (reg FLAGS_REG)
9b70259d
JH
544 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 547 "cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
548 [(set_attr "type" "icmp")
549 (set_attr "mode" "DI")])
550
551
9076b9c1 552(define_insn "*cmpsi_ccno_1"
42fabf21 553 [(set (reg FLAGS_REG)
9076b9c1
JH
554 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555 (match_operand:SI 1 "const0_operand" "n,n")))]
556 "ix86_match_ccmode (insn, CCNOmode)"
16189740 557 "@
0f40f9f7
ZW
558 test{l}\t{%0, %0|%0, %0}
559 cmp{l}\t{%1, %0|%0, %1}"
6ef67412
JH
560 [(set_attr "type" "test,icmp")
561 (set_attr "length_immediate" "0,1")
562 (set_attr "mode" "SI")])
16189740 563
9076b9c1 564(define_insn "*cmpsi_minus_1"
42fabf21 565 [(set (reg FLAGS_REG)
9076b9c1
JH
566 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567 (match_operand:SI 1 "general_operand" "ri,mr"))
568 (const_int 0)))]
569 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 570 "cmp{l}\t{%1, %0|%0, %1}"
9076b9c1 571 [(set_attr "type" "icmp")
6ef67412 572 (set_attr "mode" "SI")])
886c62d1 573
9076b9c1 574(define_expand "cmpsi_1"
8bc527af 575 [(set (reg:CC FLAGS_REG)
e075ae69
RH
576 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577 (match_operand:SI 1 "general_operand" "ri,mr")))]
9076b9c1
JH
578 ""
579 "")
580
581(define_insn "*cmpsi_1_insn"
42fabf21 582 [(set (reg FLAGS_REG)
9076b9c1
JH
583 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584 (match_operand:SI 1 "general_operand" "ri,mr")))]
585 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 587 "cmp{l}\t{%1, %0|%0, %1}"
6ef67412
JH
588 [(set_attr "type" "icmp")
589 (set_attr "mode" "SI")])
886c62d1 590
9076b9c1 591(define_insn "*cmphi_ccno_1"
42fabf21 592 [(set (reg FLAGS_REG)
16189740
RH
593 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594 (match_operand:HI 1 "const0_operand" "n,n")))]
595 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 596 "@
0f40f9f7
ZW
597 test{w}\t{%0, %0|%0, %0}
598 cmp{w}\t{%1, %0|%0, %1}"
6ef67412
JH
599 [(set_attr "type" "test,icmp")
600 (set_attr "length_immediate" "0,1")
601 (set_attr "mode" "HI")])
886c62d1 602
9076b9c1 603(define_insn "*cmphi_minus_1"
42fabf21 604 [(set (reg FLAGS_REG)
9076b9c1
JH
605 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606 (match_operand:HI 1 "general_operand" "ri,mr"))
607 (const_int 0)))]
608 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 609 "cmp{w}\t{%1, %0|%0, %1}"
6ef67412
JH
610 [(set_attr "type" "icmp")
611 (set_attr "mode" "HI")])
e075ae69 612
9076b9c1 613(define_insn "*cmphi_1"
42fabf21 614 [(set (reg FLAGS_REG)
9076b9c1
JH
615 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616 (match_operand:HI 1 "general_operand" "ri,mr")))]
617 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 619 "cmp{w}\t{%1, %0|%0, %1}"
9076b9c1
JH
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "HI")])
16189740
RH
622
623(define_insn "*cmpqi_ccno_1"
42fabf21 624 [(set (reg FLAGS_REG)
9076b9c1
JH
625 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626 (match_operand:QI 1 "const0_operand" "n,n")))]
627 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 628 "@
0f40f9f7
ZW
629 test{b}\t{%0, %0|%0, %0}
630 cmp{b}\t{$0, %0|%0, 0}"
6ef67412
JH
631 [(set_attr "type" "test,icmp")
632 (set_attr "length_immediate" "0,1")
633 (set_attr "mode" "QI")])
886c62d1 634
16189740 635(define_insn "*cmpqi_1"
42fabf21 636 [(set (reg FLAGS_REG)
9076b9c1
JH
637 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638 (match_operand:QI 1 "general_operand" "qi,mq")))]
639 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 641 "cmp{b}\t{%1, %0|%0, %1}"
6ef67412
JH
642 [(set_attr "type" "icmp")
643 (set_attr "mode" "QI")])
e075ae69 644
9076b9c1 645(define_insn "*cmpqi_minus_1"
42fabf21 646 [(set (reg FLAGS_REG)
d70401eb
JJ
647 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648 (match_operand:QI 1 "general_operand" "qi,mq"))
9076b9c1
JH
649 (const_int 0)))]
650 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 651 "cmp{b}\t{%1, %0|%0, %1}"
9076b9c1
JH
652 [(set_attr "type" "icmp")
653 (set_attr "mode" "QI")])
654
e075ae69 655(define_insn "*cmpqi_ext_1"
42fabf21 656 [(set (reg FLAGS_REG)
9076b9c1 657 (compare
d2836273 658 (match_operand:QI 0 "general_operand" "Qm")
e075ae69
RH
659 (subreg:QI
660 (zero_extract:SI
d2836273 661 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
662 (const_int 8)
663 (const_int 8)) 0)))]
d2836273 664 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 665 "cmp{b}\t{%h1, %0|%0, %h1}"
d2836273
JH
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "QI")])
668
669(define_insn "*cmpqi_ext_1_rex64"
42fabf21 670 [(set (reg FLAGS_REG)
d2836273 671 (compare
3522082b 672 (match_operand:QI 0 "register_operand" "Q")
d2836273
JH
673 (subreg:QI
674 (zero_extract:SI
675 (match_operand 1 "ext_register_operand" "Q")
676 (const_int 8)
677 (const_int 8)) 0)))]
678 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 679 "cmp{b}\t{%h1, %0|%0, %h1}"
6ef67412
JH
680 [(set_attr "type" "icmp")
681 (set_attr "mode" "QI")])
e075ae69
RH
682
683(define_insn "*cmpqi_ext_2"
42fabf21 684 [(set (reg FLAGS_REG)
16189740 685 (compare
e075ae69
RH
686 (subreg:QI
687 (zero_extract:SI
d2836273 688 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
689 (const_int 8)
690 (const_int 8)) 0)
691 (match_operand:QI 1 "const0_operand" "n")))]
16189740 692 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 693 "test{b}\t%h0, %h0"
6ef67412
JH
694 [(set_attr "type" "test")
695 (set_attr "length_immediate" "0")
696 (set_attr "mode" "QI")])
e075ae69 697
9076b9c1 698(define_expand "cmpqi_ext_3"
8bc527af 699 [(set (reg:CC FLAGS_REG)
e075ae69
RH
700 (compare:CC
701 (subreg:QI
702 (zero_extract:SI
d2836273 703 (match_operand 0 "ext_register_operand" "")
e075ae69
RH
704 (const_int 8)
705 (const_int 8)) 0)
d2836273 706 (match_operand:QI 1 "general_operand" "")))]
e075ae69 707 ""
9076b9c1
JH
708 "")
709
710(define_insn "cmpqi_ext_3_insn"
42fabf21 711 [(set (reg FLAGS_REG)
9076b9c1
JH
712 (compare
713 (subreg:QI
714 (zero_extract:SI
d2836273 715 (match_operand 0 "ext_register_operand" "Q")
9076b9c1
JH
716 (const_int 8)
717 (const_int 8)) 0)
d2836273
JH
718 (match_operand:QI 1 "general_operand" "Qmn")))]
719 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 720 "cmp{b}\t{%1, %h0|%h0, %1}"
d2836273
JH
721 [(set_attr "type" "icmp")
722 (set_attr "mode" "QI")])
723
724(define_insn "cmpqi_ext_3_insn_rex64"
42fabf21 725 [(set (reg FLAGS_REG)
d2836273
JH
726 (compare
727 (subreg:QI
728 (zero_extract:SI
729 (match_operand 0 "ext_register_operand" "Q")
730 (const_int 8)
731 (const_int 8)) 0)
732 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 734 "cmp{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
735 [(set_attr "type" "icmp")
736 (set_attr "mode" "QI")])
e075ae69
RH
737
738(define_insn "*cmpqi_ext_4"
42fabf21 739 [(set (reg FLAGS_REG)
9076b9c1 740 (compare
e075ae69
RH
741 (subreg:QI
742 (zero_extract:SI
d2836273 743 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
744 (const_int 8)
745 (const_int 8)) 0)
746 (subreg:QI
747 (zero_extract:SI
d2836273 748 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
749 (const_int 8)
750 (const_int 8)) 0)))]
9076b9c1 751 "ix86_match_ccmode (insn, CCmode)"
0f40f9f7 752 "cmp{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
753 [(set_attr "type" "icmp")
754 (set_attr "mode" "QI")])
e075ae69
RH
755
756;; These implement float point compares.
757;; %%% See if we can get away with VOIDmode operands on the actual insns,
758;; which would allow mix and match FP modes on the compares. Which is what
759;; the old patterns did, but with many more of them.
c572e5ba 760
e075ae69 761(define_expand "cmpxf"
8bc527af 762 [(set (reg:CC FLAGS_REG)
e075ae69
RH
763 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
2b589241 765 "TARGET_80387"
2b589241
JH
766{
767 ix86_compare_op0 = operands[0];
768 ix86_compare_op1 = operands[1];
769 DONE;
0f40f9f7 770})
2b589241 771
e075ae69 772(define_expand "cmpdf"
8bc527af 773 [(set (reg:CC FLAGS_REG)
e075ae69
RH
774 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
0644b628 776 "TARGET_80387 || TARGET_SSE2"
4fb21e90 777{
e075ae69
RH
778 ix86_compare_op0 = operands[0];
779 ix86_compare_op1 = operands[1];
4fb21e90 780 DONE;
0f40f9f7 781})
886c62d1 782
e075ae69 783(define_expand "cmpsf"
8bc527af 784 [(set (reg:CC FLAGS_REG)
e075ae69
RH
785 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
0644b628 787 "TARGET_80387 || TARGET_SSE"
c572e5ba 788{
e075ae69
RH
789 ix86_compare_op0 = operands[0];
790 ix86_compare_op1 = operands[1];
c572e5ba 791 DONE;
0f40f9f7 792})
c572e5ba 793
e075ae69
RH
794;; FP compares, step 1:
795;; Set the FP condition codes.
796;;
797;; CCFPmode compare with exceptions
798;; CCFPUmode compare with no exceptions
fe4435d9 799
7c82106f
UB
800;; We may not use "#" to split and emit these, since the REG_DEAD notes
801;; used to manage the reg stack popping would not be preserved.
802
45c8c47f
UB
803(define_insn "*cmpfp_0_sf"
804 [(set (match_operand:HI 0 "register_operand" "=a")
805 (unspec:HI
806 [(compare:CCFP
807 (match_operand:SF 1 "register_operand" "f")
808 (match_operand:SF 2 "const0_operand" "X"))]
809 UNSPEC_FNSTSW))]
810 "TARGET_80387"
7c82106f 811 "* return output_fp_compare (insn, operands, 0, 0);"
45c8c47f
UB
812 [(set_attr "type" "multi")
813 (set_attr "mode" "SF")])
886c62d1 814
45c8c47f 815(define_insn "*cmpfp_0_df"
e075ae69
RH
816 [(set (match_operand:HI 0 "register_operand" "=a")
817 (unspec:HI
45c8c47f
UB
818 [(compare:CCFP
819 (match_operand:DF 1 "register_operand" "f")
820 (match_operand:DF 2 "const0_operand" "X"))]
821 UNSPEC_FNSTSW))]
822 "TARGET_80387"
7c82106f 823 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412 824 [(set_attr "type" "multi")
45c8c47f
UB
825 (set_attr "mode" "DF")])
826
827(define_insn "*cmpfp_0_xf"
828 [(set (match_operand:HI 0 "register_operand" "=a")
829 (unspec:HI
830 [(compare:CCFP
831 (match_operand:XF 1 "register_operand" "f")
832 (match_operand:XF 2 "const0_operand" "X"))]
833 UNSPEC_FNSTSW))]
834 "TARGET_80387"
7c82106f 835 "* return output_fp_compare (insn, operands, 0, 0);"
45c8c47f
UB
836 [(set_attr "type" "multi")
837 (set_attr "mode" "XF")])
c572e5ba 838
7c82106f 839(define_insn "*cmpfp_sf"
e075ae69
RH
840 [(set (match_operand:HI 0 "register_operand" "=a")
841 (unspec:HI
842 [(compare:CCFP
843 (match_operand:SF 1 "register_operand" "f")
8ee41eaf
RH
844 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845 UNSPEC_FNSTSW))]
4fb21e90 846 "TARGET_80387"
e075ae69 847 "* return output_fp_compare (insn, operands, 0, 0);"
fdf97ad1 848 [(set_attr "type" "multi")
7c82106f 849 (set_attr "mode" "SF")])
926b3fae 850
7c82106f 851(define_insn "*cmpfp_df"
e075ae69
RH
852 [(set (match_operand:HI 0 "register_operand" "=a")
853 (unspec:HI
854 [(compare:CCFP
855 (match_operand:DF 1 "register_operand" "f")
8ee41eaf
RH
856 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857 UNSPEC_FNSTSW))]
4fb21e90 858 "TARGET_80387"
7c82106f 859 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412
JH
860 [(set_attr "type" "multi")
861 (set_attr "mode" "DF")])
e075ae69 862
7c82106f 863(define_insn "*cmpfp_xf"
e075ae69
RH
864 [(set (match_operand:HI 0 "register_operand" "=a")
865 (unspec:HI
866 [(compare:CCFP
867 (match_operand:XF 1 "register_operand" "f")
8ee41eaf
RH
868 (match_operand:XF 2 "register_operand" "f"))]
869 UNSPEC_FNSTSW))]
2b589241 870 "TARGET_80387"
7c82106f 871 "* return output_fp_compare (insn, operands, 0, 0);"
2b589241
JH
872 [(set_attr "type" "multi")
873 (set_attr "mode" "XF")])
874
7c82106f 875(define_insn "*cmpfp_u"
e075ae69
RH
876 [(set (match_operand:HI 0 "register_operand" "=a")
877 (unspec:HI
878 [(compare:CCFPU
879 (match_operand 1 "register_operand" "f")
8ee41eaf
RH
880 (match_operand 2 "register_operand" "f"))]
881 UNSPEC_FNSTSW))]
08a7baac 882 "TARGET_80387
e075ae69
RH
883 && FLOAT_MODE_P (GET_MODE (operands[1]))
884 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7c82106f 885 "* return output_fp_compare (insn, operands, 0, 1);"
6ef67412 886 [(set_attr "type" "multi")
4977bab6
ZW
887 (set (attr "mode")
888 (cond [(match_operand:SF 1 "" "")
889 (const_string "SF")
890 (match_operand:DF 1 "" "")
891 (const_string "DF")
892 ]
893 (const_string "XF")))])
08a7baac 894
7c82106f
UB
895(define_insn "*cmpfp_si"
896 [(set (match_operand:HI 0 "register_operand" "=a")
897 (unspec:HI
898 [(compare:CCFP
899 (match_operand 1 "register_operand" "f")
900 (match_operator 3 "float_operator"
901 [(match_operand:SI 2 "memory_operand" "m")]))]
902 UNSPEC_FNSTSW))]
903 "TARGET_80387 && TARGET_USE_FIOP
904 && FLOAT_MODE_P (GET_MODE (operands[1]))
905 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906 "* return output_fp_compare (insn, operands, 0, 0);"
907 [(set_attr "type" "multi")
908 (set_attr "fp_int_src" "true")
909 (set_attr "mode" "SI")])
e075ae69
RH
910
911;; FP compares, step 2
912;; Move the fpsw to ax.
913
5ae27cfa 914(define_insn "x86_fnstsw_1"
e075ae69 915 [(set (match_operand:HI 0 "register_operand" "=a")
8bc527af 916 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
2ae0f82c 917 "TARGET_80387"
0f40f9f7 918 "fnstsw\t%0"
e075ae69 919 [(set_attr "length" "2")
6ef67412 920 (set_attr "mode" "SI")
56bab446 921 (set_attr "unit" "i387")])
e075ae69
RH
922
923;; FP compares, step 3
924;; Get ax into flags, general case.
925
926(define_insn "x86_sahf_1"
8bc527af 927 [(set (reg:CC FLAGS_REG)
8ee41eaf 928 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
1e07edd3 929 "!TARGET_64BIT"
e075ae69
RH
930 "sahf"
931 [(set_attr "length" "1")
0b5107cf 932 (set_attr "athlon_decode" "vector")
56bab446 933 (set_attr "mode" "SI")])
e075ae69
RH
934
935;; Pentium Pro can do steps 1 through 3 in one go.
936
937(define_insn "*cmpfp_i"
8bc527af 938 [(set (reg:CCFP FLAGS_REG)
e075ae69
RH
939 (compare:CCFP (match_operand 0 "register_operand" "f")
940 (match_operand 1 "register_operand" "f")))]
941 "TARGET_80387 && TARGET_CMOVE
0644b628 942 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
e075ae69 943 && FLOAT_MODE_P (GET_MODE (operands[0]))
869d095e 944 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
e075ae69 945 "* return output_fp_compare (insn, operands, 1, 0);"
309ada50 946 [(set_attr "type" "fcmp")
4977bab6
ZW
947 (set (attr "mode")
948 (cond [(match_operand:SF 1 "" "")
949 (const_string "SF")
950 (match_operand:DF 1 "" "")
951 (const_string "DF")
952 ]
953 (const_string "XF")))
309ada50 954 (set_attr "athlon_decode" "vector")])
e075ae69 955
0644b628 956(define_insn "*cmpfp_i_sse"
8bc527af 957 [(set (reg:CCFP FLAGS_REG)
0644b628
JH
958 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960 "TARGET_80387
961 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
869d095e 962 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
0644b628 963 "* return output_fp_compare (insn, operands, 1, 0);"
26771da7 964 [(set_attr "type" "fcmp,ssecomi")
4977bab6
ZW
965 (set (attr "mode")
966 (if_then_else (match_operand:SF 1 "" "")
967 (const_string "SF")
968 (const_string "DF")))
0644b628
JH
969 (set_attr "athlon_decode" "vector")])
970
971(define_insn "*cmpfp_i_sse_only"
8bc527af 972 [(set (reg:CCFP FLAGS_REG)
0644b628
JH
973 (compare:CCFP (match_operand 0 "register_operand" "x")
974 (match_operand 1 "nonimmediate_operand" "xm")))]
975 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
869d095e 976 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
0644b628 977 "* return output_fp_compare (insn, operands, 1, 0);"
26771da7 978 [(set_attr "type" "ssecomi")
4977bab6
ZW
979 (set (attr "mode")
980 (if_then_else (match_operand:SF 1 "" "")
981 (const_string "SF")
982 (const_string "DF")))
0644b628
JH
983 (set_attr "athlon_decode" "vector")])
984
e075ae69 985(define_insn "*cmpfp_iu"
8bc527af 986 [(set (reg:CCFPU FLAGS_REG)
e075ae69
RH
987 (compare:CCFPU (match_operand 0 "register_operand" "f")
988 (match_operand 1 "register_operand" "f")))]
989 "TARGET_80387 && TARGET_CMOVE
0644b628 990 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
e075ae69
RH
991 && FLOAT_MODE_P (GET_MODE (operands[0]))
992 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993 "* return output_fp_compare (insn, operands, 1, 1);"
309ada50 994 [(set_attr "type" "fcmp")
4977bab6
ZW
995 (set (attr "mode")
996 (cond [(match_operand:SF 1 "" "")
997 (const_string "SF")
998 (match_operand:DF 1 "" "")
999 (const_string "DF")
1000 ]
1001 (const_string "XF")))
309ada50 1002 (set_attr "athlon_decode" "vector")])
0644b628
JH
1003
1004(define_insn "*cmpfp_iu_sse"
8bc527af 1005 [(set (reg:CCFPU FLAGS_REG)
0644b628
JH
1006 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008 "TARGET_80387
1009 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011 "* return output_fp_compare (insn, operands, 1, 1);"
26771da7 1012 [(set_attr "type" "fcmp,ssecomi")
4977bab6
ZW
1013 (set (attr "mode")
1014 (if_then_else (match_operand:SF 1 "" "")
1015 (const_string "SF")
1016 (const_string "DF")))
0644b628
JH
1017 (set_attr "athlon_decode" "vector")])
1018
1019(define_insn "*cmpfp_iu_sse_only"
8bc527af 1020 [(set (reg:CCFPU FLAGS_REG)
0644b628
JH
1021 (compare:CCFPU (match_operand 0 "register_operand" "x")
1022 (match_operand 1 "nonimmediate_operand" "xm")))]
1023 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025 "* return output_fp_compare (insn, operands, 1, 1);"
26771da7 1026 [(set_attr "type" "ssecomi")
4977bab6
ZW
1027 (set (attr "mode")
1028 (if_then_else (match_operand:SF 1 "" "")
1029 (const_string "SF")
1030 (const_string "DF")))
0644b628 1031 (set_attr "athlon_decode" "vector")])
e075ae69
RH
1032\f
1033;; Move instructions.
2ae0f82c 1034
e075ae69 1035;; General case of fullword move.
886c62d1 1036
e075ae69
RH
1037(define_expand "movsi"
1038 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039 (match_operand:SI 1 "general_operand" ""))]
1040 ""
1041 "ix86_expand_move (SImode, operands); DONE;")
08a7baac 1042
e075ae69
RH
1043;; Push/pop instructions. They are separate since autoinc/dec is not a
1044;; general_operand.
1045;;
1046;; %%% We don't use a post-inc memory reference because x86 is not a
1047;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049;; targets without our curiosities, and it is just as easy to represent
1050;; this differently.
886c62d1 1051
a4414093 1052(define_insn "*pushsi2"
e075ae69 1053 [(set (match_operand:SI 0 "push_operand" "=<")
2c5a510c 1054 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
0ec259ed 1055 "!TARGET_64BIT"
0f40f9f7 1056 "push{l}\t%1"
6ef67412
JH
1057 [(set_attr "type" "push")
1058 (set_attr "mode" "SI")])
4fb21e90 1059
0ec259ed
JH
1060;; For 64BIT abi we always round up to 8 bytes.
1061(define_insn "*pushsi2_rex64"
1062 [(set (match_operand:SI 0 "push_operand" "=X")
1063 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064 "TARGET_64BIT"
0f40f9f7 1065 "push{q}\t%q1"
0ec259ed
JH
1066 [(set_attr "type" "push")
1067 (set_attr "mode" "SI")])
1068
bdeb029c
JH
1069(define_insn "*pushsi2_prologue"
1070 [(set (match_operand:SI 0 "push_operand" "=<")
1071 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
f2042df3 1072 (clobber (mem:BLK (scratch)))]
0ec259ed 1073 "!TARGET_64BIT"
0f40f9f7 1074 "push{l}\t%1"
6ef67412
JH
1075 [(set_attr "type" "push")
1076 (set_attr "mode" "SI")])
bdeb029c
JH
1077
1078(define_insn "*popsi1_epilogue"
1079 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
1080 (mem:SI (reg:SI SP_REG)))
1081 (set (reg:SI SP_REG)
1082 (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 1083 (clobber (mem:BLK (scratch)))]
1e07edd3 1084 "!TARGET_64BIT"
0f40f9f7 1085 "pop{l}\t%0"
6ef67412
JH
1086 [(set_attr "type" "pop")
1087 (set_attr "mode" "SI")])
bdeb029c 1088
e075ae69
RH
1089(define_insn "popsi1"
1090 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
1091 (mem:SI (reg:SI SP_REG)))
1092 (set (reg:SI SP_REG)
1093 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1e07edd3 1094 "!TARGET_64BIT"
0f40f9f7 1095 "pop{l}\t%0"
6ef67412
JH
1096 [(set_attr "type" "pop")
1097 (set_attr "mode" "SI")])
c572e5ba 1098
a8bac9ab 1099(define_insn "*movsi_xor"
591702de
JH
1100 [(set (match_operand:SI 0 "register_operand" "=r")
1101 (match_operand:SI 1 "const0_operand" "i"))
8bc527af 1102 (clobber (reg:CC FLAGS_REG))]
591702de 1103 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
0f40f9f7 1104 "xor{l}\t{%0, %0|%0, %0}"
591702de 1105 [(set_attr "type" "alu1")
6ef67412
JH
1106 (set_attr "mode" "SI")
1107 (set_attr "length_immediate" "0")])
67e53009 1108
591702de
JH
1109(define_insn "*movsi_or"
1110 [(set (match_operand:SI 0 "register_operand" "=r")
1111 (match_operand:SI 1 "immediate_operand" "i"))
8bc527af 1112 (clobber (reg:CC FLAGS_REG))]
87d9741e
KH
1113 "reload_completed
1114 && operands[1] == constm1_rtx
591702de 1115 && (TARGET_PENTIUM || optimize_size)"
c572e5ba 1116{
591702de 1117 operands[1] = constm1_rtx;
0f40f9f7
ZW
1118 return "or{l}\t{%1, %0|%0, %1}";
1119}
591702de 1120 [(set_attr "type" "alu1")
6ef67412
JH
1121 (set_attr "mode" "SI")
1122 (set_attr "length_immediate" "1")])
e075ae69 1123
591702de 1124(define_insn "*movsi_1"
9b73c90a
EB
1125 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1126 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
8f62128d
JH
1127 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1128 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1129{
1130 switch (get_attr_type (insn))
1131 {
1132 case TYPE_SSEMOV:
1d5b4e0b 1133 if (get_attr_mode (insn) == MODE_TI)
8f62128d
JH
1134 return "movdqa\t{%1, %0|%0, %1}";
1135 return "movd\t{%1, %0|%0, %1}";
1136
1137 case TYPE_MMXMOV:
1d5b4e0b 1138 if (get_attr_mode (insn) == MODE_DI)
8f62128d
JH
1139 return "movq\t{%1, %0|%0, %1}";
1140 return "movd\t{%1, %0|%0, %1}";
1141
1142 case TYPE_LEA:
1143 return "lea{l}\t{%1, %0|%0, %1}";
1144
1145 default:
1146 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1147 abort();
1148 return "mov{l}\t{%1, %0|%0, %1}";
1149 }
1150}
1151 [(set (attr "type")
9b73c90a 1152 (cond [(eq_attr "alternative" "2,3,4")
8f62128d 1153 (const_string "mmxmov")
9b73c90a 1154 (eq_attr "alternative" "5,6,7")
8f62128d
JH
1155 (const_string "ssemov")
1156 (and (ne (symbol_ref "flag_pic") (const_int 0))
1157 (match_operand:SI 1 "symbolic_operand" ""))
1158 (const_string "lea")
1159 ]
1160 (const_string "imov")))
9b73c90a 1161 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
8f62128d
JH
1162
1163(define_insn "*movsi_1_nointernunit"
9b73c90a
EB
1164 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1165 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
8f62128d
JH
1166 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1167 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
886c62d1 1168{
e075ae69 1169 switch (get_attr_type (insn))
886c62d1 1170 {
5f90a099 1171 case TYPE_SSEMOV:
1d5b4e0b 1172 if (get_attr_mode (insn) == MODE_TI)
0f40f9f7
ZW
1173 return "movdqa\t{%1, %0|%0, %1}";
1174 return "movd\t{%1, %0|%0, %1}";
141e454b 1175
5f90a099 1176 case TYPE_MMXMOV:
1d5b4e0b 1177 if (get_attr_mode (insn) == MODE_DI)
e5a20888 1178 return "movq\t{%1, %0|%0, %1}";
0f40f9f7 1179 return "movd\t{%1, %0|%0, %1}";
915119a5 1180
e075ae69 1181 case TYPE_LEA:
0f40f9f7 1182 return "lea{l}\t{%1, %0|%0, %1}";
915119a5 1183
e075ae69 1184 default:
57d47446 1185 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
e075ae69 1186 abort();
0f40f9f7 1187 return "mov{l}\t{%1, %0|%0, %1}";
886c62d1 1188 }
0f40f9f7 1189}
e075ae69 1190 [(set (attr "type")
9b73c90a 1191 (cond [(eq_attr "alternative" "2,3,4")
3d34cd91 1192 (const_string "mmxmov")
9b73c90a 1193 (eq_attr "alternative" "5,6,7")
3d34cd91 1194 (const_string "ssemov")
915119a5 1195 (and (ne (symbol_ref "flag_pic") (const_int 0))
e075ae69
RH
1196 (match_operand:SI 1 "symbolic_operand" ""))
1197 (const_string "lea")
1198 ]
6ef67412 1199 (const_string "imov")))
9b73c90a 1200 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
e075ae69 1201
d1f87653 1202;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
1203;; We fake an second form of instruction to force reload to load address
1204;; into register when rax is not available
1205(define_insn "*movabssi_1_rex64"
7e6dc358
JJ
1206 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1207 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1208 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 1209 "@
0f40f9f7 1210 movabs{l}\t{%1, %P0|%P0, %1}
7e6dc358 1211 mov{l}\t{%1, %a0|%a0, %1}"
0ec259ed 1212 [(set_attr "type" "imov")
7e6dc358
JJ
1213 (set_attr "modrm" "0,*")
1214 (set_attr "length_address" "8,0")
1215 (set_attr "length_immediate" "0,*")
0ec259ed
JH
1216 (set_attr "memory" "store")
1217 (set_attr "mode" "SI")])
1218
1219(define_insn "*movabssi_2_rex64"
1220 [(set (match_operand:SI 0 "register_operand" "=a,r")
1221 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 1222 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 1223 "@
0f40f9f7
ZW
1224 movabs{l}\t{%P1, %0|%0, %P1}
1225 mov{l}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
1226 [(set_attr "type" "imov")
1227 (set_attr "modrm" "0,*")
1228 (set_attr "length_address" "8,0")
1229 (set_attr "length_immediate" "0")
1230 (set_attr "memory" "load")
1231 (set_attr "mode" "SI")])
1232
e075ae69
RH
1233(define_insn "*swapsi"
1234 [(set (match_operand:SI 0 "register_operand" "+r")
1235 (match_operand:SI 1 "register_operand" "+r"))
1236 (set (match_dup 1)
1237 (match_dup 0))]
2bb7a0f5 1238 ""
0f40f9f7 1239 "xchg{l}\t%1, %0"
e075ae69
RH
1240 [(set_attr "type" "imov")
1241 (set_attr "pent_pair" "np")
0b5107cf 1242 (set_attr "athlon_decode" "vector")
6ef67412 1243 (set_attr "mode" "SI")
56bab446 1244 (set_attr "modrm" "0")])
886c62d1 1245
e075ae69
RH
1246(define_expand "movhi"
1247 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1248 (match_operand:HI 1 "general_operand" ""))]
ca097615 1249 ""
e075ae69 1250 "ix86_expand_move (HImode, operands); DONE;")
2f2a49e8 1251
a4414093 1252(define_insn "*pushhi2"
e075ae69 1253 [(set (match_operand:HI 0 "push_operand" "=<,<")
2c5a510c 1254 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1e07edd3 1255 "!TARGET_64BIT"
e075ae69 1256 "@
0f40f9f7
ZW
1257 push{w}\t{|WORD PTR }%1
1258 push{w}\t%1"
6ef67412
JH
1259 [(set_attr "type" "push")
1260 (set_attr "mode" "HI")])
e075ae69 1261
b3298882
JH
1262;; For 64BIT abi we always round up to 8 bytes.
1263(define_insn "*pushhi2_rex64"
1264 [(set (match_operand:HI 0 "push_operand" "=X")
1265 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1266 "TARGET_64BIT"
0f40f9f7 1267 "push{q}\t%q1"
b3298882
JH
1268 [(set_attr "type" "push")
1269 (set_attr "mode" "QI")])
1270
e075ae69 1271(define_insn "*movhi_1"
9b73c90a
EB
1272 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1273 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
e075ae69 1274 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
886c62d1 1275{
e075ae69 1276 switch (get_attr_type (insn))
886c62d1 1277 {
e075ae69
RH
1278 case TYPE_IMOVX:
1279 /* movzwl is faster than movw on p2 due to partial word stalls,
1280 though not as fast as an aligned movl. */
0f40f9f7 1281 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
e075ae69 1282 default:
6ef67412 1283 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 1284 return "mov{l}\t{%k1, %k0|%k0, %k1}";
e075ae69 1285 else
0f40f9f7 1286 return "mov{w}\t{%1, %0|%0, %1}";
886c62d1 1287 }
0f40f9f7 1288}
e075ae69 1289 [(set (attr "type")
68f48f39
RS
1290 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1291 (const_string "imov")
1292 (and (eq_attr "alternative" "0")
0b5107cf
JH
1293 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1294 (const_int 0))
1295 (eq (symbol_ref "TARGET_HIMODE_MATH")
1296 (const_int 0))))
369e59b1 1297 (const_string "imov")
9b73c90a 1298 (and (eq_attr "alternative" "1,2")
2247f6ed 1299 (match_operand:HI 1 "aligned_operand" ""))
e075ae69
RH
1300 (const_string "imov")
1301 (and (ne (symbol_ref "TARGET_MOVX")
1302 (const_int 0))
9b73c90a 1303 (eq_attr "alternative" "0,2"))
e075ae69
RH
1304 (const_string "imovx")
1305 ]
1306 (const_string "imov")))
6ef67412 1307 (set (attr "mode")
e075ae69 1308 (cond [(eq_attr "type" "imovx")
6ef67412 1309 (const_string "SI")
9b73c90a 1310 (and (eq_attr "alternative" "1,2")
369e59b1 1311 (match_operand:HI 1 "aligned_operand" ""))
6ef67412 1312 (const_string "SI")
9b73c90a 1313 (and (eq_attr "alternative" "0")
0b5107cf
JH
1314 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315 (const_int 0))
1316 (eq (symbol_ref "TARGET_HIMODE_MATH")
1317 (const_int 0))))
6ef67412 1318 (const_string "SI")
e075ae69 1319 ]
9b73c90a 1320 (const_string "HI")))])
e075ae69 1321
d1f87653 1322;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
1323;; We fake an second form of instruction to force reload to load address
1324;; into register when rax is not available
1325(define_insn "*movabshi_1_rex64"
7e6dc358
JJ
1326 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1327 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1328 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 1329 "@
0f40f9f7 1330 movabs{w}\t{%1, %P0|%P0, %1}
7e6dc358 1331 mov{w}\t{%1, %a0|%a0, %1}"
0ec259ed 1332 [(set_attr "type" "imov")
7e6dc358
JJ
1333 (set_attr "modrm" "0,*")
1334 (set_attr "length_address" "8,0")
1335 (set_attr "length_immediate" "0,*")
0ec259ed
JH
1336 (set_attr "memory" "store")
1337 (set_attr "mode" "HI")])
1338
1339(define_insn "*movabshi_2_rex64"
1340 [(set (match_operand:HI 0 "register_operand" "=a,r")
1341 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 1342 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 1343 "@
0f40f9f7
ZW
1344 movabs{w}\t{%P1, %0|%0, %P1}
1345 mov{w}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
1346 [(set_attr "type" "imov")
1347 (set_attr "modrm" "0,*")
1348 (set_attr "length_address" "8,0")
1349 (set_attr "length_immediate" "0")
1350 (set_attr "memory" "load")
1351 (set_attr "mode" "HI")])
1352
e075ae69
RH
1353(define_insn "*swaphi_1"
1354 [(set (match_operand:HI 0 "register_operand" "+r")
1355 (match_operand:HI 1 "register_operand" "+r"))
1356 (set (match_dup 1)
1357 (match_dup 0))]
1358 "TARGET_PARTIAL_REG_STALL"
0f40f9f7 1359 "xchg{w}\t%1, %0"
e075ae69
RH
1360 [(set_attr "type" "imov")
1361 (set_attr "pent_pair" "np")
6ef67412 1362 (set_attr "mode" "HI")
56bab446 1363 (set_attr "modrm" "0")])
e075ae69
RH
1364
1365(define_insn "*swaphi_2"
1366 [(set (match_operand:HI 0 "register_operand" "+r")
1367 (match_operand:HI 1 "register_operand" "+r"))
1368 (set (match_dup 1)
1369 (match_dup 0))]
1370 "! TARGET_PARTIAL_REG_STALL"
0f40f9f7 1371 "xchg{l}\t%k1, %k0"
e075ae69 1372 [(set_attr "type" "imov")
e075ae69 1373 (set_attr "pent_pair" "np")
6ef67412 1374 (set_attr "mode" "SI")
56bab446 1375 (set_attr "modrm" "0")])
886c62d1 1376
2f2a49e8 1377(define_expand "movstricthi"
e075ae69 1378 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2f2a49e8 1379 (match_operand:HI 1 "general_operand" ""))]
b9b2c339 1380 "! TARGET_PARTIAL_REG_STALL || optimize_size"
2f2a49e8
MM
1381{
1382 /* Don't generate memory->memory moves, go through a register */
e075ae69
RH
1383 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1384 operands[1] = force_reg (HImode, operands[1]);
0f40f9f7 1385})
2f2a49e8 1386
e075ae69 1387(define_insn "*movstricthi_1"
fc524c1c 1388 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
e075ae69 1389 (match_operand:HI 1 "general_operand" "rn,m"))]
b9b2c339 1390 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
e075ae69 1391 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 1392 "mov{w}\t{%1, %0|%0, %1}"
6ef67412
JH
1393 [(set_attr "type" "imov")
1394 (set_attr "mode" "HI")])
1395
1396(define_insn "*movstricthi_xor"
208b0ab1 1397 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
6ef67412 1398 (match_operand:HI 1 "const0_operand" "i"))
8bc527af 1399 (clobber (reg:CC FLAGS_REG))]
b9b2c339
JH
1400 "reload_completed
1401 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
0f40f9f7 1402 "xor{w}\t{%0, %0|%0, %0}"
6ef67412
JH
1403 [(set_attr "type" "alu1")
1404 (set_attr "mode" "HI")
1405 (set_attr "length_immediate" "0")])
886c62d1 1406
2f2a49e8 1407(define_expand "movqi"
4cbfbb1b 1408 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2f2a49e8
MM
1409 (match_operand:QI 1 "general_operand" ""))]
1410 ""
e075ae69
RH
1411 "ix86_expand_move (QImode, operands); DONE;")
1412
7dd4b4a3
JH
1413;; emit_push_insn when it calls move_by_pieces requires an insn to
1414;; "push a byte". But actually we use pushw, which has the effect
1415;; of rounding the amount pushed up to a halfword.
1416
1417(define_insn "*pushqi2"
1418 [(set (match_operand:QI 0 "push_operand" "=X,X")
1419 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1420 "!TARGET_64BIT"
1421 "@
0f40f9f7
ZW
1422 push{w}\t{|word ptr }%1
1423 push{w}\t%w1"
7dd4b4a3
JH
1424 [(set_attr "type" "push")
1425 (set_attr "mode" "HI")])
1426
b3298882
JH
1427;; For 64BIT abi we always round up to 8 bytes.
1428(define_insn "*pushqi2_rex64"
1429 [(set (match_operand:QI 0 "push_operand" "=X")
5f90a099 1430 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
b3298882 1431 "TARGET_64BIT"
0f40f9f7 1432 "push{q}\t%q1"
b3298882
JH
1433 [(set_attr "type" "push")
1434 (set_attr "mode" "QI")])
1435
0b5107cf
JH
1436;; Situation is quite tricky about when to choose full sized (SImode) move
1437;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1438;; partial register dependency machines (such as AMD Athlon), where QImode
1439;; moves issue extra dependency and for partial register stalls machines
1440;; that don't use QImode patterns (and QImode move cause stall on the next
1441;; instruction).
1442;;
1443;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1444;; register stall machines with, where we use QImode instructions, since
1445;; partial register stall can be caused there. Then we use movzx.
e075ae69 1446(define_insn "*movqi_1"
0b5107cf
JH
1447 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1448 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
e075ae69 1449 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
886c62d1 1450{
e075ae69 1451 switch (get_attr_type (insn))
b76c90cf 1452 {
e075ae69 1453 case TYPE_IMOVX:
1a06f5fe 1454 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
e075ae69 1455 abort ();
0f40f9f7 1456 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
e075ae69 1457 default:
6ef67412 1458 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 1459 return "mov{l}\t{%k1, %k0|%k0, %k1}";
b76c90cf 1460 else
0f40f9f7 1461 return "mov{b}\t{%1, %0|%0, %1}";
b76c90cf 1462 }
0f40f9f7 1463}
e075ae69 1464 [(set (attr "type")
68f48f39
RS
1465 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1466 (const_string "imov")
1467 (and (eq_attr "alternative" "3")
0b5107cf
JH
1468 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1469 (const_int 0))
1470 (eq (symbol_ref "TARGET_QIMODE_MATH")
1471 (const_int 0))))
1472 (const_string "imov")
1473 (eq_attr "alternative" "3,5")
e075ae69
RH
1474 (const_string "imovx")
1475 (and (ne (symbol_ref "TARGET_MOVX")
1476 (const_int 0))
0b5107cf 1477 (eq_attr "alternative" "2"))
e075ae69
RH
1478 (const_string "imovx")
1479 ]
1480 (const_string "imov")))
6ef67412
JH
1481 (set (attr "mode")
1482 (cond [(eq_attr "alternative" "3,4,5")
1483 (const_string "SI")
1484 (eq_attr "alternative" "6")
1485 (const_string "QI")
1486 (eq_attr "type" "imovx")
1487 (const_string "SI")
0b5107cf 1488 (and (eq_attr "type" "imov")
6ef67412 1489 (and (eq_attr "alternative" "0,1,2")
0b5107cf
JH
1490 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1491 (const_int 0))))
6ef67412 1492 (const_string "SI")
0b5107cf
JH
1493 ;; Avoid partial register stalls when not using QImode arithmetic
1494 (and (eq_attr "type" "imov")
6ef67412 1495 (and (eq_attr "alternative" "0,1,2")
0b5107cf
JH
1496 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1497 (const_int 0))
1498 (eq (symbol_ref "TARGET_QIMODE_MATH")
1499 (const_int 0)))))
6ef67412
JH
1500 (const_string "SI")
1501 ]
1502 (const_string "QI")))])
e075ae69
RH
1503
1504(define_expand "reload_outqi"
1505 [(parallel [(match_operand:QI 0 "" "=m")
1506 (match_operand:QI 1 "register_operand" "r")
1507 (match_operand:QI 2 "register_operand" "=&q")])]
1508 ""
e075ae69
RH
1509{
1510 rtx op0, op1, op2;
1511 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
886c62d1 1512
e075ae69
RH
1513 if (reg_overlap_mentioned_p (op2, op0))
1514 abort ();
1515 if (! q_regs_operand (op1, QImode))
1516 {
1517 emit_insn (gen_movqi (op2, op1));
1518 op1 = op2;
1519 }
1520 emit_insn (gen_movqi (op0, op1));
1521 DONE;
0f40f9f7 1522})
886c62d1 1523
e075ae69
RH
1524(define_insn "*swapqi"
1525 [(set (match_operand:QI 0 "register_operand" "+r")
1526 (match_operand:QI 1 "register_operand" "+r"))
1527 (set (match_dup 1)
1528 (match_dup 0))]
1529 ""
0f40f9f7 1530 "xchg{b}\t%1, %0"
e075ae69
RH
1531 [(set_attr "type" "imov")
1532 (set_attr "pent_pair" "np")
6ef67412 1533 (set_attr "mode" "QI")
56bab446 1534 (set_attr "modrm" "0")])
886c62d1 1535
2f2a49e8 1536(define_expand "movstrictqi"
4cbfbb1b 1537 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2f2a49e8 1538 (match_operand:QI 1 "general_operand" ""))]
3c298c88 1539 "! TARGET_PARTIAL_REG_STALL || optimize_size"
2f2a49e8 1540{
e03f5d43 1541 /* Don't generate memory->memory moves, go through a register. */
e075ae69
RH
1542 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1543 operands[1] = force_reg (QImode, operands[1]);
0f40f9f7 1544})
2f2a49e8 1545
e075ae69 1546(define_insn "*movstrictqi_1"
2ae0f82c 1547 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
c0f06344 1548 (match_operand:QI 1 "general_operand" "*qn,m"))]
3c298c88 1549 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
e075ae69 1550 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 1551 "mov{b}\t{%1, %0|%0, %1}"
6ef67412
JH
1552 [(set_attr "type" "imov")
1553 (set_attr "mode" "QI")])
1554
1555(define_insn "*movstrictqi_xor"
5e6d6bf0 1556 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
6ef67412 1557 (match_operand:QI 1 "const0_operand" "i"))
8bc527af 1558 (clobber (reg:CC FLAGS_REG))]
6ef67412 1559 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
0f40f9f7 1560 "xor{b}\t{%0, %0|%0, %0}"
6ef67412
JH
1561 [(set_attr "type" "alu1")
1562 (set_attr "mode" "QI")
1563 (set_attr "length_immediate" "0")])
e075ae69
RH
1564
1565(define_insn "*movsi_extv_1"
d2836273 1566 [(set (match_operand:SI 0 "register_operand" "=R")
3522082b 1567 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1568 (const_int 8)
1569 (const_int 8)))]
1570 ""
0f40f9f7 1571 "movs{bl|x}\t{%h1, %0|%0, %h1}"
6ef67412
JH
1572 [(set_attr "type" "imovx")
1573 (set_attr "mode" "SI")])
e075ae69
RH
1574
1575(define_insn "*movhi_extv_1"
d2836273 1576 [(set (match_operand:HI 0 "register_operand" "=R")
3522082b 1577 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1578 (const_int 8)
1579 (const_int 8)))]
1580 ""
0f40f9f7 1581 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
6ef67412
JH
1582 [(set_attr "type" "imovx")
1583 (set_attr "mode" "SI")])
e075ae69
RH
1584
1585(define_insn "*movqi_extv_1"
0ec259ed 1586 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
3522082b 1587 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
e075ae69
RH
1588 (const_int 8)
1589 (const_int 8)))]
0ec259ed 1590 "!TARGET_64BIT"
886c62d1 1591{
e075ae69 1592 switch (get_attr_type (insn))
886c62d1 1593 {
e075ae69 1594 case TYPE_IMOVX:
0f40f9f7 1595 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
e075ae69 1596 default:
0f40f9f7 1597 return "mov{b}\t{%h1, %0|%0, %h1}";
886c62d1 1598 }
0f40f9f7 1599}
e075ae69
RH
1600 [(set (attr "type")
1601 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1602 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1603 (ne (symbol_ref "TARGET_MOVX")
1604 (const_int 0))))
1605 (const_string "imovx")
6ef67412
JH
1606 (const_string "imov")))
1607 (set (attr "mode")
1608 (if_then_else (eq_attr "type" "imovx")
1609 (const_string "SI")
1610 (const_string "QI")))])
e075ae69 1611
0ec259ed
JH
1612(define_insn "*movqi_extv_1_rex64"
1613 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
3522082b 1614 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
0ec259ed
JH
1615 (const_int 8)
1616 (const_int 8)))]
1617 "TARGET_64BIT"
0ec259ed
JH
1618{
1619 switch (get_attr_type (insn))
1620 {
1621 case TYPE_IMOVX:
0f40f9f7 1622 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
0ec259ed 1623 default:
0f40f9f7 1624 return "mov{b}\t{%h1, %0|%0, %h1}";
0ec259ed 1625 }
0f40f9f7 1626}
0ec259ed
JH
1627 [(set (attr "type")
1628 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1629 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1630 (ne (symbol_ref "TARGET_MOVX")
1631 (const_int 0))))
1632 (const_string "imovx")
1633 (const_string "imov")))
1634 (set (attr "mode")
1635 (if_then_else (eq_attr "type" "imovx")
1636 (const_string "SI")
1637 (const_string "QI")))])
1638
d1f87653 1639;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
1640;; We fake an second form of instruction to force reload to load address
1641;; into register when rax is not available
1642(define_insn "*movabsqi_1_rex64"
7e6dc358
JJ
1643 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1644 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1645 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 1646 "@
5e2ce672 1647 movabs{b}\t{%1, %P0|%P0, %1}
7e6dc358 1648 mov{b}\t{%1, %a0|%a0, %1}"
0ec259ed 1649 [(set_attr "type" "imov")
7e6dc358
JJ
1650 (set_attr "modrm" "0,*")
1651 (set_attr "length_address" "8,0")
1652 (set_attr "length_immediate" "0,*")
0ec259ed
JH
1653 (set_attr "memory" "store")
1654 (set_attr "mode" "QI")])
1655
1656(define_insn "*movabsqi_2_rex64"
1657 [(set (match_operand:QI 0 "register_operand" "=a,r")
1658 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 1659 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 1660 "@
5e2ce672
JH
1661 movabs{b}\t{%P1, %0|%0, %P1}
1662 mov{b}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
1663 [(set_attr "type" "imov")
1664 (set_attr "modrm" "0,*")
1665 (set_attr "length_address" "8,0")
1666 (set_attr "length_immediate" "0")
1667 (set_attr "memory" "load")
1668 (set_attr "mode" "QI")])
1669
e075ae69 1670(define_insn "*movsi_extzv_1"
d2836273
JH
1671 [(set (match_operand:SI 0 "register_operand" "=R")
1672 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1673 (const_int 8)
1674 (const_int 8)))]
1675 ""
0f40f9f7 1676 "movz{bl|x}\t{%h1, %0|%0, %h1}"
6ef67412
JH
1677 [(set_attr "type" "imovx")
1678 (set_attr "mode" "SI")])
886c62d1 1679
d2836273
JH
1680(define_insn "*movqi_extzv_2"
1681 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1682 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
e075ae69
RH
1683 (const_int 8)
1684 (const_int 8)) 0))]
d2836273 1685 "!TARGET_64BIT"
f31fce3f 1686{
e075ae69 1687 switch (get_attr_type (insn))
f31fce3f 1688 {
e075ae69 1689 case TYPE_IMOVX:
0f40f9f7 1690 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
e075ae69 1691 default:
0f40f9f7 1692 return "mov{b}\t{%h1, %0|%0, %h1}";
e075ae69 1693 }
0f40f9f7 1694}
e075ae69
RH
1695 [(set (attr "type")
1696 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1697 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1698 (ne (symbol_ref "TARGET_MOVX")
1699 (const_int 0))))
1700 (const_string "imovx")
6ef67412
JH
1701 (const_string "imov")))
1702 (set (attr "mode")
1703 (if_then_else (eq_attr "type" "imovx")
1704 (const_string "SI")
1705 (const_string "QI")))])
e075ae69 1706
d2836273
JH
1707(define_insn "*movqi_extzv_2_rex64"
1708 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1709 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1710 (const_int 8)
1711 (const_int 8)) 0))]
1712 "TARGET_64BIT"
d2836273
JH
1713{
1714 switch (get_attr_type (insn))
1715 {
1716 case TYPE_IMOVX:
0f40f9f7 1717 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
d2836273 1718 default:
0f40f9f7 1719 return "mov{b}\t{%h1, %0|%0, %h1}";
d2836273 1720 }
0f40f9f7 1721}
d2836273
JH
1722 [(set (attr "type")
1723 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1724 (ne (symbol_ref "TARGET_MOVX")
1725 (const_int 0)))
1726 (const_string "imovx")
1727 (const_string "imov")))
1728 (set (attr "mode")
1729 (if_then_else (eq_attr "type" "imovx")
1730 (const_string "SI")
1731 (const_string "QI")))])
1732
7a2e09f4 1733(define_insn "movsi_insv_1"
d2836273 1734 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
e075ae69
RH
1735 (const_int 8)
1736 (const_int 8))
f47c8646 1737 (match_operand:SI 1 "general_operand" "Qmn"))]
d2836273 1738 "!TARGET_64BIT"
0f40f9f7 1739 "mov{b}\t{%b1, %h0|%h0, %b1}"
d2836273
JH
1740 [(set_attr "type" "imov")
1741 (set_attr "mode" "QI")])
1742
044b3892
L
1743(define_insn "movdi_insv_1_rex64"
1744 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
d2836273
JH
1745 (const_int 8)
1746 (const_int 8))
044b3892 1747 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
d2836273 1748 "TARGET_64BIT"
0f40f9f7 1749 "mov{b}\t{%b1, %h0|%h0, %b1}"
6ef67412
JH
1750 [(set_attr "type" "imov")
1751 (set_attr "mode" "QI")])
e075ae69
RH
1752
1753(define_insn "*movqi_insv_2"
d2836273 1754 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
e075ae69
RH
1755 (const_int 8)
1756 (const_int 8))
99f296a0
KH
1757 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1758 (const_int 8)))]
e075ae69 1759 ""
0f40f9f7 1760 "mov{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
1761 [(set_attr "type" "imov")
1762 (set_attr "mode" "QI")])
f31fce3f 1763
e075ae69 1764(define_expand "movdi"
4cbfbb1b 1765 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69
RH
1766 (match_operand:DI 1 "general_operand" ""))]
1767 ""
1768 "ix86_expand_move (DImode, operands); DONE;")
f31fce3f 1769
e075ae69
RH
1770(define_insn "*pushdi"
1771 [(set (match_operand:DI 0 "push_operand" "=<")
2c5a510c 1772 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1e07edd3 1773 "!TARGET_64BIT"
e075ae69 1774 "#")
f31fce3f 1775
0ec259ed
JH
1776(define_insn "pushdi2_rex64"
1777 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1778 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1779 "TARGET_64BIT"
1780 "@
0f40f9f7 1781 push{q}\t%1
0ec259ed
JH
1782 #"
1783 [(set_attr "type" "push,multi")
1784 (set_attr "mode" "DI")])
1785
1786;; Convert impossible pushes of immediate to existing instructions.
f5143c46 1787;; First try to get scratch register and go through it. In case this
0ec259ed
JH
1788;; fails, push sign extended lower part first and then overwrite
1789;; upper part by 32bit move.
1790(define_peephole2
1791 [(match_scratch:DI 2 "r")
1792 (set (match_operand:DI 0 "push_operand" "")
1793 (match_operand:DI 1 "immediate_operand" ""))]
1794 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1795 && !x86_64_immediate_operand (operands[1], DImode)"
1796 [(set (match_dup 2) (match_dup 1))
1797 (set (match_dup 0) (match_dup 2))]
1798 "")
1799
1800;; We need to define this as both peepholer and splitter for case
1801;; peephole2 pass is not run.
731edaed 1802;; "&& 1" is needed to keep it from matching the previous pattern.
0ec259ed
JH
1803(define_peephole2
1804 [(set (match_operand:DI 0 "push_operand" "")
1805 (match_operand:DI 1 "immediate_operand" ""))]
1806 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
731edaed 1807 && !x86_64_immediate_operand (operands[1], DImode) && 1"
0ec259ed
JH
1808 [(set (match_dup 0) (match_dup 1))
1809 (set (match_dup 2) (match_dup 3))]
1810 "split_di (operands + 1, 1, operands + 2, operands + 3);
1811 operands[1] = gen_lowpart (DImode, operands[2]);
1812 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1813 GEN_INT (4)));
1814 ")
1815
1816(define_split
1817 [(set (match_operand:DI 0 "push_operand" "")
1818 (match_operand:DI 1 "immediate_operand" ""))]
93330ea1 1819 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
0ec259ed
JH
1820 && !symbolic_operand (operands[1], DImode)
1821 && !x86_64_immediate_operand (operands[1], DImode)"
1822 [(set (match_dup 0) (match_dup 1))
1823 (set (match_dup 2) (match_dup 3))]
1824 "split_di (operands + 1, 1, operands + 2, operands + 3);
1825 operands[1] = gen_lowpart (DImode, operands[2]);
1826 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1827 GEN_INT (4)));
1828 ")
1829
1830(define_insn "*pushdi2_prologue_rex64"
1831 [(set (match_operand:DI 0 "push_operand" "=<")
1832 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
f2042df3 1833 (clobber (mem:BLK (scratch)))]
0ec259ed 1834 "TARGET_64BIT"
0f40f9f7 1835 "push{q}\t%1"
0ec259ed
JH
1836 [(set_attr "type" "push")
1837 (set_attr "mode" "DI")])
1838
1839(define_insn "*popdi1_epilogue_rex64"
1840 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
1841 (mem:DI (reg:DI SP_REG)))
1842 (set (reg:DI SP_REG)
1843 (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 1844 (clobber (mem:BLK (scratch)))]
0ec259ed 1845 "TARGET_64BIT"
0f40f9f7 1846 "pop{q}\t%0"
0ec259ed
JH
1847 [(set_attr "type" "pop")
1848 (set_attr "mode" "DI")])
1849
1850(define_insn "popdi1"
1851 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
1852 (mem:DI (reg:DI SP_REG)))
1853 (set (reg:DI SP_REG)
1854 (plus:DI (reg:DI SP_REG) (const_int 8)))]
0ec259ed 1855 "TARGET_64BIT"
0f40f9f7 1856 "pop{q}\t%0"
0ec259ed
JH
1857 [(set_attr "type" "pop")
1858 (set_attr "mode" "DI")])
1859
1860(define_insn "*movdi_xor_rex64"
1861 [(set (match_operand:DI 0 "register_operand" "=r")
1862 (match_operand:DI 1 "const0_operand" "i"))
8bc527af 1863 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
1864 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1865 && reload_completed"
0f40f9f7 1866 "xor{l}\t{%k0, %k0|%k0, %k0}"
0ec259ed
JH
1867 [(set_attr "type" "alu1")
1868 (set_attr "mode" "SI")
1869 (set_attr "length_immediate" "0")])
1870
1871(define_insn "*movdi_or_rex64"
1872 [(set (match_operand:DI 0 "register_operand" "=r")
1873 (match_operand:DI 1 "const_int_operand" "i"))
8bc527af 1874 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
1875 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1876 && reload_completed
87d9741e 1877 && operands[1] == constm1_rtx"
0ec259ed
JH
1878{
1879 operands[1] = constm1_rtx;
0f40f9f7
ZW
1880 return "or{q}\t{%1, %0|%0, %1}";
1881}
0ec259ed
JH
1882 [(set_attr "type" "alu1")
1883 (set_attr "mode" "DI")
1884 (set_attr "length_immediate" "1")])
1885
e075ae69 1886(define_insn "*movdi_2"
749e7b80 1887 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
141e454b 1888 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1e07edd3
JH
1889 "!TARGET_64BIT
1890 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
915119a5
BS
1891 "@
1892 #
1893 #
0f40f9f7
ZW
1894 movq\t{%1, %0|%0, %1}
1895 movq\t{%1, %0|%0, %1}
1896 movq\t{%1, %0|%0, %1}
1897 movdqa\t{%1, %0|%0, %1}
1898 movq\t{%1, %0|%0, %1}"
3d34cd91 1899 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
141e454b 1900 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
dc0f0eb8 1901
e075ae69
RH
1902(define_split
1903 [(set (match_operand:DI 0 "push_operand" "")
1904 (match_operand:DI 1 "general_operand" ""))]
6c12e488
JH
1905 "!TARGET_64BIT && reload_completed
1906 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2450a057 1907 [(const_int 0)]
26e5b205 1908 "ix86_split_long_move (operands); DONE;")
f31fce3f 1909
e075ae69 1910;; %%% This multiword shite has got to go.
e075ae69 1911(define_split
c76aab11 1912 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69 1913 (match_operand:DI 1 "general_operand" ""))]
6c12e488
JH
1914 "!TARGET_64BIT && reload_completed
1915 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1916 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
26e5b205
JH
1917 [(const_int 0)]
1918 "ix86_split_long_move (operands); DONE;")
0ec259ed
JH
1919
1920(define_insn "*movdi_1_rex64"
9e9fb0ce
JB
1921 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1922 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1b0c37d7 1923 "TARGET_64BIT
8f62128d 1924 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1b0c37d7 1925 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0ec259ed
JH
1926{
1927 switch (get_attr_type (insn))
1928 {
9e9fb0ce
JB
1929 case TYPE_SSECVT:
1930 if (which_alternative == 11)
1931 return "movq2dq\t{%1, %0|%0, %1}";
1932 else
1933 return "movdq2q\t{%1, %0|%0, %1}";
5f90a099 1934 case TYPE_SSEMOV:
8f62128d 1935 if (get_attr_mode (insn) == MODE_TI)
0f40f9f7 1936 return "movdqa\t{%1, %0|%0, %1}";
5efb1046 1937 /* FALLTHRU */
5ccbcd8c 1938 case TYPE_MMXMOV:
8f62128d
JH
1939 /* Moves from and into integer register is done using movd opcode with
1940 REX prefix. */
1941 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942 return "movd\t{%1, %0|%0, %1}";
0f40f9f7 1943 return "movq\t{%1, %0|%0, %1}";
0ec259ed 1944 case TYPE_MULTI:
0f40f9f7 1945 return "#";
0ec259ed 1946 case TYPE_LEA:
0f40f9f7 1947 return "lea{q}\t{%a1, %0|%0, %a1}";
0ec259ed 1948 default:
57d47446 1949 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
0ec259ed
JH
1950 abort ();
1951 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 1952 return "mov{l}\t{%k1, %k0|%k0, %k1}";
0ec259ed 1953 else if (which_alternative == 2)
0f40f9f7 1954 return "movabs{q}\t{%1, %0|%0, %1}";
0ec259ed 1955 else
0f40f9f7 1956 return "mov{q}\t{%1, %0|%0, %1}";
0ec259ed 1957 }
0f40f9f7 1958}
0ec259ed 1959 [(set (attr "type")
8f62128d 1960 (cond [(eq_attr "alternative" "5,6,7")
3d34cd91 1961 (const_string "mmxmov")
8f62128d 1962 (eq_attr "alternative" "8,9,10")
3d34cd91 1963 (const_string "ssemov")
9e9fb0ce
JB
1964 (eq_attr "alternative" "11,12")
1965 (const_string "ssecvt")
0ec259ed
JH
1966 (eq_attr "alternative" "4")
1967 (const_string "multi")
1968 (and (ne (symbol_ref "flag_pic") (const_int 0))
1969 (match_operand:DI 1 "symbolic_operand" ""))
1970 (const_string "lea")
1971 ]
1972 (const_string "imov")))
9e9fb0ce
JB
1973 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1974 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1975 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
8f62128d
JH
1976
1977(define_insn "*movdi_1_rex64_nointerunit"
1978 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1979 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1980 "TARGET_64BIT
1981 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1982 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1983{
1984 switch (get_attr_type (insn))
1985 {
1986 case TYPE_SSEMOV:
1987 if (get_attr_mode (insn) == MODE_TI)
1988 return "movdqa\t{%1, %0|%0, %1}";
5efb1046 1989 /* FALLTHRU */
8f62128d
JH
1990 case TYPE_MMXMOV:
1991 return "movq\t{%1, %0|%0, %1}";
1992 case TYPE_MULTI:
1993 return "#";
1994 case TYPE_LEA:
1995 return "lea{q}\t{%a1, %0|%0, %a1}";
1996 default:
1997 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1998 abort ();
1999 if (get_attr_mode (insn) == MODE_SI)
2000 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2001 else if (which_alternative == 2)
2002 return "movabs{q}\t{%1, %0|%0, %1}";
2003 else
2004 return "mov{q}\t{%1, %0|%0, %1}";
2005 }
2006}
2007 [(set (attr "type")
2008 (cond [(eq_attr "alternative" "5,6,7")
2009 (const_string "mmxmov")
2010 (eq_attr "alternative" "8,9,10")
2011 (const_string "ssemov")
2012 (eq_attr "alternative" "4")
2013 (const_string "multi")
2014 (and (ne (symbol_ref "flag_pic") (const_int 0))
2015 (match_operand:DI 1 "symbolic_operand" ""))
2016 (const_string "lea")
2017 ]
2018 (const_string "imov")))
2019 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2020 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2021 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
0ec259ed 2022
d1f87653 2023;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
2024;; We fake an second form of instruction to force reload to load address
2025;; into register when rax is not available
2026(define_insn "*movabsdi_1_rex64"
7e6dc358
JJ
2027 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2029 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 2030 "@
0f40f9f7 2031 movabs{q}\t{%1, %P0|%P0, %1}
7e6dc358 2032 mov{q}\t{%1, %a0|%a0, %1}"
0ec259ed 2033 [(set_attr "type" "imov")
7e6dc358
JJ
2034 (set_attr "modrm" "0,*")
2035 (set_attr "length_address" "8,0")
2036 (set_attr "length_immediate" "0,*")
0ec259ed
JH
2037 (set_attr "memory" "store")
2038 (set_attr "mode" "DI")])
2039
2040(define_insn "*movabsdi_2_rex64"
2041 [(set (match_operand:DI 0 "register_operand" "=a,r")
2042 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 2043 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 2044 "@
0f40f9f7
ZW
2045 movabs{q}\t{%P1, %0|%0, %P1}
2046 mov{q}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
2047 [(set_attr "type" "imov")
2048 (set_attr "modrm" "0,*")
2049 (set_attr "length_address" "8,0")
2050 (set_attr "length_immediate" "0")
2051 (set_attr "memory" "load")
2052 (set_attr "mode" "DI")])
2053
2054;; Convert impossible stores of immediate to existing instructions.
f5143c46 2055;; First try to get scratch register and go through it. In case this
0ec259ed
JH
2056;; fails, move by 32bit parts.
2057(define_peephole2
2058 [(match_scratch:DI 2 "r")
2059 (set (match_operand:DI 0 "memory_operand" "")
2060 (match_operand:DI 1 "immediate_operand" ""))]
2061 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2062 && !x86_64_immediate_operand (operands[1], DImode)"
2063 [(set (match_dup 2) (match_dup 1))
2064 (set (match_dup 0) (match_dup 2))]
2065 "")
2066
2067;; We need to define this as both peepholer and splitter for case
2068;; peephole2 pass is not run.
731edaed 2069;; "&& 1" is needed to keep it from matching the previous pattern.
0ec259ed
JH
2070(define_peephole2
2071 [(set (match_operand:DI 0 "memory_operand" "")
2072 (match_operand:DI 1 "immediate_operand" ""))]
2073 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
731edaed 2074 && !x86_64_immediate_operand (operands[1], DImode) && 1"
0ec259ed
JH
2075 [(set (match_dup 2) (match_dup 3))
2076 (set (match_dup 4) (match_dup 5))]
2077 "split_di (operands, 2, operands + 2, operands + 4);")
2078
2079(define_split
2080 [(set (match_operand:DI 0 "memory_operand" "")
2081 (match_operand:DI 1 "immediate_operand" ""))]
93330ea1 2082 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
0ec259ed
JH
2083 && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode)"
2085 [(set (match_dup 2) (match_dup 3))
2086 (set (match_dup 4) (match_dup 5))]
2087 "split_di (operands, 2, operands + 2, operands + 4);")
2088
2089(define_insn "*swapdi_rex64"
2090 [(set (match_operand:DI 0 "register_operand" "+r")
2091 (match_operand:DI 1 "register_operand" "+r"))
2092 (set (match_dup 1)
2093 (match_dup 0))]
2094 "TARGET_64BIT"
0f40f9f7 2095 "xchg{q}\t%1, %0"
0ec259ed
JH
2096 [(set_attr "type" "imov")
2097 (set_attr "pent_pair" "np")
2098 (set_attr "athlon_decode" "vector")
2099 (set_attr "mode" "DI")
56bab446 2100 (set_attr "modrm" "0")])
0ec259ed 2101
e075ae69 2102
0be5d99f 2103(define_expand "movsf"
4cbfbb1b 2104 [(set (match_operand:SF 0 "nonimmediate_operand" "")
0be5d99f
MM
2105 (match_operand:SF 1 "general_operand" ""))]
2106 ""
e075ae69
RH
2107 "ix86_expand_move (SFmode, operands); DONE;")
2108
2109(define_insn "*pushsf"
446988df 2110 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
c6e95f34 2111 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
0ec259ed 2112 "!TARGET_64BIT"
0be5d99f 2113{
e075ae69 2114 switch (which_alternative)
0be5d99f 2115 {
e075ae69 2116 case 1:
0f40f9f7 2117 return "push{l}\t%1";
e075ae69
RH
2118
2119 default:
839a4992 2120 /* This insn should be already split before reg-stack. */
e075ae69 2121 abort ();
0bb6c81b 2122 }
0f40f9f7 2123}
446988df
JH
2124 [(set_attr "type" "multi,push,multi")
2125 (set_attr "mode" "SF,SI,SF")])
0be5d99f 2126
0ec259ed
JH
2127(define_insn "*pushsf_rex64"
2128 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2129 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2130 "TARGET_64BIT"
0ec259ed
JH
2131{
2132 switch (which_alternative)
2133 {
0ec259ed 2134 case 1:
0f40f9f7 2135 return "push{q}\t%q1";
0ec259ed 2136
0ec259ed 2137 default:
839a4992 2138 /* This insn should be already split before reg-stack. */
0ec259ed
JH
2139 abort ();
2140 }
0f40f9f7 2141}
0ec259ed
JH
2142 [(set_attr "type" "multi,push,multi")
2143 (set_attr "mode" "SF,DI,SF")])
2144
d7a29404
JH
2145(define_split
2146 [(set (match_operand:SF 0 "push_operand" "")
2147 (match_operand:SF 1 "memory_operand" ""))]
2148 "reload_completed
2149 && GET_CODE (operands[1]) == MEM
2150 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2151 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2152 [(set (match_dup 0)
2153 (match_dup 1))]
2154 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2155
2156
e075ae69
RH
2157;; %%% Kill this when call knows how to work this out.
2158(define_split
2159 [(set (match_operand:SF 0 "push_operand" "")
c3c637e3
GS
2160 (match_operand:SF 1 "any_fp_register_operand" ""))]
2161 "!TARGET_64BIT"
8bc527af
SB
2162 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2163 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
e075ae69 2164
0ec259ed
JH
2165(define_split
2166 [(set (match_operand:SF 0 "push_operand" "")
c3c637e3
GS
2167 (match_operand:SF 1 "any_fp_register_operand" ""))]
2168 "TARGET_64BIT"
8bc527af
SB
2169 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2170 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
0ec259ed 2171
e075ae69 2172(define_insn "*movsf_1"
e5a20888 2173 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
f8ca7923 2174 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
8f62128d
JH
2175 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2176 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2177 && (reload_in_progress || reload_completed
2178 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2179 || GET_CODE (operands[1]) != CONST_DOUBLE
2180 || memory_operand (operands[0], SFmode))"
2181{
2182 switch (which_alternative)
2183 {
2184 case 0:
5ea9cb6e 2185 return output_387_reg_move (insn, operands);
8f62128d
JH
2186
2187 case 1:
2188 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2189 return "fstp%z0\t%y0";
2190 else
2191 return "fst%z0\t%y0";
2192
2193 case 2:
881b2a96 2194 return standard_80387_constant_opcode (operands[1]);
8f62128d
JH
2195
2196 case 3:
2197 case 4:
2198 return "mov{l}\t{%1, %0|%0, %1}";
2199 case 5:
2200 if (get_attr_mode (insn) == MODE_TI)
2201 return "pxor\t%0, %0";
2202 else
2203 return "xorps\t%0, %0";
2204 case 6:
2205 if (get_attr_mode (insn) == MODE_V4SF)
2206 return "movaps\t{%1, %0|%0, %1}";
2207 else
2208 return "movss\t{%1, %0|%0, %1}";
2209 case 7:
2210 case 8:
2211 return "movss\t{%1, %0|%0, %1}";
2212
2213 case 9:
2214 case 10:
2215 return "movd\t{%1, %0|%0, %1}";
2216
2217 case 11:
2218 return "movq\t{%1, %0|%0, %1}";
2219
2220 default:
2221 abort();
2222 }
2223}
2224 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2225 (set (attr "mode")
2226 (cond [(eq_attr "alternative" "3,4,9,10")
2227 (const_string "SI")
2228 (eq_attr "alternative" "5")
2229 (if_then_else
2230 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2231 (const_int 0))
2232 (ne (symbol_ref "TARGET_SSE2")
2233 (const_int 0)))
2234 (eq (symbol_ref "optimize_size")
2235 (const_int 0)))
2236 (const_string "TI")
2237 (const_string "V4SF"))
2238 /* For architectures resolving dependencies on
2239 whole SSE registers use APS move to break dependency
2240 chains, otherwise use short move to avoid extra work.
2241
2242 Do the same for architectures resolving dependencies on
2243 the parts. While in DF mode it is better to always handle
2244 just register parts, the SF mode is different due to lack
2245 of instructions to load just part of the register. It is
2246 better to maintain the whole registers in single format
2247 to avoid problems on using packed logical operations. */
2248 (eq_attr "alternative" "6")
2249 (if_then_else
2250 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2251 (const_int 0))
2252 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2253 (const_int 0)))
2254 (const_string "V4SF")
2255 (const_string "SF"))
2256 (eq_attr "alternative" "11")
2257 (const_string "DI")]
2258 (const_string "SF")))])
2259
2260(define_insn "*movsf_1_nointerunit"
2261 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2262 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2263 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2264 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
d7a29404 2265 && (reload_in_progress || reload_completed
3987b9db 2266 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
d7a29404
JH
2267 || GET_CODE (operands[1]) != CONST_DOUBLE
2268 || memory_operand (operands[0], SFmode))"
886c62d1 2269{
e075ae69 2270 switch (which_alternative)
886c62d1 2271 {
e075ae69 2272 case 0:
5ea9cb6e 2273 return output_387_reg_move (insn, operands);
886c62d1 2274
e075ae69
RH
2275 case 1:
2276 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2277 return "fstp%z0\t%y0";
886c62d1 2278 else
0f40f9f7 2279 return "fst%z0\t%y0";
886c62d1 2280
e075ae69 2281 case 2:
881b2a96 2282 return standard_80387_constant_opcode (operands[1]);
886c62d1 2283
e075ae69
RH
2284 case 3:
2285 case 4:
0f40f9f7 2286 return "mov{l}\t{%1, %0|%0, %1}";
446988df 2287 case 5:
4977bab6 2288 if (get_attr_mode (insn) == MODE_TI)
692efa8e
JJ
2289 return "pxor\t%0, %0";
2290 else
2291 return "xorps\t%0, %0";
446988df 2292 case 6:
4977bab6 2293 if (get_attr_mode (insn) == MODE_V4SF)
0f40f9f7 2294 return "movaps\t{%1, %0|%0, %1}";
2b04e52b 2295 else
0f40f9f7 2296 return "movss\t{%1, %0|%0, %1}";
2b04e52b
JH
2297 case 7:
2298 case 8:
0f40f9f7 2299 return "movss\t{%1, %0|%0, %1}";
886c62d1 2300
ac300a45
JJ
2301 case 9:
2302 case 10:
2303 return "movd\t{%1, %0|%0, %1}";
2304
e5a20888
JJ
2305 case 11:
2306 return "movq\t{%1, %0|%0, %1}";
2307
e075ae69
RH
2308 default:
2309 abort();
2310 }
0f40f9f7 2311}
3d34cd91 2312 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
4977bab6
ZW
2313 (set (attr "mode")
2314 (cond [(eq_attr "alternative" "3,4,9,10")
2315 (const_string "SI")
2316 (eq_attr "alternative" "5")
2317 (if_then_else
2318 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2319 (const_int 0))
2320 (ne (symbol_ref "TARGET_SSE2")
2321 (const_int 0)))
2322 (eq (symbol_ref "optimize_size")
2323 (const_int 0)))
2324 (const_string "TI")
2325 (const_string "V4SF"))
2326 /* For architectures resolving dependencies on
2327 whole SSE registers use APS move to break dependency
2328 chains, otherwise use short move to avoid extra work.
2329
2330 Do the same for architectures resolving dependencies on
2331 the parts. While in DF mode it is better to always handle
2332 just register parts, the SF mode is different due to lack
2333 of instructions to load just part of the register. It is
2334 better to maintain the whole registers in single format
2335 to avoid problems on using packed logical operations. */
2336 (eq_attr "alternative" "6")
2337 (if_then_else
2338 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2339 (const_int 0))
2340 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2341 (const_int 0)))
2342 (const_string "V4SF")
2343 (const_string "SF"))
2344 (eq_attr "alternative" "11")
2345 (const_string "DI")]
2346 (const_string "SF")))])
d7a29404 2347
a4414093 2348(define_insn "*swapsf"
e075ae69
RH
2349 [(set (match_operand:SF 0 "register_operand" "+f")
2350 (match_operand:SF 1 "register_operand" "+f"))
0be5d99f
MM
2351 (set (match_dup 1)
2352 (match_dup 0))]
965f5423 2353 "reload_completed || !TARGET_SSE"
0be5d99f
MM
2354{
2355 if (STACK_TOP_P (operands[0]))
0f40f9f7 2356 return "fxch\t%1";
0be5d99f 2357 else
0f40f9f7
ZW
2358 return "fxch\t%0";
2359}
6ef67412
JH
2360 [(set_attr "type" "fxch")
2361 (set_attr "mode" "SF")])
0be5d99f 2362
e075ae69 2363(define_expand "movdf"
4cbfbb1b 2364 [(set (match_operand:DF 0 "nonimmediate_operand" "")
e075ae69
RH
2365 (match_operand:DF 1 "general_operand" ""))]
2366 ""
2367 "ix86_expand_move (DFmode, operands); DONE;")
55953cea 2368
8fcaaa80 2369;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
d1f87653 2370;; Size of pushdf using integer instructions is 2+2*memory operand size
8fcaaa80
JH
2371;; On the average, pushdf using integers can be still shorter. Allow this
2372;; pattern for optimize_size too.
2373
0b5107cf 2374(define_insn "*pushdf_nointeger"
446988df 2375 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
c6e95f34 2376 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
0ec259ed 2377 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
0b5107cf 2378{
839a4992 2379 /* This insn should be already split before reg-stack. */
4977bab6 2380 abort ();
0f40f9f7 2381}
6ef67412 2382 [(set_attr "type" "multi")
446988df 2383 (set_attr "mode" "DF,SI,SI,DF")])
0b5107cf
JH
2384
2385(define_insn "*pushdf_integer"
446988df
JH
2386 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2387 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
0ec259ed 2388 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
f31fce3f 2389{
839a4992 2390 /* This insn should be already split before reg-stack. */
4977bab6 2391 abort ();
0f40f9f7 2392}
6ef67412 2393 [(set_attr "type" "multi")
446988df 2394 (set_attr "mode" "DF,SI,DF")])
f31fce3f 2395
e075ae69 2396;; %%% Kill this when call knows how to work this out.
f72b27a5
JH
2397(define_split
2398 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3
GS
2399 (match_operand:DF 1 "any_fp_register_operand" ""))]
2400 "!TARGET_64BIT && reload_completed"
8bc527af
SB
2401 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2402 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
f72b27a5 2403 "")
f31fce3f 2404
0ec259ed
JH
2405(define_split
2406 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3
GS
2407 (match_operand:DF 1 "any_fp_register_operand" ""))]
2408 "TARGET_64BIT && reload_completed"
8bc527af
SB
2409 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2410 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
0ec259ed
JH
2411 "")
2412
e075ae69
RH
2413(define_split
2414 [(set (match_operand:DF 0 "push_operand" "")
0be5d99f 2415 (match_operand:DF 1 "general_operand" ""))]
e075ae69 2416 "reload_completed"
2450a057 2417 [(const_int 0)]
26e5b205 2418 "ix86_split_long_move (operands); DONE;")
0be5d99f 2419
8fcaaa80
JH
2420;; Moving is usually shorter when only FP registers are used. This separate
2421;; movdf pattern avoids the use of integer registers for FP operations
2422;; when optimizing for size.
2423
2424(define_insn "*movdf_nointeger"
2b04e52b 2425 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
f8ca7923 2426 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
8fcaaa80 2427 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
4977bab6 2428 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
d7a29404 2429 && (reload_in_progress || reload_completed
3987b9db 2430 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
d7a29404
JH
2431 || GET_CODE (operands[1]) != CONST_DOUBLE
2432 || memory_operand (operands[0], DFmode))"
8fcaaa80
JH
2433{
2434 switch (which_alternative)
2435 {
2436 case 0:
5ea9cb6e 2437 return output_387_reg_move (insn, operands);
8fcaaa80
JH
2438
2439 case 1:
2440 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2441 return "fstp%z0\t%y0";
8fcaaa80 2442 else
0f40f9f7 2443 return "fst%z0\t%y0";
8fcaaa80
JH
2444
2445 case 2:
881b2a96 2446 return standard_80387_constant_opcode (operands[1]);
8fcaaa80
JH
2447
2448 case 3:
2449 case 4:
0f40f9f7 2450 return "#";
446988df 2451 case 5:
4977bab6
ZW
2452 switch (get_attr_mode (insn))
2453 {
2454 case MODE_V4SF:
2455 return "xorps\t%0, %0";
2456 case MODE_V2DF:
2457 return "xorpd\t%0, %0";
2458 case MODE_TI:
2459 return "pxor\t%0, %0";
2460 default:
2461 abort ();
2462 }
446988df 2463 case 6:
4977bab6
ZW
2464 switch (get_attr_mode (insn))
2465 {
2466 case MODE_V4SF:
2467 return "movaps\t{%1, %0|%0, %1}";
2468 case MODE_V2DF:
2469 return "movapd\t{%1, %0|%0, %1}";
2470 case MODE_DF:
2471 return "movsd\t{%1, %0|%0, %1}";
2472 default:
2473 abort ();
2474 }
2475 case 7:
2476 if (get_attr_mode (insn) == MODE_V2DF)
2477 return "movlpd\t{%1, %0|%0, %1}";
2b04e52b 2478 else
0f40f9f7 2479 return "movsd\t{%1, %0|%0, %1}";
2b04e52b 2480 case 8:
4977bab6 2481 return "movsd\t{%1, %0|%0, %1}";
8fcaaa80
JH
2482
2483 default:
2484 abort();
2485 }
0f40f9f7 2486}
3d34cd91 2487 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
4977bab6
ZW
2488 (set (attr "mode")
2489 (cond [(eq_attr "alternative" "3,4")
2490 (const_string "SI")
2491 /* xorps is one byte shorter. */
2492 (eq_attr "alternative" "5")
2493 (cond [(ne (symbol_ref "optimize_size")
2494 (const_int 0))
2495 (const_string "V4SF")
2496 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2497 (const_int 0))
2498 (const_string "TI")]
2499 (const_string "V2DF"))
2500 /* For architectures resolving dependencies on
2501 whole SSE registers use APD move to break dependency
2502 chains, otherwise use short move to avoid extra work.
2503
2504 movaps encodes one byte shorter. */
2505 (eq_attr "alternative" "6")
2506 (cond
2507 [(ne (symbol_ref "optimize_size")
2508 (const_int 0))
2509 (const_string "V4SF")
2510 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2511 (const_int 0))
2512 (const_string "V2DF")]
2513 (const_string "DF"))
d1f87653 2514 /* For architectures resolving dependencies on register
4977bab6
ZW
2515 parts we may avoid extra work to zero out upper part
2516 of register. */
2517 (eq_attr "alternative" "7")
2518 (if_then_else
2519 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2520 (const_int 0))
2521 (const_string "V2DF")
2522 (const_string "DF"))]
2523 (const_string "DF")))])
8fcaaa80
JH
2524
2525(define_insn "*movdf_integer"
2b04e52b 2526 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
f8ca7923 2527 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
8fcaaa80 2528 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
4977bab6 2529 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
d7a29404 2530 && (reload_in_progress || reload_completed
3987b9db 2531 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
d7a29404
JH
2532 || GET_CODE (operands[1]) != CONST_DOUBLE
2533 || memory_operand (operands[0], DFmode))"
886c62d1 2534{
e075ae69 2535 switch (which_alternative)
886c62d1 2536 {
e075ae69 2537 case 0:
5ea9cb6e 2538 return output_387_reg_move (insn, operands);
886c62d1 2539
e075ae69
RH
2540 case 1:
2541 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2542 return "fstp%z0\t%y0";
886c62d1 2543 else
0f40f9f7 2544 return "fst%z0\t%y0";
886c62d1 2545
e075ae69 2546 case 2:
881b2a96 2547 return standard_80387_constant_opcode (operands[1]);
886c62d1 2548
e075ae69
RH
2549 case 3:
2550 case 4:
0f40f9f7 2551 return "#";
886c62d1 2552
446988df 2553 case 5:
4977bab6
ZW
2554 switch (get_attr_mode (insn))
2555 {
2556 case MODE_V4SF:
2557 return "xorps\t%0, %0";
2558 case MODE_V2DF:
2559 return "xorpd\t%0, %0";
2560 case MODE_TI:
2561 return "pxor\t%0, %0";
2562 default:
2563 abort ();
2564 }
446988df 2565 case 6:
4977bab6
ZW
2566 switch (get_attr_mode (insn))
2567 {
2568 case MODE_V4SF:
2569 return "movaps\t{%1, %0|%0, %1}";
2570 case MODE_V2DF:
2571 return "movapd\t{%1, %0|%0, %1}";
2572 case MODE_DF:
2573 return "movsd\t{%1, %0|%0, %1}";
2574 default:
2575 abort ();
2576 }
2577 case 7:
2578 if (get_attr_mode (insn) == MODE_V2DF)
2579 return "movlpd\t{%1, %0|%0, %1}";
2b04e52b 2580 else
0f40f9f7 2581 return "movsd\t{%1, %0|%0, %1}";
2b04e52b 2582 case 8:
0f40f9f7 2583 return "movsd\t{%1, %0|%0, %1}";
446988df 2584
e075ae69
RH
2585 default:
2586 abort();
2587 }
0f40f9f7 2588}
3d34cd91 2589 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
4977bab6
ZW
2590 (set (attr "mode")
2591 (cond [(eq_attr "alternative" "3,4")
2592 (const_string "SI")
2593 /* xorps is one byte shorter. */
2594 (eq_attr "alternative" "5")
2595 (cond [(ne (symbol_ref "optimize_size")
2596 (const_int 0))
2597 (const_string "V4SF")
2598 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2599 (const_int 0))
2600 (const_string "TI")]
2601 (const_string "V2DF"))
2602 /* For architectures resolving dependencies on
2603 whole SSE registers use APD move to break dependency
2604 chains, otherwise use short move to avoid extra work.
2605
2606 movaps encodes one byte shorter. */
2607 (eq_attr "alternative" "6")
2608 (cond
2609 [(ne (symbol_ref "optimize_size")
2610 (const_int 0))
2611 (const_string "V4SF")
2612 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2613 (const_int 0))
2614 (const_string "V2DF")]
2615 (const_string "DF"))
d1f87653 2616 /* For architectures resolving dependencies on register
4977bab6
ZW
2617 parts we may avoid extra work to zero out upper part
2618 of register. */
2619 (eq_attr "alternative" "7")
2620 (if_then_else
2621 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2622 (const_int 0))
2623 (const_string "V2DF")
2624 (const_string "DF"))]
2625 (const_string "DF")))])
2ae0f82c 2626
e075ae69
RH
2627(define_split
2628 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2629 (match_operand:DF 1 "general_operand" ""))]
2630 "reload_completed
2631 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
446988df 2632 && ! (ANY_FP_REG_P (operands[0]) ||
e075ae69 2633 (GET_CODE (operands[0]) == SUBREG
446988df
JH
2634 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2635 && ! (ANY_FP_REG_P (operands[1]) ||
e075ae69 2636 (GET_CODE (operands[1]) == SUBREG
446988df 2637 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
26e5b205
JH
2638 [(const_int 0)]
2639 "ix86_split_long_move (operands); DONE;")
886c62d1 2640
a4414093 2641(define_insn "*swapdf"
e075ae69
RH
2642 [(set (match_operand:DF 0 "register_operand" "+f")
2643 (match_operand:DF 1 "register_operand" "+f"))
0be5d99f
MM
2644 (set (match_dup 1)
2645 (match_dup 0))]
446988df 2646 "reload_completed || !TARGET_SSE2"
0be5d99f
MM
2647{
2648 if (STACK_TOP_P (operands[0]))
0f40f9f7 2649 return "fxch\t%1";
0be5d99f 2650 else
0f40f9f7
ZW
2651 return "fxch\t%0";
2652}
6ef67412
JH
2653 [(set_attr "type" "fxch")
2654 (set_attr "mode" "DF")])
e075ae69
RH
2655
2656(define_expand "movxf"
4cbfbb1b 2657 [(set (match_operand:XF 0 "nonimmediate_operand" "")
e075ae69 2658 (match_operand:XF 1 "general_operand" ""))]
2b589241 2659 ""
f8a1ebc6 2660 "ix86_expand_move (XFmode, operands); DONE;")
2b589241 2661
8fcaaa80 2662;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
d1f87653 2663;; Size of pushdf using integer instructions is 3+3*memory operand size
8fcaaa80
JH
2664;; Pushing using integer instructions is longer except for constants
2665;; and direct memory references.
2666;; (assuming that any given constant is pushed only once, but this ought to be
2667;; handled elsewhere).
2668
2669(define_insn "*pushxf_nointeger"
1e07edd3 2670 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2c5a510c 2671 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2b589241 2672 "optimize_size"
2b589241 2673{
839a4992 2674 /* This insn should be already split before reg-stack. */
4977bab6 2675 abort ();
0f40f9f7 2676}
2b589241
JH
2677 [(set_attr "type" "multi")
2678 (set_attr "mode" "XF,SI,SI")])
2679
8fcaaa80 2680(define_insn "*pushxf_integer"
2450a057 2681 [(set (match_operand:XF 0 "push_operand" "=<,<")
1e07edd3 2682 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2b589241 2683 "!optimize_size"
2b589241 2684{
839a4992 2685 /* This insn should be already split before reg-stack. */
4977bab6 2686 abort ();
0f40f9f7 2687}
2b589241
JH
2688 [(set_attr "type" "multi")
2689 (set_attr "mode" "XF,SI")])
2690
2450a057 2691(define_split
2b589241
JH
2692 [(set (match_operand 0 "push_operand" "")
2693 (match_operand 1 "general_operand" ""))]
2450a057 2694 "reload_completed
2b589241 2695 && (GET_MODE (operands[0]) == XFmode
2b589241 2696 || GET_MODE (operands[0]) == DFmode)
c3c637e3 2697 && !ANY_FP_REG_P (operands[1])"
2450a057 2698 [(const_int 0)]
26e5b205 2699 "ix86_split_long_move (operands); DONE;")
2450a057 2700
f72b27a5
JH
2701(define_split
2702 [(set (match_operand:XF 0 "push_operand" "")
c3c637e3 2703 (match_operand:XF 1 "any_fp_register_operand" ""))]
c3c637e3 2704 "!TARGET_64BIT"
8bc527af
SB
2705 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2706 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
f8a1ebc6 2707 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2b589241 2708
0ec259ed 2709(define_split
f8a1ebc6
JH
2710 [(set (match_operand:XF 0 "push_operand" "")
2711 (match_operand:XF 1 "any_fp_register_operand" ""))]
c3c637e3 2712 "TARGET_64BIT"
8bc527af
SB
2713 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2714 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
f8a1ebc6 2715 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
0ec259ed 2716
8fcaaa80
JH
2717;; Do not use integer registers when optimizing for size
2718(define_insn "*movxf_nointeger"
2719 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2720 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
f8a1ebc6 2721 "optimize_size
1b0c37d7 2722 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
d7a29404
JH
2723 && (reload_in_progress || reload_completed
2724 || GET_CODE (operands[1]) != CONST_DOUBLE
2725 || memory_operand (operands[0], XFmode))"
0be5d99f 2726{
8fcaaa80
JH
2727 switch (which_alternative)
2728 {
2729 case 0:
5ea9cb6e 2730 return output_387_reg_move (insn, operands);
0be5d99f 2731
8fcaaa80
JH
2732 case 1:
2733 /* There is no non-popping store to memory for XFmode. So if
2734 we need one, follow the store with a load. */
2735 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2736 return "fstp%z0\t%y0\;fld%z0\t%y0";
8fcaaa80 2737 else
0f40f9f7 2738 return "fstp%z0\t%y0";
8fcaaa80
JH
2739
2740 case 2:
881b2a96 2741 return standard_80387_constant_opcode (operands[1]);
8fcaaa80
JH
2742
2743 case 3: case 4:
0f40f9f7 2744 return "#";
8fcaaa80
JH
2745 }
2746 abort();
0f40f9f7 2747}
6ef67412
JH
2748 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2749 (set_attr "mode" "XF,XF,XF,SI,SI")])
8fcaaa80
JH
2750
2751(define_insn "*movxf_integer"
2752 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2753 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
f8a1ebc6 2754 "!optimize_size
1b0c37d7 2755 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
d7a29404
JH
2756 && (reload_in_progress || reload_completed
2757 || GET_CODE (operands[1]) != CONST_DOUBLE
2758 || memory_operand (operands[0], XFmode))"
4fb21e90 2759{
e075ae69 2760 switch (which_alternative)
4fb21e90 2761 {
e075ae69 2762 case 0:
5ea9cb6e 2763 return output_387_reg_move (insn, operands);
4fb21e90 2764
e075ae69
RH
2765 case 1:
2766 /* There is no non-popping store to memory for XFmode. So if
2767 we need one, follow the store with a load. */
2768 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2769 return "fstp%z0\t%y0\;fld%z0\t%y0";
e075ae69 2770 else
0f40f9f7 2771 return "fstp%z0\t%y0";
2f17722a 2772
e075ae69 2773 case 2:
881b2a96 2774 return standard_80387_constant_opcode (operands[1]);
467403ca
RH
2775
2776 case 3: case 4:
0f40f9f7 2777 return "#";
4fb21e90 2778 }
e075ae69 2779 abort();
0f40f9f7 2780}
6ef67412
JH
2781 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2782 (set_attr "mode" "XF,XF,XF,SI,SI")])
4fb21e90 2783
467403ca 2784(define_split
2b589241
JH
2785 [(set (match_operand 0 "nonimmediate_operand" "")
2786 (match_operand 1 "general_operand" ""))]
2450a057 2787 "reload_completed
8fcaaa80 2788 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
f8a1ebc6 2789 && GET_MODE (operands[0]) == XFmode
446988df 2790 && ! (ANY_FP_REG_P (operands[0]) ||
8fcaaa80 2791 (GET_CODE (operands[0]) == SUBREG
446988df
JH
2792 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2793 && ! (ANY_FP_REG_P (operands[1]) ||
8fcaaa80 2794 (GET_CODE (operands[1]) == SUBREG
446988df 2795 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
26e5b205
JH
2796 [(const_int 0)]
2797 "ix86_split_long_move (operands); DONE;")
467403ca 2798
d7a29404 2799(define_split
2b589241
JH
2800 [(set (match_operand 0 "register_operand" "")
2801 (match_operand 1 "memory_operand" ""))]
d7a29404
JH
2802 "reload_completed
2803 && GET_CODE (operands[1]) == MEM
f8a1ebc6 2804 && (GET_MODE (operands[0]) == XFmode
2b04e52b 2805 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
d7a29404 2806 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
b87cfcfb
RH
2807 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2808 [(set (match_dup 0) (match_dup 1))]
2809{
2810 rtx c = get_pool_constant (XEXP (operands[1], 0));
2811 rtx r = operands[0];
2812
2813 if (GET_CODE (r) == SUBREG)
2814 r = SUBREG_REG (r);
2815
2816 if (SSE_REG_P (r))
2817 {
2818 if (!standard_sse_constant_p (c))
2819 FAIL;
2820 }
2821 else if (FP_REG_P (r))
2822 {
2823 if (!standard_80387_constant_p (c))
2824 FAIL;
2825 }
2826 else if (MMX_REG_P (r))
2827 FAIL;
2828
2829 operands[1] = c;
2830})
d7a29404 2831
e075ae69
RH
2832(define_insn "swapxf"
2833 [(set (match_operand:XF 0 "register_operand" "+f")
2834 (match_operand:XF 1 "register_operand" "+f"))
0be5d99f
MM
2835 (set (match_dup 1)
2836 (match_dup 0))]
2837 ""
0be5d99f
MM
2838{
2839 if (STACK_TOP_P (operands[0]))
0f40f9f7 2840 return "fxch\t%1";
0be5d99f 2841 else
0f40f9f7
ZW
2842 return "fxch\t%0";
2843}
0b5107cf 2844 [(set_attr "type" "fxch")
6ef67412 2845 (set_attr "mode" "XF")])
886c62d1 2846\f
e075ae69 2847;; Zero extension instructions
886c62d1 2848
8f7661f2
JH
2849(define_expand "zero_extendhisi2"
2850 [(set (match_operand:SI 0 "register_operand" "")
2851 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
d626200a 2852 ""
e075ae69 2853{
8f7661f2 2854 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2ae0f82c 2855 {
8f7661f2
JH
2856 operands[1] = force_reg (HImode, operands[1]);
2857 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2858 DONE;
2ae0f82c 2859 }
0f40f9f7 2860})
886c62d1 2861
8f7661f2
JH
2862(define_insn "zero_extendhisi2_and"
2863 [(set (match_operand:SI 0 "register_operand" "=r")
2864 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
8bc527af 2865 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
2866 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2867 "#"
6ef67412
JH
2868 [(set_attr "type" "alu1")
2869 (set_attr "mode" "SI")])
2ae0f82c
SC
2870
2871(define_split
2872 [(set (match_operand:SI 0 "register_operand" "")
8f7661f2 2873 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
8bc527af 2874 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
2875 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2876 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
8bc527af 2877 (clobber (reg:CC FLAGS_REG))])]
d626200a
JL
2878 "")
2879
8f7661f2
JH
2880(define_insn "*zero_extendhisi2_movzwl"
2881 [(set (match_operand:SI 0 "register_operand" "=r")
2882 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2883 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
0f40f9f7 2884 "movz{wl|x}\t{%1, %0|%0, %1}"
6ef67412
JH
2885 [(set_attr "type" "imovx")
2886 (set_attr "mode" "SI")])
8f7661f2
JH
2887
2888(define_expand "zero_extendqihi2"
2889 [(parallel
2890 [(set (match_operand:HI 0 "register_operand" "")
2891 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 2892 (clobber (reg:CC FLAGS_REG))])]
e075ae69 2893 ""
8f7661f2
JH
2894 "")
2895
2896(define_insn "*zero_extendqihi2_and"
2897 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2898 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
8bc527af 2899 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
2900 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2901 "#"
6ef67412
JH
2902 [(set_attr "type" "alu1")
2903 (set_attr "mode" "HI")])
8f7661f2
JH
2904
2905(define_insn "*zero_extendqihi2_movzbw_and"
2906 [(set (match_operand:HI 0 "register_operand" "=r,r")
2907 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
8bc527af 2908 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
2909 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2910 "#"
6ef67412
JH
2911 [(set_attr "type" "imovx,alu1")
2912 (set_attr "mode" "HI")])
886c62d1 2913
8f7661f2
JH
2914(define_insn "*zero_extendqihi2_movzbw"
2915 [(set (match_operand:HI 0 "register_operand" "=r")
2916 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1c27d4b2 2917 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
0f40f9f7 2918 "movz{bw|x}\t{%1, %0|%0, %1}"
6ef67412
JH
2919 [(set_attr "type" "imovx")
2920 (set_attr "mode" "HI")])
8f7661f2
JH
2921
2922;; For the movzbw case strip only the clobber
2ae0f82c
SC
2923(define_split
2924 [(set (match_operand:HI 0 "register_operand" "")
e075ae69 2925 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 2926 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
2927 "reload_completed
2928 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
1a06f5fe 2929 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2
JH
2930 [(set (match_operand:HI 0 "register_operand" "")
2931 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2ae0f82c 2932
8f7661f2
JH
2933;; When source and destination does not overlap, clear destination
2934;; first and then do the movb
2ae0f82c
SC
2935(define_split
2936 [(set (match_operand:HI 0 "register_operand" "")
8f7661f2 2937 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 2938 (clobber (reg:CC FLAGS_REG))]
e075ae69 2939 "reload_completed
1a06f5fe 2940 && ANY_QI_REG_P (operands[0])
8f7661f2
JH
2941 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2942 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2943 [(set (match_dup 0) (const_int 0))
2944 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2945 "operands[2] = gen_lowpart (QImode, operands[0]);")
2ae0f82c 2946
8f7661f2 2947;; Rest is handled by single and.
2ae0f82c
SC
2948(define_split
2949 [(set (match_operand:HI 0 "register_operand" "")
e075ae69 2950 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
8bc527af 2951 (clobber (reg:CC FLAGS_REG))]
e075ae69 2952 "reload_completed
8f7661f2
JH
2953 && true_regnum (operands[0]) == true_regnum (operands[1])"
2954 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
8bc527af 2955 (clobber (reg:CC FLAGS_REG))])]
d626200a
JL
2956 "")
2957
8f7661f2
JH
2958(define_expand "zero_extendqisi2"
2959 [(parallel
2960 [(set (match_operand:SI 0 "register_operand" "")
2961 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 2962 (clobber (reg:CC FLAGS_REG))])]
e075ae69 2963 ""
8f7661f2
JH
2964 "")
2965
2966(define_insn "*zero_extendqisi2_and"
2967 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2968 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
8bc527af 2969 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
2970 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2971 "#"
6ef67412
JH
2972 [(set_attr "type" "alu1")
2973 (set_attr "mode" "SI")])
8f7661f2
JH
2974
2975(define_insn "*zero_extendqisi2_movzbw_and"
2976 [(set (match_operand:SI 0 "register_operand" "=r,r")
2977 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
8bc527af 2978 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
2979 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2980 "#"
6ef67412
JH
2981 [(set_attr "type" "imovx,alu1")
2982 (set_attr "mode" "SI")])
2ae0f82c 2983
8f7661f2
JH
2984(define_insn "*zero_extendqisi2_movzbw"
2985 [(set (match_operand:SI 0 "register_operand" "=r")
2986 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2987 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
0f40f9f7 2988 "movz{bl|x}\t{%1, %0|%0, %1}"
6ef67412
JH
2989 [(set_attr "type" "imovx")
2990 (set_attr "mode" "SI")])
8f7661f2
JH
2991
2992;; For the movzbl case strip only the clobber
2993(define_split
2994 [(set (match_operand:SI 0 "register_operand" "")
2995 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 2996 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
2997 "reload_completed
2998 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
1a06f5fe 2999 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2
JH
3000 [(set (match_dup 0)
3001 (zero_extend:SI (match_dup 1)))])
3002
3003;; When source and destination does not overlap, clear destination
3004;; first and then do the movb
2ae0f82c
SC
3005(define_split
3006 [(set (match_operand:SI 0 "register_operand" "")
e075ae69 3007 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 3008 (clobber (reg:CC FLAGS_REG))]
e075ae69 3009 "reload_completed
1a06f5fe
JH
3010 && ANY_QI_REG_P (operands[0])
3011 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
8f7661f2 3012 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
e075ae69 3013 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8f7661f2
JH
3014 [(set (match_dup 0) (const_int 0))
3015 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3016 "operands[2] = gen_lowpart (QImode, operands[0]);")
2ae0f82c 3017
8f7661f2 3018;; Rest is handled by single and.
2ae0f82c
SC
3019(define_split
3020 [(set (match_operand:SI 0 "register_operand" "")
e075ae69 3021 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
8bc527af 3022 (clobber (reg:CC FLAGS_REG))]
e075ae69 3023 "reload_completed
8f7661f2
JH
3024 && true_regnum (operands[0]) == true_regnum (operands[1])"
3025 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
8bc527af 3026 (clobber (reg:CC FLAGS_REG))])]
e075ae69 3027 "")
2ae0f82c 3028
e075ae69 3029;; %%% Kill me once multi-word ops are sane.
123bf9e3
JH
3030(define_expand "zero_extendsidi2"
3031 [(set (match_operand:DI 0 "register_operand" "=r")
3032 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3033 ""
3034 "if (!TARGET_64BIT)
3035 {
3036 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3037 DONE;
3038 }
3039 ")
3040
3041(define_insn "zero_extendsidi2_32"
ebe75517
JH
3042 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3043 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
8bc527af 3044 (clobber (reg:CC FLAGS_REG))]
ebe75517
JH
3045 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3046 "@
3047 #
3048 #
3049 #
3050 movd\t{%1, %0|%0, %1}
3051 movd\t{%1, %0|%0, %1}"
3052 [(set_attr "mode" "SI,SI,SI,DI,TI")
3053 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3054
3055(define_insn "*zero_extendsidi2_32_1"
3056 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3057 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
8bc527af 3058 (clobber (reg:CC FLAGS_REG))]
ebe75517
JH
3059 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3060 "@
3061 #
3062 #
3063 #
3064 movd\t{%1, %0|%0, %1}
3065 movd\t{%1, %0|%0, %1}"
3066 [(set_attr "mode" "SI,SI,SI,DI,TI")
3067 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
2ae0f82c 3068
123bf9e3 3069(define_insn "zero_extendsidi2_rex64"
ebe75517
JH
3070 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3071 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3072 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
123bf9e3 3073 "@
0f40f9f7 3074 mov\t{%k1, %k0|%k0, %k1}
ebe75517
JH
3075 #
3076 movd\t{%1, %0|%0, %1}
3077 movd\t{%1, %0|%0, %1}"
3078 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3079 (set_attr "mode" "SI,DI,DI,TI")])
3080
3081(define_insn "*zero_extendsidi2_rex64_1"
3082 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3083 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3084 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3085 "@
3086 mov\t{%k1, %k0|%k0, %k1}
3087 #
3088 movd\t{%1, %0|%0, %1}
3089 movd\t{%1, %0|%0, %1}"
3090 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3091 (set_attr "mode" "SI,DI,SI,SI")])
123bf9e3
JH
3092
3093(define_split
3094 [(set (match_operand:DI 0 "memory_operand" "")
3095 (zero_extend:DI (match_dup 0)))]
1b0c37d7 3096 "TARGET_64BIT"
123bf9e3
JH
3097 [(set (match_dup 4) (const_int 0))]
3098 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3099
bb62e19a
JH
3100(define_split
3101 [(set (match_operand:DI 0 "register_operand" "")
e075ae69 3102 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3103 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
3104 "!TARGET_64BIT && reload_completed
3105 && true_regnum (operands[0]) == true_regnum (operands[1])"
591702de 3106 [(set (match_dup 4) (const_int 0))]
bb62e19a
JH
3107 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3108
3109(define_split
3110 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69 3111 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
8bc527af 3112 (clobber (reg:CC FLAGS_REG))]
ebe75517
JH
3113 "!TARGET_64BIT && reload_completed
3114 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
bb62e19a 3115 [(set (match_dup 3) (match_dup 1))
591702de 3116 (set (match_dup 4) (const_int 0))]
bb62e19a 3117 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
123bf9e3
JH
3118
3119(define_insn "zero_extendhidi2"
3120 [(set (match_operand:DI 0 "register_operand" "=r,r")
3121 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3122 "TARGET_64BIT"
3123 "@
5a0855a0 3124 movz{wl|x}\t{%1, %k0|%k0, %1}
0f40f9f7 3125 movz{wq|x}\t{%1, %0|%0, %1}"
123bf9e3
JH
3126 [(set_attr "type" "imovx")
3127 (set_attr "mode" "SI,DI")])
3128
3129(define_insn "zero_extendqidi2"
3130 [(set (match_operand:DI 0 "register_operand" "=r,r")
3131 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3132 "TARGET_64BIT"
3133 "@
5a0855a0 3134 movz{bl|x}\t{%1, %k0|%k0, %1}
0f40f9f7 3135 movz{bq|x}\t{%1, %0|%0, %1}"
123bf9e3
JH
3136 [(set_attr "type" "imovx")
3137 (set_attr "mode" "SI,DI")])
886c62d1 3138\f
e075ae69 3139;; Sign extension instructions
886c62d1 3140
123bf9e3
JH
3141(define_expand "extendsidi2"
3142 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3143 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3144 (clobber (reg:CC FLAGS_REG))
123bf9e3
JH
3145 (clobber (match_scratch:SI 2 ""))])]
3146 ""
123bf9e3
JH
3147{
3148 if (TARGET_64BIT)
3149 {
3150 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3151 DONE;
3152 }
0f40f9f7 3153})
123bf9e3
JH
3154
3155(define_insn "*extendsidi2_1"
e075ae69
RH
3156 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3157 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
8bc527af 3158 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3159 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
123bf9e3 3160 "!TARGET_64BIT"
724d568a
JH
3161 "#")
3162
123bf9e3
JH
3163(define_insn "extendsidi2_rex64"
3164 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3165 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3166 "TARGET_64BIT"
3167 "@
3168 {cltq|cdqe}
0f40f9f7 3169 movs{lq|x}\t{%1,%0|%0, %1}"
123bf9e3
JH
3170 [(set_attr "type" "imovx")
3171 (set_attr "mode" "DI")
3172 (set_attr "prefix_0f" "0")
3173 (set_attr "modrm" "0,1")])
3174
3175(define_insn "extendhidi2"
3176 [(set (match_operand:DI 0 "register_operand" "=r")
3177 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3178 "TARGET_64BIT"
0f40f9f7 3179 "movs{wq|x}\t{%1,%0|%0, %1}"
123bf9e3
JH
3180 [(set_attr "type" "imovx")
3181 (set_attr "mode" "DI")])
3182
3183(define_insn "extendqidi2"
3184 [(set (match_operand:DI 0 "register_operand" "=r")
3185 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3186 "TARGET_64BIT"
0f40f9f7 3187 "movs{bq|x}\t{%1,%0|%0, %1}"
123bf9e3
JH
3188 [(set_attr "type" "imovx")
3189 (set_attr "mode" "DI")])
3190
724d568a
JH
3191;; Extend to memory case when source register does die.
3192(define_split
3193 [(set (match_operand:DI 0 "memory_operand" "")
3194 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3195 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3196 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 3197 "(reload_completed
724d568a
JH
3198 && dead_or_set_p (insn, operands[1])
3199 && !reg_mentioned_p (operands[1], operands[0]))"
3200 [(set (match_dup 3) (match_dup 1))
e075ae69 3201 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
8bc527af 3202 (clobber (reg:CC FLAGS_REG))])
724d568a
JH
3203 (set (match_dup 4) (match_dup 1))]
3204 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205
3206;; Extend to memory case when source register does not die.
3207(define_split
3208 [(set (match_operand:DI 0 "memory_operand" "")
3209 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3210 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3211 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 3212 "reload_completed"
724d568a 3213 [(const_int 0)]
9c530261 3214{
724d568a
JH
3215 split_di (&operands[0], 1, &operands[3], &operands[4]);
3216
3217 emit_move_insn (operands[3], operands[1]);
3218
3219 /* Generate a cltd if possible and doing so it profitable. */
3220 if (true_regnum (operands[1]) == 0
3221 && true_regnum (operands[2]) == 1
e075ae69 3222 && (optimize_size || TARGET_USE_CLTD))
71a247f0 3223 {
e075ae69 3224 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
724d568a
JH
3225 }
3226 else
3227 {
3228 emit_move_insn (operands[2], operands[1]);
e075ae69 3229 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
71a247f0 3230 }
724d568a
JH
3231 emit_move_insn (operands[4], operands[2]);
3232 DONE;
0f40f9f7 3233})
9c530261 3234
724d568a
JH
3235;; Extend to register case. Optimize case where source and destination
3236;; registers match and cases where we can use cltd.
3237(define_split
3238 [(set (match_operand:DI 0 "register_operand" "")
3239 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3240 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3241 (clobber (match_scratch:SI 2 ""))]
724d568a
JH
3242 "reload_completed"
3243 [(const_int 0)]
724d568a
JH
3244{
3245 split_di (&operands[0], 1, &operands[3], &operands[4]);
3246
3247 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3248 emit_move_insn (operands[3], operands[1]);
9c530261 3249
724d568a
JH
3250 /* Generate a cltd if possible and doing so it profitable. */
3251 if (true_regnum (operands[3]) == 0
e075ae69 3252 && (optimize_size || TARGET_USE_CLTD))
724d568a 3253 {
e075ae69 3254 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
724d568a
JH
3255 DONE;
3256 }
3257
3258 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3259 emit_move_insn (operands[4], operands[1]);
3260
e075ae69 3261 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
724d568a 3262 DONE;
0f40f9f7 3263})
886c62d1 3264
886c62d1 3265(define_insn "extendhisi2"
e075ae69
RH
3266 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3267 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
886c62d1 3268 ""
886c62d1 3269{
6ef67412 3270 switch (get_attr_prefix_0f (insn))
e075ae69 3271 {
6ef67412 3272 case 0:
0f40f9f7 3273 return "{cwtl|cwde}";
e075ae69 3274 default:
0f40f9f7 3275 return "movs{wl|x}\t{%1,%0|%0, %1}";
e075ae69 3276 }
0f40f9f7 3277}
e075ae69 3278 [(set_attr "type" "imovx")
6ef67412
JH
3279 (set_attr "mode" "SI")
3280 (set (attr "prefix_0f")
3281 ;; movsx is short decodable while cwtl is vector decoded.
3282 (if_then_else (and (eq_attr "cpu" "!k6")
3283 (eq_attr "alternative" "0"))
3284 (const_string "0")
3285 (const_string "1")))
3286 (set (attr "modrm")
3287 (if_then_else (eq_attr "prefix_0f" "0")
3288 (const_string "0")
3289 (const_string "1")))])
886c62d1 3290
123bf9e3
JH
3291(define_insn "*extendhisi2_zext"
3292 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3293 (zero_extend:DI
3294 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3295 "TARGET_64BIT"
123bf9e3
JH
3296{
3297 switch (get_attr_prefix_0f (insn))
3298 {
3299 case 0:
0f40f9f7 3300 return "{cwtl|cwde}";
123bf9e3 3301 default:
0f40f9f7 3302 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
123bf9e3 3303 }
0f40f9f7 3304}
123bf9e3
JH
3305 [(set_attr "type" "imovx")
3306 (set_attr "mode" "SI")
3307 (set (attr "prefix_0f")
3308 ;; movsx is short decodable while cwtl is vector decoded.
3309 (if_then_else (and (eq_attr "cpu" "!k6")
3310 (eq_attr "alternative" "0"))
3311 (const_string "0")
3312 (const_string "1")))
3313 (set (attr "modrm")
3314 (if_then_else (eq_attr "prefix_0f" "0")
3315 (const_string "0")
3316 (const_string "1")))])
3317
886c62d1 3318(define_insn "extendqihi2"
e075ae69
RH
3319 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3320 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
886c62d1 3321 ""
886c62d1 3322{
6ef67412 3323 switch (get_attr_prefix_0f (insn))
e075ae69 3324 {
6ef67412 3325 case 0:
0f40f9f7 3326 return "{cbtw|cbw}";
e075ae69 3327 default:
0f40f9f7 3328 return "movs{bw|x}\t{%1,%0|%0, %1}";
e075ae69 3329 }
0f40f9f7 3330}
e075ae69 3331 [(set_attr "type" "imovx")
6ef67412
JH
3332 (set_attr "mode" "HI")
3333 (set (attr "prefix_0f")
3334 ;; movsx is short decodable while cwtl is vector decoded.
3335 (if_then_else (and (eq_attr "cpu" "!k6")
3336 (eq_attr "alternative" "0"))
3337 (const_string "0")
3338 (const_string "1")))
3339 (set (attr "modrm")
3340 (if_then_else (eq_attr "prefix_0f" "0")
3341 (const_string "0")
3342 (const_string "1")))])
886c62d1
JVA
3343
3344(define_insn "extendqisi2"
2ae0f82c
SC
3345 [(set (match_operand:SI 0 "register_operand" "=r")
3346 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
886c62d1 3347 ""
0f40f9f7 3348 "movs{bl|x}\t{%1,%0|%0, %1}"
6ef67412
JH
3349 [(set_attr "type" "imovx")
3350 (set_attr "mode" "SI")])
123bf9e3
JH
3351
3352(define_insn "*extendqisi2_zext"
3353 [(set (match_operand:DI 0 "register_operand" "=r")
3354 (zero_extend:DI
3355 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3356 "TARGET_64BIT"
0f40f9f7 3357 "movs{bl|x}\t{%1,%k0|%k0, %1}"
123bf9e3
JH
3358 [(set_attr "type" "imovx")
3359 (set_attr "mode" "SI")])
886c62d1
JVA
3360\f
3361;; Conversions between float and double.
3362
e075ae69
RH
3363;; These are all no-ops in the model used for the 80387. So just
3364;; emit moves.
6a4a5d95 3365
e075ae69 3366;; %%% Kill these when call knows how to work out a DFmode push earlier.
6343a50e 3367(define_insn "*dummy_extendsfdf2"
e075ae69 3368 [(set (match_operand:DF 0 "push_operand" "=<")
42a0aa6f 3369 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
e075ae69
RH
3370 "0"
3371 "#")
6a4a5d95
JW
3372
3373(define_split
e075ae69 3374 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3
GS
3375 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3376 "!TARGET_64BIT"
8bc527af
SB
3377 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3378 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
0fcad513 3379
123bf9e3
JH
3380(define_split
3381 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3
GS
3382 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3383 "TARGET_64BIT"
8bc527af
SB
3384 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3385 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
123bf9e3 3386
6343a50e 3387(define_insn "*dummy_extendsfxf2"
e075ae69
RH
3388 [(set (match_operand:XF 0 "push_operand" "=<")
3389 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3390 "0"
3391 "#")
e4ad1003
JW
3392
3393(define_split
e075ae69 3394 [(set (match_operand:XF 0 "push_operand" "")
c3c637e3 3395 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
f8a1ebc6 3396 ""
8bc527af
SB
3397 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3398 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
f8a1ebc6 3399 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
123bf9e3
JH
3400
3401(define_split
f8a1ebc6
JH
3402 [(set (match_operand:XF 0 "push_operand" "")
3403 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
c3c637e3 3404 "TARGET_64BIT"
8bc527af
SB
3405 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3406 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
f8a1ebc6 3407 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
e4ad1003
JW
3408
3409(define_split
e075ae69 3410 [(set (match_operand:XF 0 "push_operand" "")
c3c637e3 3411 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
f8a1ebc6 3412 ""
8bc527af
SB
3413 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3414 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
f8a1ebc6 3415 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4fb21e90 3416
123bf9e3 3417(define_split
f8a1ebc6
JH
3418 [(set (match_operand:XF 0 "push_operand" "")
3419 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
c3c637e3 3420 "TARGET_64BIT"
8bc527af
SB
3421 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3422 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
f8a1ebc6 3423 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
123bf9e3 3424
f97d9ec3
JH
3425(define_expand "extendsfdf2"
3426 [(set (match_operand:DF 0 "nonimmediate_operand" "")
51286de6 3427 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
42a0aa6f 3428 "TARGET_80387 || TARGET_SSE2"
f97d9ec3 3429{
51286de6
RH
3430 /* ??? Needed for compress_float_constant since all fp constants
3431 are LEGITIMATE_CONSTANT_P. */
3432 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3433 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
f97d9ec3 3434 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 3435 operands[1] = force_reg (SFmode, operands[1]);
0f40f9f7 3436})
f97d9ec3
JH
3437
3438(define_insn "*extendsfdf2_1"
a811cc63
JH
3439 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3440 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
42a0aa6f 3441 "(TARGET_80387 || TARGET_SSE2)
f97d9ec3 3442 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4fb21e90 3443{
e075ae69 3444 switch (which_alternative)
4fb21e90 3445 {
e075ae69 3446 case 0:
5ea9cb6e 3447 return output_387_reg_move (insn, operands);
886c62d1 3448
e075ae69
RH
3449 case 1:
3450 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3451 return "fstp%z0\t%y0";
e075ae69 3452 else
0f40f9f7 3453 return "fst%z0\t%y0";
5ea9cb6e 3454
42a0aa6f 3455 case 2:
0f40f9f7 3456 return "cvtss2sd\t{%1, %0|%0, %1}";
4fb21e90 3457
e075ae69
RH
3458 default:
3459 abort ();
3460 }
0f40f9f7 3461}
3d34cd91 3462 [(set_attr "type" "fmov,fmov,ssecvt")
a811cc63 3463 (set_attr "mode" "SF,XF,DF")])
42a0aa6f
JH
3464
3465(define_insn "*extendsfdf2_1_sse_only"
3466 [(set (match_operand:DF 0 "register_operand" "=Y")
3467 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3468 "!TARGET_80387 && TARGET_SSE2
3469 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 3470 "cvtss2sd\t{%1, %0|%0, %1}"
3d34cd91 3471 [(set_attr "type" "ssecvt")
42a0aa6f 3472 (set_attr "mode" "DF")])
e075ae69 3473
f97d9ec3
JH
3474(define_expand "extendsfxf2"
3475 [(set (match_operand:XF 0 "nonimmediate_operand" "")
51286de6 3476 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
f8a1ebc6 3477 "TARGET_80387"
f97d9ec3 3478{
51286de6
RH
3479 /* ??? Needed for compress_float_constant since all fp constants
3480 are LEGITIMATE_CONSTANT_P. */
3481 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3482 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
f97d9ec3 3483 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 3484 operands[1] = force_reg (SFmode, operands[1]);
0f40f9f7 3485})
f97d9ec3
JH
3486
3487(define_insn "*extendsfxf2_1"
e075ae69
RH
3488 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3489 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2b589241
JH
3490 "TARGET_80387
3491 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2b589241
JH
3492{
3493 switch (which_alternative)
3494 {
3495 case 0:
5ea9cb6e 3496 return output_387_reg_move (insn, operands);
2b589241
JH
3497
3498 case 1:
3499 /* There is no non-popping store to memory for XFmode. So if
3500 we need one, follow the store with a load. */
3501 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3502 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
2b589241 3503 else
0f40f9f7 3504 return "fstp%z0\t%y0";
2b589241
JH
3505
3506 default:
3507 abort ();
3508 }
0f40f9f7 3509}
2b589241
JH
3510 [(set_attr "type" "fmov")
3511 (set_attr "mode" "SF,XF")])
3512
f97d9ec3
JH
3513(define_expand "extenddfxf2"
3514 [(set (match_operand:XF 0 "nonimmediate_operand" "")
51286de6 3515 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
f8a1ebc6 3516 "TARGET_80387"
f97d9ec3 3517{
51286de6
RH
3518 /* ??? Needed for compress_float_constant since all fp constants
3519 are LEGITIMATE_CONSTANT_P. */
3520 if (GET_CODE (operands[1]) == CONST_DOUBLE)
110b3faa 3521 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
f97d9ec3 3522 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 3523 operands[1] = force_reg (DFmode, operands[1]);
0f40f9f7 3524})
f97d9ec3
JH
3525
3526(define_insn "*extenddfxf2_1"
e075ae69
RH
3527 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3528 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
2b589241
JH
3529 "TARGET_80387
3530 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2b589241
JH
3531{
3532 switch (which_alternative)
3533 {
3534 case 0:
5ea9cb6e 3535 return output_387_reg_move (insn, operands);
2b589241
JH
3536
3537 case 1:
3538 /* There is no non-popping store to memory for XFmode. So if
3539 we need one, follow the store with a load. */
3540 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3541 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
2b589241 3542 else
0f40f9f7 3543 return "fstp%z0\t%y0";
2b589241
JH
3544
3545 default:
3546 abort ();
3547 }
0f40f9f7 3548}
2b589241
JH
3549 [(set_attr "type" "fmov")
3550 (set_attr "mode" "DF,XF")])
3551
e075ae69
RH
3552;; %%% This seems bad bad news.
3553;; This cannot output into an f-reg because there is no way to be sure
3554;; of truncating in that case. Otherwise this is just like a simple move
3555;; insn. So we pretend we can output to a reg in order to get better
3556;; register preferencing, but we really use a stack slot.
886c62d1 3557
e075ae69
RH
3558(define_expand "truncdfsf2"
3559 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3560 (float_truncate:SF
3561 (match_operand:DF 1 "register_operand" "")))
3562 (clobber (match_dup 2))])]
42a0aa6f
JH
3563 "TARGET_80387 || TARGET_SSE2"
3564 "
0c5faf29 3565 if (!TARGET_80387)
42a0aa6f
JH
3566 {
3567 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3568 DONE;
3569 }
0c5faf29
RS
3570 else if (flag_unsafe_math_optimizations)
3571 {
3572 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3573 emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3574 if (reg != operands[0])
3575 emit_move_insn (operands[0], reg);
3576 DONE;
3577 }
3578 else
3579 operands[2] = assign_386_stack_local (SFmode, 0);
42a0aa6f 3580")
bc725565 3581
0c5faf29
RS
3582(define_insn "truncdfsf2_noop"
3583 [(set (match_operand:SF 0 "register_operand" "=f")
3584 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3585 "TARGET_80387 && flag_unsafe_math_optimizations"
82a6a758 3586{
5ea9cb6e 3587 return output_387_reg_move (insn, operands);
82a6a758
RS
3588}
3589 [(set_attr "type" "fmov")
3590 (set_attr "mode" "SF")])
0c5faf29 3591
e075ae69 3592(define_insn "*truncdfsf2_1"
46ed7963 3593 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
e075ae69 3594 (float_truncate:SF
46ed7963
JH
3595 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3596 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
42a0aa6f 3597 "TARGET_80387 && !TARGET_SSE2"
e075ae69
RH
3598{
3599 switch (which_alternative)
3600 {
3601 case 0:
3602 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3603 return "fstp%z0\t%y0";
e075ae69 3604 else
0f40f9f7 3605 return "fst%z0\t%y0";
46ed7963
JH
3606 default:
3607 abort ();
e075ae69 3608 }
0f40f9f7 3609}
46ed7963
JH
3610 [(set_attr "type" "fmov,multi,multi,multi")
3611 (set_attr "mode" "SF,SF,SF,SF")])
42a0aa6f
JH
3612
3613(define_insn "*truncdfsf2_1_sse"
4977bab6 3614 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
42a0aa6f 3615 (float_truncate:SF
4977bab6 3616 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
46ed7963 3617 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
4977bab6 3618 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
42a0aa6f
JH
3619{
3620 switch (which_alternative)
3621 {
3622 case 0:
3623 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3624 return "fstp%z0\t%y0";
42a0aa6f 3625 else
0f40f9f7 3626 return "fst%z0\t%y0";
46ed7963 3627 case 4:
4977bab6
ZW
3628 return "#";
3629 default:
3630 abort ();
3631 }
3632}
3633 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3634 (set_attr "mode" "SF,SF,SF,SF,DF")])
3635
3636(define_insn "*truncdfsf2_1_sse_nooverlap"
3637 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3638 (float_truncate:SF
3639 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3640 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3641 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3642{
3643 switch (which_alternative)
3644 {
3645 case 0:
3646 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3647 return "fstp%z0\t%y0";
3648 else
3649 return "fst%z0\t%y0";
3650 case 4:
3651 return "#";
46ed7963
JH
3652 default:
3653 abort ();
42a0aa6f 3654 }
0f40f9f7 3655}
3d34cd91 3656 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
46ed7963 3657 (set_attr "mode" "SF,SF,SF,SF,DF")])
53b5ce19 3658
e075ae69 3659(define_insn "*truncdfsf2_2"
f56e86bd 3660 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
42a0aa6f 3661 (float_truncate:SF
f56e86bd 3662 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
4977bab6 3663 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
79005df5 3664 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
42a0aa6f
JH
3665{
3666 switch (which_alternative)
3667 {
3668 case 0:
79005df5 3669 case 1:
f56e86bd
JH
3670 return "cvtsd2ss\t{%1, %0|%0, %1}";
3671 case 2:
42a0aa6f 3672 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3673 return "fstp%z0\t%y0";
42a0aa6f 3674 else
0f40f9f7
ZW
3675 return "fst%z0\t%y0";
3676 default:
3677 abort ();
42a0aa6f 3678 }
0f40f9f7 3679}
f56e86bd
JH
3680 [(set_attr "type" "ssecvt,ssecvt,fmov")
3681 (set_attr "athlon_decode" "vector,double,*")
26f74aa3 3682 (set_attr "mode" "SF,SF,SF")])
42a0aa6f 3683
4977bab6
ZW
3684(define_insn "*truncdfsf2_2_nooverlap"
3685 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3686 (float_truncate:SF
3687 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3688 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3689 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3690{
3691 switch (which_alternative)
3692 {
3693 case 0:
3694 return "#";
3695 case 1:
3696 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697 return "fstp%z0\t%y0";
3698 else
3699 return "fst%z0\t%y0";
3700 default:
3701 abort ();
3702 }
3703}
3704 [(set_attr "type" "ssecvt,fmov")
3705 (set_attr "mode" "DF,SF")])
3706
3707(define_insn "*truncdfsf2_3"
cc2e591b 3708 [(set (match_operand:SF 0 "memory_operand" "=m")
e075ae69
RH
3709 (float_truncate:SF
3710 (match_operand:DF 1 "register_operand" "f")))]
53b5ce19 3711 "TARGET_80387"
e075ae69
RH
3712{
3713 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3714 return "fstp%z0\t%y0";
e075ae69 3715 else
0f40f9f7
ZW
3716 return "fst%z0\t%y0";
3717}
6ef67412
JH
3718 [(set_attr "type" "fmov")
3719 (set_attr "mode" "SF")])
53b5ce19 3720
42a0aa6f 3721(define_insn "truncdfsf2_sse_only"
f56e86bd 3722 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
42a0aa6f 3723 (float_truncate:SF
f56e86bd 3724 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
4977bab6 3725 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
0f40f9f7 3726 "cvtsd2ss\t{%1, %0|%0, %1}"
3d34cd91 3727 [(set_attr "type" "ssecvt")
f56e86bd 3728 (set_attr "athlon_decode" "vector,double")
26f74aa3 3729 (set_attr "mode" "SF")])
42a0aa6f 3730
4977bab6
ZW
3731(define_insn "*truncdfsf2_sse_only_nooverlap"
3732 [(set (match_operand:SF 0 "register_operand" "=&Y")
3733 (float_truncate:SF
3734 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3735 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3736 "#"
3737 [(set_attr "type" "ssecvt")
3738 (set_attr "mode" "DF")])
3739
53b5ce19 3740(define_split
e075ae69
RH
3741 [(set (match_operand:SF 0 "memory_operand" "")
3742 (float_truncate:SF
3743 (match_operand:DF 1 "register_operand" "")))
3744 (clobber (match_operand:SF 2 "memory_operand" ""))]
3745 "TARGET_80387"
3746 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
53b5ce19
JW
3747 "")
3748
d1f87653 3749; Avoid possible reformatting penalty on the destination by first
4977bab6 3750; zeroing it out
42a0aa6f 3751(define_split
4977bab6 3752 [(set (match_operand:SF 0 "register_operand" "")
42a0aa6f
JH
3753 (float_truncate:SF
3754 (match_operand:DF 1 "nonimmediate_operand" "")))
3755 (clobber (match_operand 2 "" ""))]
05b432db 3756 "TARGET_80387 && reload_completed
4977bab6
ZW
3757 && SSE_REG_P (operands[0])
3758 && !STACK_REG_P (operands[1])"
3759 [(const_int 0)]
3760{
3761 rtx src, dest;
3762 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3763 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3764 else
3765 {
3766 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3767 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3768 /* simplify_gen_subreg refuses to widen memory references. */
3769 if (GET_CODE (src) == SUBREG)
3770 alter_subreg (&src);
3771 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3772 abort ();
3773 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3774 emit_insn (gen_cvtsd2ss (dest, dest, src));
3775 }
3776 DONE;
3777})
3778
3779(define_split
3780 [(set (match_operand:SF 0 "register_operand" "")
3781 (float_truncate:SF
3782 (match_operand:DF 1 "nonimmediate_operand" "")))]
3783 "TARGET_80387 && reload_completed
3784 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3785 [(const_int 0)]
3786{
3787 rtx src, dest;
3788 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3789 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3790 /* simplify_gen_subreg refuses to widen memory references. */
3791 if (GET_CODE (src) == SUBREG)
3792 alter_subreg (&src);
3793 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3794 abort ();
3795 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3796 emit_insn (gen_cvtsd2ss (dest, dest, src));
3797 DONE;
3798})
42a0aa6f 3799
53b5ce19
JW
3800(define_split
3801 [(set (match_operand:SF 0 "register_operand" "")
e075ae69 3802 (float_truncate:SF
c3c637e3 3803 (match_operand:DF 1 "fp_register_operand" "")))
e075ae69 3804 (clobber (match_operand:SF 2 "memory_operand" ""))]
c3c637e3 3805 "TARGET_80387 && reload_completed"
e075ae69
RH
3806 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3807 (set (match_dup 0) (match_dup 2))]
53b5ce19
JW
3808 "")
3809
e075ae69
RH
3810(define_expand "truncxfsf2"
3811 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3812 (float_truncate:SF
3813 (match_operand:XF 1 "register_operand" "")))
3814 (clobber (match_dup 2))])]
f8a1ebc6 3815 "TARGET_80387"
0c5faf29
RS
3816 "
3817 if (flag_unsafe_math_optimizations)
3818 {
3819 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3820 emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3821 if (reg != operands[0])
3822 emit_move_insn (operands[0], reg);
3823 DONE;
3824 }
3825 else
3826 operands[2] = assign_386_stack_local (SFmode, 0);
3827 ")
3828
3829(define_insn "truncxfsf2_noop"
3830 [(set (match_operand:SF 0 "register_operand" "=f")
3831 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3832 "TARGET_80387 && flag_unsafe_math_optimizations"
82a6a758 3833{
5ea9cb6e 3834 return output_387_reg_move (insn, operands);
82a6a758
RS
3835}
3836 [(set_attr "type" "fmov")
3837 (set_attr "mode" "SF")])
53b5ce19 3838
e075ae69 3839(define_insn "*truncxfsf2_1"
46ed7963 3840 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
e075ae69 3841 (float_truncate:SF
46ed7963
JH
3842 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
f8a1ebc6 3844 "TARGET_80387"
e075ae69
RH
3845{
3846 switch (which_alternative)
3847 {
3848 case 0:
3849 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3850 return "fstp%z0\t%y0";
e075ae69 3851 else
0f40f9f7 3852 return "fst%z0\t%y0";
46ed7963
JH
3853 default:
3854 abort();
e075ae69 3855 }
0f40f9f7 3856}
46ed7963 3857 [(set_attr "type" "fmov,multi,multi,multi")
6ef67412 3858 (set_attr "mode" "SF")])
886c62d1 3859
e075ae69 3860(define_insn "*truncxfsf2_2"
dd80b906 3861 [(set (match_operand:SF 0 "memory_operand" "=m")
e075ae69
RH
3862 (float_truncate:SF
3863 (match_operand:XF 1 "register_operand" "f")))]
f8a1ebc6 3864 "TARGET_80387"
e075ae69
RH
3865{
3866 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3867 return "fstp%z0\t%y0";
e075ae69 3868 else
0f40f9f7
ZW
3869 return "fst%z0\t%y0";
3870}
6ef67412
JH
3871 [(set_attr "type" "fmov")
3872 (set_attr "mode" "SF")])
bc725565
JW
3873
3874(define_split
e075ae69
RH
3875 [(set (match_operand:SF 0 "memory_operand" "")
3876 (float_truncate:SF
3877 (match_operand:XF 1 "register_operand" "")))
3878 (clobber (match_operand:SF 2 "memory_operand" ""))]
3879 "TARGET_80387"
3880 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
886c62d1
JVA
3881 "")
3882
bc725565 3883(define_split
6a4a5d95 3884 [(set (match_operand:SF 0 "register_operand" "")
e075ae69
RH
3885 (float_truncate:SF
3886 (match_operand:XF 1 "register_operand" "")))
3887 (clobber (match_operand:SF 2 "memory_operand" ""))]
bc725565 3888 "TARGET_80387 && reload_completed"
e075ae69
RH
3889 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3890 (set (match_dup 0) (match_dup 2))]
886c62d1
JVA
3891 "")
3892
e075ae69
RH
3893(define_expand "truncxfdf2"
3894 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3895 (float_truncate:DF
3896 (match_operand:XF 1 "register_operand" "")))
3897 (clobber (match_dup 2))])]
f8a1ebc6 3898 "TARGET_80387"
0c5faf29
RS
3899 "
3900 if (flag_unsafe_math_optimizations)
3901 {
3902 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3903 emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3904 if (reg != operands[0])
3905 emit_move_insn (operands[0], reg);
3906 DONE;
3907 }
3908 else
3909 operands[2] = assign_386_stack_local (DFmode, 0);
3910 ")
3911
3912(define_insn "truncxfdf2_noop"
3913 [(set (match_operand:DF 0 "register_operand" "=f")
3914 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3915 "TARGET_80387 && flag_unsafe_math_optimizations"
82a6a758 3916{
5ea9cb6e 3917 return output_387_reg_move (insn, operands);
82a6a758
RS
3918}
3919 [(set_attr "type" "fmov")
3920 (set_attr "mode" "DF")])
bc725565 3921
e075ae69 3922(define_insn "*truncxfdf2_1"
46ed7963 3923 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
e075ae69 3924 (float_truncate:DF
46ed7963
JH
3925 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3926 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
f8a1ebc6 3927 "TARGET_80387"
e075ae69
RH
3928{
3929 switch (which_alternative)
3930 {
3931 case 0:
3932 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3933 return "fstp%z0\t%y0";
e075ae69 3934 else
0f40f9f7 3935 return "fst%z0\t%y0";
46ed7963
JH
3936 default:
3937 abort();
e075ae69
RH
3938 }
3939 abort ();
0f40f9f7 3940}
46ed7963 3941 [(set_attr "type" "fmov,multi,multi,multi")
6ef67412 3942 (set_attr "mode" "DF")])
bc725565 3943
e075ae69
RH
3944(define_insn "*truncxfdf2_2"
3945 [(set (match_operand:DF 0 "memory_operand" "=m")
3946 (float_truncate:DF
3947 (match_operand:XF 1 "register_operand" "f")))]
f8a1ebc6 3948 "TARGET_80387"
e075ae69
RH
3949{
3950 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3951 return "fstp%z0\t%y0";
e075ae69 3952 else
0f40f9f7
ZW
3953 return "fst%z0\t%y0";
3954}
6ef67412
JH
3955 [(set_attr "type" "fmov")
3956 (set_attr "mode" "DF")])
bc725565
JW
3957
3958(define_split
e075ae69
RH
3959 [(set (match_operand:DF 0 "memory_operand" "")
3960 (float_truncate:DF
3961 (match_operand:XF 1 "register_operand" "")))
3962 (clobber (match_operand:DF 2 "memory_operand" ""))]
ca285e07
JH
3963 "TARGET_80387"
3964 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4fb21e90
JVA
3965 "")
3966
bc725565 3967(define_split
6a4a5d95 3968 [(set (match_operand:DF 0 "register_operand" "")
e075ae69
RH
3969 (float_truncate:DF
3970 (match_operand:XF 1 "register_operand" "")))
3971 (clobber (match_operand:DF 2 "memory_operand" ""))]
bc725565 3972 "TARGET_80387 && reload_completed"
ca285e07 3973 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
e075ae69 3974 (set (match_dup 0) (match_dup 2))]
4fb21e90 3975 "")
ca285e07 3976
e075ae69
RH
3977\f
3978;; %%% Break up all these bad boys.
4fb21e90 3979
e075ae69
RH
3980;; Signed conversion to DImode.
3981
2b589241 3982(define_expand "fix_truncxfdi2"
ec13ba83
CT
3983 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3984 (fix:DI (match_operand:XF 1 "register_operand" "")))
8bc527af 3985 (clobber (reg:CC FLAGS_REG))])]
bc725565 3986 "TARGET_80387"
22fb740d 3987 "")
bc725565 3988
e075ae69 3989(define_expand "fix_truncdfdi2"
ec13ba83
CT
3990 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3991 (fix:DI (match_operand:DF 1 "register_operand" "")))
8bc527af 3992 (clobber (reg:CC FLAGS_REG))])]
46ed7963 3993 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
46ed7963 3994{
1b0c37d7 3995 if (TARGET_64BIT && TARGET_SSE2)
46ed7963
JH
3996 {
3997 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3998 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
3999 if (out != operands[0])
4000 emit_move_insn (operands[0], out);
4001 DONE;
4002 }
0f40f9f7 4003})
53b5ce19 4004
e075ae69 4005(define_expand "fix_truncsfdi2"
ec13ba83
CT
4006 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4007 (fix:DI (match_operand:SF 1 "register_operand" "")))
8bc527af 4008 (clobber (reg:CC FLAGS_REG))])]
46ed7963 4009 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
46ed7963 4010{
22fb740d 4011 if (TARGET_SSE && TARGET_64BIT)
46ed7963
JH
4012 {
4013 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4014 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4015 if (out != operands[0])
4016 emit_move_insn (operands[0], out);
4017 DONE;
4018 }
0f40f9f7 4019})
e075ae69 4020
22fb740d
JH
4021;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4022;; of the machinery.
4023(define_insn_and_split "*fix_truncdi_1"
4024 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
ec13ba83 4025 (fix:DI (match_operand 1 "register_operand" "f,f")))
8bc527af 4026 (clobber (reg:CC FLAGS_REG))]
22fb740d
JH
4027 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4028 && !reload_completed && !reload_in_progress
4029 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4030 "#"
14f73b5a 4031 "&& 1"
22fb740d
JH
4032 [(const_int 0)]
4033{
fa1a0d02 4034 ix86_optimize_mode_switching = 1;
22fb740d
JH
4035 operands[2] = assign_386_stack_local (HImode, 1);
4036 operands[3] = assign_386_stack_local (HImode, 2);
4037 if (memory_operand (operands[0], VOIDmode))
4038 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4039 operands[2], operands[3]));
4040 else
4041 {
4042 operands[4] = assign_386_stack_local (DImode, 0);
4043 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4044 operands[2], operands[3],
4045 operands[4]));
4046 }
4047 DONE;
4048}
26f74aa3 4049 [(set_attr "type" "fistp")
edeacc14 4050 (set_attr "i387_cw" "trunc")
26f74aa3 4051 (set_attr "mode" "DI")])
22fb740d
JH
4052
4053(define_insn "fix_truncdi_nomemory"
c76aab11 4054 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
e075ae69 4055 (fix:DI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
4056 (use (match_operand:HI 2 "memory_operand" "m,m"))
4057 (use (match_operand:HI 3 "memory_operand" "m,m"))
4058 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
22fb740d 4059 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
46ed7963 4060 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
22fb740d
JH
4061 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4062 "#"
26f74aa3 4063 [(set_attr "type" "fistp")
edeacc14 4064 (set_attr "i387_cw" "trunc")
26f74aa3 4065 (set_attr "mode" "DI")])
22fb740d
JH
4066
4067(define_insn "fix_truncdi_memory"
4068 [(set (match_operand:DI 0 "memory_operand" "=m")
4069 (fix:DI (match_operand 1 "register_operand" "f")))
4070 (use (match_operand:HI 2 "memory_operand" "m"))
4071 (use (match_operand:HI 3 "memory_operand" "m"))
4072 (clobber (match_scratch:DF 4 "=&1f"))]
4073 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4074 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
869d095e 4075 "* return output_fix_trunc (insn, operands);"
26f74aa3 4076 [(set_attr "type" "fistp")
edeacc14 4077 (set_attr "i387_cw" "trunc")
26f74aa3 4078 (set_attr "mode" "DI")])
53b5ce19 4079
e075ae69
RH
4080(define_split
4081 [(set (match_operand:DI 0 "register_operand" "")
4082 (fix:DI (match_operand 1 "register_operand" "")))
7a2e09f4
JH
4083 (use (match_operand:HI 2 "memory_operand" ""))
4084 (use (match_operand:HI 3 "memory_operand" ""))
4085 (clobber (match_operand:DI 4 "memory_operand" ""))
a05924f9 4086 (clobber (match_scratch 5 ""))]
7a2e09f4
JH
4087 "reload_completed"
4088 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4089 (use (match_dup 2))
4090 (use (match_dup 3))
e075ae69 4091 (clobber (match_dup 5))])
7a2e09f4 4092 (set (match_dup 0) (match_dup 4))]
53b5ce19
JW
4093 "")
4094
22fb740d
JH
4095(define_split
4096 [(set (match_operand:DI 0 "memory_operand" "")
4097 (fix:DI (match_operand 1 "register_operand" "")))
4098 (use (match_operand:HI 2 "memory_operand" ""))
4099 (use (match_operand:HI 3 "memory_operand" ""))
4100 (clobber (match_operand:DI 4 "memory_operand" ""))
4101 (clobber (match_scratch 5 ""))]
4102 "reload_completed"
4103 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4104 (use (match_dup 2))
4105 (use (match_dup 3))
4106 (clobber (match_dup 5))])]
4107 "")
4108
46ed7963
JH
4109;; When SSE available, it is always faster to use it!
4110(define_insn "fix_truncsfdi_sse"
f56e86bd
JH
4111 [(set (match_operand:DI 0 "register_operand" "=r,r")
4112 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
1b0c37d7 4113 "TARGET_64BIT && TARGET_SSE"
0f40f9f7 4114 "cvttss2si{q}\t{%1, %0|%0, %1}"
f56e86bd 4115 [(set_attr "type" "sseicvt")
26f74aa3 4116 (set_attr "mode" "SF")
f56e86bd 4117 (set_attr "athlon_decode" "double,vector")])
46ed7963 4118
8dfa3bb0
JH
4119;; Avoid vector decoded form of the instruction.
4120(define_peephole2
4121 [(match_scratch:SF 2 "x")
4122 (set (match_operand:DI 0 "register_operand" "")
4123 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4124 "TARGET_K8 && !optimize_size"
4125 [(set (match_dup 2) (match_dup 1))
4126 (set (match_dup 0) (fix:DI (match_dup 2)))]
4127 "")
4128
46ed7963 4129(define_insn "fix_truncdfdi_sse"
f56e86bd
JH
4130 [(set (match_operand:DI 0 "register_operand" "=r,r")
4131 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
1b0c37d7 4132 "TARGET_64BIT && TARGET_SSE2"
0f40f9f7 4133 "cvttsd2si{q}\t{%1, %0|%0, %1}"
f56e86bd 4134 [(set_attr "type" "sseicvt,sseicvt")
26f74aa3 4135 (set_attr "mode" "DF")
f56e86bd 4136 (set_attr "athlon_decode" "double,vector")])
46ed7963 4137
8dfa3bb0
JH
4138;; Avoid vector decoded form of the instruction.
4139(define_peephole2
4140 [(match_scratch:DF 2 "Y")
4141 (set (match_operand:DI 0 "register_operand" "")
4142 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4143 "TARGET_K8 && !optimize_size"
4144 [(set (match_dup 2) (match_dup 1))
4145 (set (match_dup 0) (fix:DI (match_dup 2)))]
4146 "")
4147
e075ae69 4148;; Signed conversion to SImode.
53b5ce19 4149
e075ae69 4150(define_expand "fix_truncxfsi2"
ec13ba83
CT
4151 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4152 (fix:SI (match_operand:XF 1 "register_operand" "")))
8bc527af 4153 (clobber (reg:CC FLAGS_REG))])]
2b589241 4154 "TARGET_80387"
22fb740d 4155 "")
2b589241 4156
e075ae69 4157(define_expand "fix_truncdfsi2"
ec13ba83
CT
4158 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159 (fix:SI (match_operand:DF 1 "register_operand" "")))
8bc527af 4160 (clobber (reg:CC FLAGS_REG))])]
42a0aa6f 4161 "TARGET_80387 || TARGET_SSE2"
42a0aa6f
JH
4162{
4163 if (TARGET_SSE2)
4164 {
ca9a9b12 4165 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
b1675dbd
JH
4166 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4167 if (out != operands[0])
4168 emit_move_insn (operands[0], out);
42a0aa6f
JH
4169 DONE;
4170 }
0f40f9f7 4171})
886c62d1 4172
e075ae69 4173(define_expand "fix_truncsfsi2"
ec13ba83
CT
4174 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4175 (fix:SI (match_operand:SF 1 "register_operand" "")))
8bc527af 4176 (clobber (reg:CC FLAGS_REG))])]
42a0aa6f 4177 "TARGET_80387 || TARGET_SSE"
42a0aa6f 4178{
22fb740d 4179 if (TARGET_SSE)
42a0aa6f 4180 {
ca9a9b12 4181 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
46ed7963 4182 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
b1675dbd
JH
4183 if (out != operands[0])
4184 emit_move_insn (operands[0], out);
42a0aa6f
JH
4185 DONE;
4186 }
0f40f9f7 4187})
e075ae69 4188
22fb740d
JH
4189;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4190;; of the machinery.
4191(define_insn_and_split "*fix_truncsi_1"
4192 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
ec13ba83 4193 (fix:SI (match_operand 1 "register_operand" "f,f")))
8bc527af 4194 (clobber (reg:CC FLAGS_REG))]
22fb740d
JH
4195 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4196 && !reload_completed && !reload_in_progress
4197 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4198 "#"
ab75d1f1 4199 "&& 1"
22fb740d
JH
4200 [(const_int 0)]
4201{
fa1a0d02 4202 ix86_optimize_mode_switching = 1;
22fb740d
JH
4203 operands[2] = assign_386_stack_local (HImode, 1);
4204 operands[3] = assign_386_stack_local (HImode, 2);
4205 if (memory_operand (operands[0], VOIDmode))
4206 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4207 operands[2], operands[3]));
4208 else
4209 {
4210 operands[4] = assign_386_stack_local (SImode, 0);
4211 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4212 operands[2], operands[3],
4213 operands[4]));
4214 }
4215 DONE;
4216}
26f74aa3 4217 [(set_attr "type" "fistp")
edeacc14 4218 (set_attr "i387_cw" "trunc")
26f74aa3 4219 (set_attr "mode" "SI")])
22fb740d
JH
4220
4221(define_insn "fix_truncsi_nomemory"
c76aab11 4222 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
e075ae69 4223 (fix:SI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
4224 (use (match_operand:HI 2 "memory_operand" "m,m"))
4225 (use (match_operand:HI 3 "memory_operand" "m,m"))
4226 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
42a0aa6f 4227 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
22fb740d
JH
4228 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4229 "#"
26f74aa3 4230 [(set_attr "type" "fistp")
edeacc14 4231 (set_attr "i387_cw" "trunc")
26f74aa3 4232 (set_attr "mode" "SI")])
22fb740d
JH
4233
4234(define_insn "fix_truncsi_memory"
4235 [(set (match_operand:SI 0 "memory_operand" "=m")
4236 (fix:SI (match_operand 1 "register_operand" "f")))
4237 (use (match_operand:HI 2 "memory_operand" "m"))
4238 (use (match_operand:HI 3 "memory_operand" "m"))]
4239 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4240 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
e075ae69 4241 "* return output_fix_trunc (insn, operands);"
26f74aa3 4242 [(set_attr "type" "fistp")
edeacc14 4243 (set_attr "i387_cw" "trunc")
26f74aa3 4244 (set_attr "mode" "SI")])
bc725565 4245
42a0aa6f
JH
4246;; When SSE available, it is always faster to use it!
4247(define_insn "fix_truncsfsi_sse"
f56e86bd
JH
4248 [(set (match_operand:SI 0 "register_operand" "=r,r")
4249 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
42a0aa6f 4250 "TARGET_SSE"
0f40f9f7 4251 "cvttss2si\t{%1, %0|%0, %1}"
f56e86bd 4252 [(set_attr "type" "sseicvt")
26f74aa3 4253 (set_attr "mode" "DF")
f56e86bd 4254 (set_attr "athlon_decode" "double,vector")])
42a0aa6f 4255
8dfa3bb0
JH
4256;; Avoid vector decoded form of the instruction.
4257(define_peephole2
4258 [(match_scratch:SF 2 "x")
4259 (set (match_operand:SI 0 "register_operand" "")
4260 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4261 "TARGET_K8 && !optimize_size"
4262 [(set (match_dup 2) (match_dup 1))
4263 (set (match_dup 0) (fix:SI (match_dup 2)))]
4264 "")
4265
42a0aa6f 4266(define_insn "fix_truncdfsi_sse"
f56e86bd
JH
4267 [(set (match_operand:SI 0 "register_operand" "=r,r")
4268 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
42a0aa6f 4269 "TARGET_SSE2"
0f40f9f7 4270 "cvttsd2si\t{%1, %0|%0, %1}"
f56e86bd 4271 [(set_attr "type" "sseicvt")
26f74aa3 4272 (set_attr "mode" "DF")
f56e86bd 4273 (set_attr "athlon_decode" "double,vector")])
42a0aa6f 4274
18d13f34 4275;; Avoid vector decoded form of the instruction.
8dfa3bb0
JH
4276(define_peephole2
4277 [(match_scratch:DF 2 "Y")
4278 (set (match_operand:SI 0 "register_operand" "")
4279 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4280 "TARGET_K8 && !optimize_size"
4281 [(set (match_dup 2) (match_dup 1))
4282 (set (match_dup 0) (fix:SI (match_dup 2)))]
4283 "")
4284
e075ae69
RH
4285(define_split
4286 [(set (match_operand:SI 0 "register_operand" "")
4287 (fix:SI (match_operand 1 "register_operand" "")))
7a2e09f4
JH
4288 (use (match_operand:HI 2 "memory_operand" ""))
4289 (use (match_operand:HI 3 "memory_operand" ""))
4290 (clobber (match_operand:SI 4 "memory_operand" ""))]
e075ae69 4291 "reload_completed"
7a2e09f4
JH
4292 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4293 (use (match_dup 2))
22fb740d 4294 (use (match_dup 3))])
7a2e09f4 4295 (set (match_dup 0) (match_dup 4))]
bc725565 4296 "")
4fb21e90 4297
22fb740d
JH
4298(define_split
4299 [(set (match_operand:SI 0 "memory_operand" "")
4300 (fix:SI (match_operand 1 "register_operand" "")))
4301 (use (match_operand:HI 2 "memory_operand" ""))
4302 (use (match_operand:HI 3 "memory_operand" ""))
4303 (clobber (match_operand:SI 4 "memory_operand" ""))]
4304 "reload_completed"
4305 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4306 (use (match_dup 2))
4307 (use (match_dup 3))])]
4308 "")
4309
46d21d2c
JW
4310;; Signed conversion to HImode.
4311
4312(define_expand "fix_truncxfhi2"
ec13ba83
CT
4313 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4314 (fix:HI (match_operand:XF 1 "register_operand" "")))
8bc527af 4315 (clobber (reg:CC FLAGS_REG))])]
2b589241 4316 "TARGET_80387"
22fb740d 4317 "")
2b589241 4318
46d21d2c 4319(define_expand "fix_truncdfhi2"
ec13ba83
CT
4320 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4321 (fix:HI (match_operand:DF 1 "register_operand" "")))
8bc527af 4322 (clobber (reg:CC FLAGS_REG))])]
42a0aa6f 4323 "TARGET_80387 && !TARGET_SSE2"
22fb740d 4324 "")
46d21d2c
JW
4325
4326(define_expand "fix_truncsfhi2"
ec13ba83
CT
4327 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328 (fix:HI (match_operand:SF 1 "register_operand" "")))
8bc527af 4329 (clobber (reg:CC FLAGS_REG))])]
42a0aa6f 4330 "TARGET_80387 && !TARGET_SSE"
22fb740d
JH
4331 "")
4332
4333;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4334;; of the machinery.
4335(define_insn_and_split "*fix_trunchi_1"
4336 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
ec13ba83 4337 (fix:HI (match_operand 1 "register_operand" "f,f")))
8bc527af 4338 (clobber (reg:CC FLAGS_REG))]
22fb740d
JH
4339 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4340 && !reload_completed && !reload_in_progress
4341 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4342 "#"
d7518354 4343 "&& 1"
22fb740d
JH
4344 [(const_int 0)]
4345{
fa1a0d02 4346 ix86_optimize_mode_switching = 1;
22fb740d
JH
4347 operands[2] = assign_386_stack_local (HImode, 1);
4348 operands[3] = assign_386_stack_local (HImode, 2);
4349 if (memory_operand (operands[0], VOIDmode))
4350 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4351 operands[2], operands[3]));
4352 else
4353 {
4354 operands[4] = assign_386_stack_local (HImode, 0);
4355 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4356 operands[2], operands[3],
4357 operands[4]));
4358 }
4359 DONE;
4360}
26f74aa3 4361 [(set_attr "type" "fistp")
edeacc14 4362 (set_attr "i387_cw" "trunc")
26f74aa3 4363 (set_attr "mode" "HI")])
46d21d2c 4364
22fb740d 4365(define_insn "fix_trunchi_nomemory"
46d21d2c
JW
4366 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4367 (fix:HI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
4368 (use (match_operand:HI 2 "memory_operand" "m,m"))
4369 (use (match_operand:HI 3 "memory_operand" "m,m"))
4370 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
42a0aa6f 4371 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
22fb740d
JH
4372 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373 "#"
26f74aa3 4374 [(set_attr "type" "fistp")
edeacc14 4375 (set_attr "i387_cw" "trunc")
26f74aa3 4376 (set_attr "mode" "HI")])
22fb740d
JH
4377
4378(define_insn "fix_trunchi_memory"
4379 [(set (match_operand:HI 0 "memory_operand" "=m")
4380 (fix:HI (match_operand 1 "register_operand" "f")))
4381 (use (match_operand:HI 2 "memory_operand" "m"))
4382 (use (match_operand:HI 3 "memory_operand" "m"))]
4383 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4384 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
46d21d2c 4385 "* return output_fix_trunc (insn, operands);"
26f74aa3 4386 [(set_attr "type" "fistp")
edeacc14 4387 (set_attr "i387_cw" "trunc")
26f74aa3 4388 (set_attr "mode" "HI")])
22fb740d
JH
4389
4390(define_split
4391 [(set (match_operand:HI 0 "memory_operand" "")
4392 (fix:HI (match_operand 1 "register_operand" "")))
4393 (use (match_operand:HI 2 "memory_operand" ""))
4394 (use (match_operand:HI 3 "memory_operand" ""))
4395 (clobber (match_operand:HI 4 "memory_operand" ""))]
4396 "reload_completed"
4397 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4398 (use (match_dup 2))
4399 (use (match_dup 3))])]
4400 "")
46d21d2c
JW
4401
4402(define_split
4403 [(set (match_operand:HI 0 "register_operand" "")
4404 (fix:HI (match_operand 1 "register_operand" "")))
7a2e09f4
JH
4405 (use (match_operand:HI 2 "memory_operand" ""))
4406 (use (match_operand:HI 3 "memory_operand" ""))
4407 (clobber (match_operand:HI 4 "memory_operand" ""))]
46d21d2c 4408 "reload_completed"
7a2e09f4
JH
4409 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4410 (use (match_dup 2))
4411 (use (match_dup 3))
46d21d2c 4412 (clobber (match_dup 4))])
7a2e09f4 4413 (set (match_dup 0) (match_dup 4))]
46d21d2c
JW
4414 "")
4415
e075ae69 4416(define_insn "x86_fnstcw_1"
c76aab11 4417 [(set (match_operand:HI 0 "memory_operand" "=m")
8bc527af 4418 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
e1f998ad 4419 "TARGET_80387"
0f40f9f7 4420 "fnstcw\t%0"
6ef67412
JH
4421 [(set_attr "length" "2")
4422 (set_attr "mode" "HI")
56bab446 4423 (set_attr "unit" "i387")])
bc725565 4424
e075ae69 4425(define_insn "x86_fldcw_1"
8bc527af 4426 [(set (reg:HI FPSR_REG)
8ee41eaf 4427 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
bc725565 4428 "TARGET_80387"
0f40f9f7 4429 "fldcw\t%0"
6ef67412
JH
4430 [(set_attr "length" "2")
4431 (set_attr "mode" "HI")
3d34cd91 4432 (set_attr "unit" "i387")
56bab446 4433 (set_attr "athlon_decode" "vector")])
e075ae69
RH
4434\f
4435;; Conversion between fixed point and floating point.
886c62d1 4436
e075ae69
RH
4437;; Even though we only accept memory inputs, the backend _really_
4438;; wants to be able to do this between registers.
4439
35c28a13
JH
4440(define_expand "floathisf2"
4441 [(set (match_operand:SF 0 "register_operand" "")
4442 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
da8947b0 4443 "TARGET_80387 || TARGET_SSE_MATH"
35c28a13 4444{
da8947b0 4445 if (TARGET_SSE_MATH)
35c28a13
JH
4446 {
4447 emit_insn (gen_floatsisf2 (operands[0],
4448 convert_to_mode (SImode, operands[1], 0)));
4449 DONE;
4450 }
4451})
4452
da8947b0 4453(define_insn "*floathisf2_i387"
155d8a47 4454 [(set (match_operand:SF 0 "register_operand" "=f,f")
da8947b0
UB
4455 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4456 "TARGET_80387 && !TARGET_SSE_MATH"
155d8a47 4457 "@
0f40f9f7 4458 fild%z1\t%1
155d8a47
JW
4459 #"
4460 [(set_attr "type" "fmov,multi")
6ef67412 4461 (set_attr "mode" "SF")
155d8a47
JW
4462 (set_attr "fp_int_src" "true")])
4463
42a0aa6f
JH
4464(define_expand "floatsisf2"
4465 [(set (match_operand:SF 0 "register_operand" "")
4466 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
da8947b0 4467 "TARGET_80387 || TARGET_SSE_MATH"
42a0aa6f
JH
4468 "")
4469
da8947b0 4470(define_insn "*floatsisf2_mixed"
f56e86bd
JH
4471 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4472 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
da8947b0 4473 "TARGET_MIX_SSE_I387"
e075ae69 4474 "@
0f40f9f7 4475 fild%z1\t%1
42a0aa6f 4476 #
f56e86bd 4477 cvtsi2ss\t{%1, %0|%0, %1}
0f40f9f7 4478 cvtsi2ss\t{%1, %0|%0, %1}"
f56e86bd 4479 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
42a0aa6f 4480 (set_attr "mode" "SF")
f56e86bd 4481 (set_attr "athlon_decode" "*,*,vector,double")
42a0aa6f
JH
4482 (set_attr "fp_int_src" "true")])
4483
4484(define_insn "*floatsisf2_sse"
f56e86bd
JH
4485 [(set (match_operand:SF 0 "register_operand" "=x,x")
4486 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
da8947b0 4487 "TARGET_SSE_MATH"
0f40f9f7 4488 "cvtsi2ss\t{%1, %0|%0, %1}"
f56e86bd 4489 [(set_attr "type" "sseicvt")
6ef67412 4490 (set_attr "mode" "SF")
f56e86bd 4491 (set_attr "athlon_decode" "vector,double")
e075ae69 4492 (set_attr "fp_int_src" "true")])
bc725565 4493
d1f87653 4494; Avoid possible reformatting penalty on the destination by first
4977bab6
ZW
4495; zeroing it out
4496(define_split
4497 [(set (match_operand:SF 0 "register_operand" "")
4498 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
da8947b0
UB
4499 "reload_completed
4500 && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4977bab6
ZW
4501 && SSE_REG_P (operands[0])"
4502 [(const_int 0)]
4503{
4504 rtx dest;
4505 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4506 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4507 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4508 DONE;
4509})
4510
da8947b0
UB
4511(define_insn "*floatsisf2_i387"
4512 [(set (match_operand:SF 0 "register_operand" "=f,f")
4513 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4514 "TARGET_80387"
ef6257cd 4515 "@
0f40f9f7 4516 fild%z1\t%1
ef6257cd
JH
4517 #"
4518 [(set_attr "type" "fmov,multi")
4519 (set_attr "mode" "SF")
4520 (set_attr "fp_int_src" "true")])
4521
da8947b0
UB
4522(define_expand "floatdisf2"
4523 [(set (match_operand:SF 0 "register_operand" "")
4524 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4525 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4526 "")
4527
4528(define_insn "*floatdisf2_mixed"
f56e86bd
JH
4529 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4530 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
da8947b0 4531 "TARGET_64BIT && TARGET_MIX_SSE_I387"
e075ae69 4532 "@
0f40f9f7 4533 fild%z1\t%1
46ed7963 4534 #
f56e86bd 4535 cvtsi2ss{q}\t{%1, %0|%0, %1}
0f40f9f7 4536 cvtsi2ss{q}\t{%1, %0|%0, %1}"
f56e86bd 4537 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
46ed7963 4538 (set_attr "mode" "SF")
f56e86bd 4539 (set_attr "athlon_decode" "*,*,vector,double")
46ed7963
JH
4540 (set_attr "fp_int_src" "true")])
4541
4542(define_insn "*floatdisf2_sse"
f56e86bd
JH
4543 [(set (match_operand:SF 0 "register_operand" "=x,x")
4544 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
da8947b0 4545 "TARGET_64BIT && TARGET_SSE_MATH"
0f40f9f7 4546 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
f56e86bd 4547 [(set_attr "type" "sseicvt")
6ef67412 4548 (set_attr "mode" "SF")
f56e86bd 4549 (set_attr "athlon_decode" "vector,double")
e075ae69 4550 (set_attr "fp_int_src" "true")])
bc725565 4551
d1f87653 4552; Avoid possible reformatting penalty on the destination by first
4977bab6
ZW
4553; zeroing it out
4554(define_split
4555 [(set (match_operand:SF 0 "register_operand" "")
4556 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
da8947b0
UB
4557 "reload_completed
4558 && TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4977bab6
ZW
4559 && SSE_REG_P (operands[0])"
4560 [(const_int 0)]
4561{
4562 rtx dest;
4563 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4564 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4565 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4566 DONE;
4567})
4568
da8947b0
UB
4569(define_insn "*floatdisf2_i387"
4570 [(set (match_operand:SF 0 "register_operand" "=f,f")
4571 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4572 "TARGET_80387"
4573 "@
4574 fild%z1\t%1
4575 #"
4576 [(set_attr "type" "fmov,multi")
4577 (set_attr "mode" "SF")
4578 (set_attr "fp_int_src" "true")])
4579
35c28a13
JH
4580(define_expand "floathidf2"
4581 [(set (match_operand:DF 0 "register_operand" "")
4582 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
da8947b0 4583 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
35c28a13 4584{
da8947b0 4585 if (TARGET_SSE2 && TARGET_SSE_MATH)
35c28a13
JH
4586 {
4587 emit_insn (gen_floatsidf2 (operands[0],
4588 convert_to_mode (SImode, operands[1], 0)));
4589 DONE;
4590 }
4591})
4592
da8947b0 4593(define_insn "*floathidf2_i387"
155d8a47 4594 [(set (match_operand:DF 0 "register_operand" "=f,f")
da8947b0
UB
4595 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4596 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
155d8a47 4597 "@
0f40f9f7 4598 fild%z1\t%1
155d8a47
JW
4599 #"
4600 [(set_attr "type" "fmov,multi")
6ef67412 4601 (set_attr "mode" "DF")
155d8a47
JW
4602 (set_attr "fp_int_src" "true")])
4603
42a0aa6f
JH
4604(define_expand "floatsidf2"
4605 [(set (match_operand:DF 0 "register_operand" "")
4606 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
da8947b0 4607 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
42a0aa6f
JH
4608 "")
4609
da8947b0 4610(define_insn "*floatsidf2_mixed"
f56e86bd
JH
4611 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4612 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
da8947b0 4613 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
e075ae69 4614 "@
0f40f9f7 4615 fild%z1\t%1
42a0aa6f 4616 #
f56e86bd 4617 cvtsi2sd\t{%1, %0|%0, %1}
0f40f9f7 4618 cvtsi2sd\t{%1, %0|%0, %1}"
f56e86bd 4619 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
42a0aa6f 4620 (set_attr "mode" "DF")
f56e86bd 4621 (set_attr "athlon_decode" "*,*,double,direct")
42a0aa6f
JH
4622 (set_attr "fp_int_src" "true")])
4623
4624(define_insn "*floatsidf2_sse"
f56e86bd
JH
4625 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4626 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
da8947b0 4627 "TARGET_SSE2 && TARGET_SSE_MATH"
0f40f9f7 4628 "cvtsi2sd\t{%1, %0|%0, %1}"
f56e86bd 4629 [(set_attr "type" "sseicvt")
6ef67412 4630 (set_attr "mode" "DF")
f56e86bd 4631 (set_attr "athlon_decode" "double,direct")
e075ae69 4632 (set_attr "fp_int_src" "true")])
e1f998ad 4633
da8947b0
UB
4634(define_insn "*floatsidf2_i387"
4635 [(set (match_operand:DF 0 "register_operand" "=f,f")
4636 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4637 "TARGET_80387"
ef6257cd 4638 "@
0f40f9f7 4639 fild%z1\t%1
ef6257cd
JH
4640 #"
4641 [(set_attr "type" "fmov,multi")
4642 (set_attr "mode" "DF")
4643 (set_attr "fp_int_src" "true")])
4644
da8947b0
UB
4645(define_expand "floatdidf2"
4646 [(set (match_operand:DF 0 "register_operand" "")
4647 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4648 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4649 "")
4650
4651(define_insn "*floatdidf2_mixed"
f56e86bd
JH
4652 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4653 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
da8947b0 4654 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
e075ae69 4655 "@
0f40f9f7 4656 fild%z1\t%1
46ed7963 4657 #
f56e86bd 4658 cvtsi2sd{q}\t{%1, %0|%0, %1}
0f40f9f7 4659 cvtsi2sd{q}\t{%1, %0|%0, %1}"
f56e86bd 4660 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
46ed7963 4661 (set_attr "mode" "DF")
f56e86bd 4662 (set_attr "athlon_decode" "*,*,double,direct")
46ed7963
JH
4663 (set_attr "fp_int_src" "true")])
4664
4665(define_insn "*floatdidf2_sse"
f56e86bd
JH
4666 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4667 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
da8947b0 4668 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
0f40f9f7 4669 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
f56e86bd 4670 [(set_attr "type" "sseicvt")
6ef67412 4671 (set_attr "mode" "DF")
f56e86bd 4672 (set_attr "athlon_decode" "double,direct")
e075ae69 4673 (set_attr "fp_int_src" "true")])
bc725565 4674
da8947b0
UB
4675(define_insn "*floatdidf2_i387"
4676 [(set (match_operand:DF 0 "register_operand" "=f,f")
4677 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4678 "TARGET_80387"
4679 "@
4680 fild%z1\t%1
4681 #"
4682 [(set_attr "type" "fmov,multi")
4683 (set_attr "mode" "DF")
4684 (set_attr "fp_int_src" "true")])
4685
155d8a47
JW
4686(define_insn "floathixf2"
4687 [(set (match_operand:XF 0 "register_operand" "=f,f")
da8947b0 4688 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
2b589241
JH
4689 "TARGET_80387"
4690 "@
0f40f9f7 4691 fild%z1\t%1
2b589241
JH
4692 #"
4693 [(set_attr "type" "fmov,multi")
4694 (set_attr "mode" "XF")
4695 (set_attr "fp_int_src" "true")])
4696
e075ae69
RH
4697(define_insn "floatsixf2"
4698 [(set (match_operand:XF 0 "register_operand" "=f,f")
da8947b0 4699 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
2b589241
JH
4700 "TARGET_80387"
4701 "@
0f40f9f7 4702 fild%z1\t%1
2b589241
JH
4703 #"
4704 [(set_attr "type" "fmov,multi")
4705 (set_attr "mode" "XF")
4706 (set_attr "fp_int_src" "true")])
4707
e075ae69 4708(define_insn "floatdixf2"
53b5ce19 4709 [(set (match_operand:XF 0 "register_operand" "=f,f")
da8947b0 4710 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
2b589241
JH
4711 "TARGET_80387"
4712 "@
0f40f9f7 4713 fild%z1\t%1
2b589241
JH
4714 #"
4715 [(set_attr "type" "fmov,multi")
4716 (set_attr "mode" "XF")
4717 (set_attr "fp_int_src" "true")])
4718
e075ae69 4719;; %%% Kill these when reload knows how to do it.
155d8a47 4720(define_split
c3c637e3 4721 [(set (match_operand 0 "fp_register_operand" "")
4211a8fb 4722 (float (match_operand 1 "register_operand" "")))]
da8947b0
UB
4723 "reload_completed
4724 && TARGET_80387
4725 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211a8fb 4726 [(const_int 0)]
4211a8fb
JH
4727{
4728 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4729 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4730 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4731 ix86_free_from_memory (GET_MODE (operands[1]));
4732 DONE;
0f40f9f7 4733})
8d705469
JH
4734
4735(define_expand "floatunssisf2"
4736 [(use (match_operand:SF 0 "register_operand" ""))
4737 (use (match_operand:SI 1 "register_operand" ""))]
da8947b0 4738 "!TARGET_64BIT && TARGET_SSE_MATH"
8d705469
JH
4739 "x86_emit_floatuns (operands); DONE;")
4740
4741(define_expand "floatunsdisf2"
4742 [(use (match_operand:SF 0 "register_operand" ""))
4743 (use (match_operand:DI 1 "register_operand" ""))]
da8947b0 4744 "TARGET_64BIT && TARGET_SSE_MATH"
8d705469
JH
4745 "x86_emit_floatuns (operands); DONE;")
4746
4747(define_expand "floatunsdidf2"
4748 [(use (match_operand:DF 0 "register_operand" ""))
4749 (use (match_operand:DI 1 "register_operand" ""))]
da8947b0 4750 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
8d705469 4751 "x86_emit_floatuns (operands); DONE;")
e075ae69 4752\f
997404de
JH
4753;; SSE extract/set expanders
4754
4755(define_expand "vec_setv2df"
4756 [(match_operand:V2DF 0 "register_operand" "")
4757 (match_operand:DF 1 "register_operand" "")
4758 (match_operand 2 "const_int_operand" "")]
4759 "TARGET_SSE2"
4760{
4761 switch (INTVAL (operands[2]))
4762 {
4763 case 0:
4764 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4765 simplify_gen_subreg (V2DFmode, operands[1],
4766 DFmode, 0)));
4767 break;
4768 case 1:
4769 {
4770 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4771
4772 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4773 }
4774 break;
4775 default:
4776 abort ();
4777 }
4778 DONE;
4779})
4780
4781(define_expand "vec_extractv2df"
4782 [(match_operand:DF 0 "register_operand" "")
4783 (match_operand:V2DF 1 "register_operand" "")
4784 (match_operand 2 "const_int_operand" "")]
4785 "TARGET_SSE2"
4786{
4787 switch (INTVAL (operands[2]))
4788 {
4789 case 0:
4790 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4791 break;
4792 case 1:
4793 {
4794 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4795
4796 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4797 }
4798 break;
4799 default:
4800 abort ();
4801 }
4802 DONE;
4803})
4804
4805(define_expand "vec_initv2df"
4806 [(match_operand:V2DF 0 "register_operand" "")
4807 (match_operand 1 "" "")]
4808 "TARGET_SSE2"
4809{
4810 ix86_expand_vector_init (operands[0], operands[1]);
4811 DONE;
4812})
4813
4814(define_expand "vec_setv4sf"
4815 [(match_operand:V4SF 0 "register_operand" "")
4816 (match_operand:SF 1 "register_operand" "")
4817 (match_operand 2 "const_int_operand" "")]
4818 "TARGET_SSE"
4819{
4820 switch (INTVAL (operands[2]))
4821 {
4822 case 0:
4823 emit_insn (gen_sse_movss (operands[0], operands[0],
4824 simplify_gen_subreg (V4SFmode, operands[1],
4825 SFmode, 0)));
4826 break;
4827 case 1:
4828 {
4829 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4830 rtx tmp = gen_reg_rtx (V4SFmode);
4831
4832 emit_move_insn (tmp, operands[0]);
4833 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4834 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4835 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4837 }
b42271d6 4838 break;
997404de
JH
4839 case 2:
4840 {
4841 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4842 rtx tmp = gen_reg_rtx (V4SFmode);
4843
4844 emit_move_insn (tmp, operands[0]);
4845 emit_insn (gen_sse_movss (tmp, tmp, op1));
4846 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4847 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4848 }
4849 break;
4850 case 3:
4851 {
4852 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4853 rtx tmp = gen_reg_rtx (V4SFmode);
4854
4855 emit_move_insn (tmp, operands[0]);
4856 emit_insn (gen_sse_movss (tmp, tmp, op1));
4857 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4858 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4859 }
4860 break;
4861 default:
4862 abort ();
4863 }
4864 DONE;
4865})
4866
4867(define_expand "vec_extractv4sf"
4868 [(match_operand:SF 0 "register_operand" "")
4869 (match_operand:V4SF 1 "register_operand" "")
4870 (match_operand 2 "const_int_operand" "")]
4871 "TARGET_SSE"
4872{
4873 switch (INTVAL (operands[2]))
4874 {
4875 case 0:
4876 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4877 break;
4878 case 1:
4879 {
4880 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4881 rtx tmp = gen_reg_rtx (V4SFmode);
4882
4883 emit_move_insn (tmp, operands[1]);
4884 emit_insn (gen_sse_shufps (op0, tmp, tmp,
60c81c89 4885 const1_rtx));
997404de 4886 }
b42271d6 4887 break;
997404de
JH
4888 case 2:
4889 {
4890 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4891 rtx tmp = gen_reg_rtx (V4SFmode);
4892
4893 emit_move_insn (tmp, operands[1]);
4894 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4895 }
b42271d6 4896 break;
997404de
JH
4897 case 3:
4898 {
4899 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4900 rtx tmp = gen_reg_rtx (V4SFmode);
4901
4902 emit_move_insn (tmp, operands[1]);
4903 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4904 GEN_INT (3)));
4905 }
b42271d6 4906 break;
997404de
JH
4907 default:
4908 abort ();
4909 }
4910 DONE;
4911})
4912
4913(define_expand "vec_initv4sf"
4914 [(match_operand:V4SF 0 "register_operand" "")
4915 (match_operand 1 "" "")]
4916 "TARGET_SSE"
4917{
4918 ix86_expand_vector_init (operands[0], operands[1]);
4919 DONE;
4920})
4921\f
e075ae69 4922;; Add instructions
53b5ce19 4923
e075ae69
RH
4924;; %%% splits for addsidi3
4925; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4926; (plus:DI (match_operand:DI 1 "general_operand" "")
4927; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
e1f998ad 4928
9b70259d
JH
4929(define_expand "adddi3"
4930 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4931 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4932 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 4933 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
4934 ""
4935 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4936
4937(define_insn "*adddi3_1"
e075ae69
RH
4938 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4939 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4940 (match_operand:DI 2 "general_operand" "roiF,riF")))
8bc527af 4941 (clobber (reg:CC FLAGS_REG))]
c15c18c5 4942 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
bc725565
JW
4943 "#")
4944
4945(define_split
e075ae69 4946 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4cbfbb1b 4947 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
e075ae69 4948 (match_operand:DI 2 "general_operand" "")))
8bc527af 4949 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 4950 "!TARGET_64BIT && reload_completed"
8bc527af 4951 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
8ee41eaf 4952 UNSPEC_ADD_CARRY))
e075ae69
RH
4953 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4954 (parallel [(set (match_dup 3)
8bc527af 4955 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9dcbdc7e
JH
4956 (match_dup 4))
4957 (match_dup 5)))
8bc527af 4958 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
4959 "split_di (operands+0, 1, operands+0, operands+3);
4960 split_di (operands+1, 1, operands+1, operands+4);
4961 split_di (operands+2, 1, operands+2, operands+5);")
4962
7b52eede 4963(define_insn "adddi3_carry_rex64"
9b70259d 4964 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
e6e81735 4965 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
9b70259d
JH
4966 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4967 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8bc527af 4968 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 4969 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
0f40f9f7 4970 "adc{q}\t{%2, %0|%0, %2}"
9b70259d
JH
4971 [(set_attr "type" "alu")
4972 (set_attr "pent_pair" "pu")
56bab446 4973 (set_attr "mode" "DI")])
9b70259d
JH
4974
4975(define_insn "*adddi3_cc_rex64"
8bc527af 4976 [(set (reg:CC FLAGS_REG)
8ee41eaf
RH
4977 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4978 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4979 UNSPEC_ADD_CARRY))
9b70259d
JH
4980 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4981 (plus:DI (match_dup 1) (match_dup 2)))]
4982 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
0f40f9f7 4983 "add{q}\t{%2, %0|%0, %2}"
9b70259d
JH
4984 [(set_attr "type" "alu")
4985 (set_attr "mode" "DI")])
4986
7b52eede 4987(define_insn "addqi3_carry"
d67e96cf 4988 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
e6e81735 4989 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7b52eede 4990 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
d67e96cf 4991 (match_operand:QI 2 "general_operand" "qi,qm")))
8bc527af 4992 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
4993 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4994 "adc{b}\t{%2, %0|%0, %2}"
4995 [(set_attr "type" "alu")
4996 (set_attr "pent_pair" "pu")
56bab446 4997 (set_attr "mode" "QI")])
7b52eede
JH
4998
4999(define_insn "addhi3_carry"
5000 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
e6e81735 5001 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7b52eede
JH
5002 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5003 (match_operand:HI 2 "general_operand" "ri,rm")))
8bc527af 5004 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
5005 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5006 "adc{w}\t{%2, %0|%0, %2}"
5007 [(set_attr "type" "alu")
5008 (set_attr "pent_pair" "pu")
56bab446 5009 (set_attr "mode" "HI")])
7b52eede
JH
5010
5011(define_insn "addsi3_carry"
e075ae69 5012 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
e6e81735 5013 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9dcbdc7e
JH
5014 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5015 (match_operand:SI 2 "general_operand" "ri,rm")))
8bc527af 5016 (clobber (reg:CC FLAGS_REG))]
d525dfdf 5017 "ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 5018 "adc{l}\t{%2, %0|%0, %2}"
e075ae69
RH
5019 [(set_attr "type" "alu")
5020 (set_attr "pent_pair" "pu")
56bab446 5021 (set_attr "mode" "SI")])
4fb21e90 5022
9b70259d
JH
5023(define_insn "*addsi3_carry_zext"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (zero_extend:DI
e6e81735 5026 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9b70259d
JH
5027 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5028 (match_operand:SI 2 "general_operand" "rim"))))
8bc527af 5029 (clobber (reg:CC FLAGS_REG))]
9b70259d 5030 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 5031 "adc{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
5032 [(set_attr "type" "alu")
5033 (set_attr "pent_pair" "pu")
56bab446 5034 (set_attr "mode" "SI")])
9b70259d 5035
7e08e190 5036(define_insn "*addsi3_cc"
8bc527af 5037 [(set (reg:CC FLAGS_REG)
8ee41eaf
RH
5038 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5039 (match_operand:SI 2 "general_operand" "ri,rm")]
5040 UNSPEC_ADD_CARRY))
7e08e190
JH
5041 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5042 (plus:SI (match_dup 1) (match_dup 2)))]
265dab10 5043 "ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 5044 "add{l}\t{%2, %0|%0, %2}"
265dab10 5045 [(set_attr "type" "alu")
7e08e190
JH
5046 (set_attr "mode" "SI")])
5047
5048(define_insn "addqi3_cc"
8bc527af 5049 [(set (reg:CC FLAGS_REG)
8ee41eaf
RH
5050 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5051 (match_operand:QI 2 "general_operand" "qi,qm")]
5052 UNSPEC_ADD_CARRY))
7e08e190
JH
5053 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5054 (plus:QI (match_dup 1) (match_dup 2)))]
5055 "ix86_binary_operator_ok (PLUS, QImode, operands)"
0f40f9f7 5056 "add{b}\t{%2, %0|%0, %2}"
7e08e190
JH
5057 [(set_attr "type" "alu")
5058 (set_attr "mode" "QI")])
265dab10 5059
e075ae69
RH
5060(define_expand "addsi3"
5061 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5062 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5063 (match_operand:SI 2 "general_operand" "")))
8bc527af 5064 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
5065 ""
5066 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
886c62d1 5067
ac62a60e 5068(define_insn "*lea_1"
e075ae69 5069 [(set (match_operand:SI 0 "register_operand" "=r")
74dc3e94 5070 (match_operand:SI 1 "no_seg_address_operand" "p"))]
ac62a60e 5071 "!TARGET_64BIT"
0f40f9f7 5072 "lea{l}\t{%a1, %0|%0, %a1}"
6ef67412
JH
5073 [(set_attr "type" "lea")
5074 (set_attr "mode" "SI")])
2ae0f82c 5075
ac62a60e
JH
5076(define_insn "*lea_1_rex64"
5077 [(set (match_operand:SI 0 "register_operand" "=r")
74dc3e94 5078 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
ac62a60e 5079 "TARGET_64BIT"
0f40f9f7 5080 "lea{l}\t{%a1, %0|%0, %a1}"
ac62a60e
JH
5081 [(set_attr "type" "lea")
5082 (set_attr "mode" "SI")])
5083
5084(define_insn "*lea_1_zext"
5085 [(set (match_operand:DI 0 "register_operand" "=r")
74dc3e94
RH
5086 (zero_extend:DI
5087 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
d4f33f6c 5088 "TARGET_64BIT"
0f40f9f7 5089 "lea{l}\t{%a1, %k0|%k0, %a1}"
ac62a60e
JH
5090 [(set_attr "type" "lea")
5091 (set_attr "mode" "SI")])
5092
5093(define_insn "*lea_2_rex64"
5094 [(set (match_operand:DI 0 "register_operand" "=r")
74dc3e94 5095 (match_operand:DI 1 "no_seg_address_operand" "p"))]
ac62a60e 5096 "TARGET_64BIT"
0f40f9f7 5097 "lea{q}\t{%a1, %0|%0, %a1}"
ac62a60e
JH
5098 [(set_attr "type" "lea")
5099 (set_attr "mode" "DI")])
5100
58787064
JH
5101;; The lea patterns for non-Pmodes needs to be matched by several
5102;; insns converted to real lea by splitters.
5103
5104(define_insn_and_split "*lea_general_1"
5105 [(set (match_operand 0 "register_operand" "=r")
9a9286af 5106 (plus (plus (match_operand 1 "index_register_operand" "l")
58787064
JH
5107 (match_operand 2 "register_operand" "r"))
5108 (match_operand 3 "immediate_operand" "i")))]
ac62a60e
JH
5109 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5110 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
58787064
JH
5111 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5112 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5113 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5114 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5115 || GET_MODE (operands[3]) == VOIDmode)"
5116 "#"
cb694d2c 5117 "&& reload_completed"
58787064 5118 [(const_int 0)]
58787064
JH
5119{
5120 rtx pat;
5121 operands[0] = gen_lowpart (SImode, operands[0]);
5122 operands[1] = gen_lowpart (Pmode, operands[1]);
5123 operands[2] = gen_lowpart (Pmode, operands[2]);
5124 operands[3] = gen_lowpart (Pmode, operands[3]);
5125 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5126 operands[3]);
5127 if (Pmode != SImode)
5128 pat = gen_rtx_SUBREG (SImode, pat, 0);
5129 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5130 DONE;
0f40f9f7 5131}
58787064
JH
5132 [(set_attr "type" "lea")
5133 (set_attr "mode" "SI")])
5134
ac62a60e
JH
5135(define_insn_and_split "*lea_general_1_zext"
5136 [(set (match_operand:DI 0 "register_operand" "=r")
5137 (zero_extend:DI
9a9286af 5138 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
ac62a60e
JH
5139 (match_operand:SI 2 "register_operand" "r"))
5140 (match_operand:SI 3 "immediate_operand" "i"))))]
5141 "TARGET_64BIT"
5142 "#"
5143 "&& reload_completed"
5144 [(set (match_dup 0)
5145 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5146 (match_dup 2))
5147 (match_dup 3)) 0)))]
ac62a60e
JH
5148{
5149 operands[1] = gen_lowpart (Pmode, operands[1]);
5150 operands[2] = gen_lowpart (Pmode, operands[2]);
5151 operands[3] = gen_lowpart (Pmode, operands[3]);
0f40f9f7 5152}
ac62a60e
JH
5153 [(set_attr "type" "lea")
5154 (set_attr "mode" "SI")])
5155
58787064
JH
5156(define_insn_and_split "*lea_general_2"
5157 [(set (match_operand 0 "register_operand" "=r")
9a9286af 5158 (plus (mult (match_operand 1 "index_register_operand" "l")
58787064
JH
5159 (match_operand 2 "const248_operand" "i"))
5160 (match_operand 3 "nonmemory_operand" "ri")))]
ac62a60e
JH
5161 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5162 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
58787064
JH
5163 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5164 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5165 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5166 || GET_MODE (operands[3]) == VOIDmode)"
5167 "#"
cb694d2c 5168 "&& reload_completed"
58787064 5169 [(const_int 0)]
58787064
JH
5170{
5171 rtx pat;
5172 operands[0] = gen_lowpart (SImode, operands[0]);
5173 operands[1] = gen_lowpart (Pmode, operands[1]);
5174 operands[3] = gen_lowpart (Pmode, operands[3]);
5175 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5176 operands[3]);
5177 if (Pmode != SImode)
5178 pat = gen_rtx_SUBREG (SImode, pat, 0);
5179 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5180 DONE;
0f40f9f7 5181}
58787064
JH
5182 [(set_attr "type" "lea")
5183 (set_attr "mode" "SI")])
5184
ac62a60e
JH
5185(define_insn_and_split "*lea_general_2_zext"
5186 [(set (match_operand:DI 0 "register_operand" "=r")
5187 (zero_extend:DI
9a9286af 5188 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
ac62a60e
JH
5189 (match_operand:SI 2 "const248_operand" "n"))
5190 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5191 "TARGET_64BIT"
5192 "#"
5193 "&& reload_completed"
5194 [(set (match_dup 0)
5195 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5196 (match_dup 2))
5197 (match_dup 3)) 0)))]
ac62a60e
JH
5198{
5199 operands[1] = gen_lowpart (Pmode, operands[1]);
5200 operands[3] = gen_lowpart (Pmode, operands[3]);
0f40f9f7 5201}
ac62a60e
JH
5202 [(set_attr "type" "lea")
5203 (set_attr "mode" "SI")])
5204
58787064
JH
5205(define_insn_and_split "*lea_general_3"
5206 [(set (match_operand 0 "register_operand" "=r")
9a9286af 5207 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
58787064
JH
5208 (match_operand 2 "const248_operand" "i"))
5209 (match_operand 3 "register_operand" "r"))
5210 (match_operand 4 "immediate_operand" "i")))]
ac62a60e
JH
5211 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5212 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
58787064
JH
5213 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5214 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5215 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5216 "#"
cb694d2c 5217 "&& reload_completed"
58787064 5218 [(const_int 0)]
58787064
JH
5219{
5220 rtx pat;
5221 operands[0] = gen_lowpart (SImode, operands[0]);
5222 operands[1] = gen_lowpart (Pmode, operands[1]);
5223 operands[3] = gen_lowpart (Pmode, operands[3]);
5224 operands[4] = gen_lowpart (Pmode, operands[4]);
5225 pat = gen_rtx_PLUS (Pmode,
5226 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5227 operands[2]),
5228 operands[3]),
5229 operands[4]);
5230 if (Pmode != SImode)
5231 pat = gen_rtx_SUBREG (SImode, pat, 0);
5232 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5233 DONE;
0f40f9f7 5234}
58787064
JH
5235 [(set_attr "type" "lea")
5236 (set_attr "mode" "SI")])
5237
ac62a60e
JH
5238(define_insn_and_split "*lea_general_3_zext"
5239 [(set (match_operand:DI 0 "register_operand" "=r")
5240 (zero_extend:DI
9a9286af
RH
5241 (plus:SI (plus:SI (mult:SI
5242 (match_operand:SI 1 "index_register_operand" "l")
5243 (match_operand:SI 2 "const248_operand" "n"))
ac62a60e
JH
5244 (match_operand:SI 3 "register_operand" "r"))
5245 (match_operand:SI 4 "immediate_operand" "i"))))]
5246 "TARGET_64BIT"
5247 "#"
5248 "&& reload_completed"
5249 [(set (match_dup 0)
5250 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5251 (match_dup 2))
5252 (match_dup 3))
5253 (match_dup 4)) 0)))]
ac62a60e
JH
5254{
5255 operands[1] = gen_lowpart (Pmode, operands[1]);
5256 operands[3] = gen_lowpart (Pmode, operands[3]);
5257 operands[4] = gen_lowpart (Pmode, operands[4]);
0f40f9f7 5258}
ac62a60e
JH
5259 [(set_attr "type" "lea")
5260 (set_attr "mode" "SI")])
5261
9b70259d
JH
5262(define_insn "*adddi_1_rex64"
5263 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5264 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
9a9286af 5265 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
8bc527af 5266 (clobber (reg:CC FLAGS_REG))]
9b70259d 5267 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
2ae0f82c 5268{
e075ae69 5269 switch (get_attr_type (insn))
2ae0f82c 5270 {
e075ae69
RH
5271 case TYPE_LEA:
5272 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 5273 return "lea{q}\t{%a2, %0|%0, %a2}";
2ae0f82c 5274
e075ae69
RH
5275 case TYPE_INCDEC:
5276 if (! rtx_equal_p (operands[0], operands[1]))
5277 abort ();
5278 if (operands[2] == const1_rtx)
0f40f9f7 5279 return "inc{q}\t%0";
e075ae69 5280 else if (operands[2] == constm1_rtx)
0f40f9f7 5281 return "dec{q}\t%0";
2ae0f82c 5282 else
9b70259d 5283 abort ();
2ae0f82c 5284
e075ae69
RH
5285 default:
5286 if (! rtx_equal_p (operands[0], operands[1]))
5287 abort ();
2ae0f82c 5288
e075ae69
RH
5289 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5290 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5291 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5292 /* Avoid overflows. */
0f40f9f7 5293 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
e075ae69
RH
5294 && (INTVAL (operands[2]) == 128
5295 || (INTVAL (operands[2]) < 0
5296 && INTVAL (operands[2]) != -128)))
5297 {
5298 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5299 return "sub{q}\t{%2, %0|%0, %2}";
e075ae69 5300 }
0f40f9f7 5301 return "add{q}\t{%2, %0|%0, %2}";
e075ae69 5302 }
0f40f9f7 5303}
e075ae69
RH
5304 [(set (attr "type")
5305 (cond [(eq_attr "alternative" "2")
5306 (const_string "lea")
5307 ; Current assemblers are broken and do not allow @GOTOFF in
5308 ; ought but a memory context.
9b70259d 5309 (match_operand:DI 2 "pic_symbolic_operand" "")
e075ae69 5310 (const_string "lea")
9b70259d 5311 (match_operand:DI 2 "incdec_operand" "")
e075ae69
RH
5312 (const_string "incdec")
5313 ]
6ef67412 5314 (const_string "alu")))
9b70259d 5315 (set_attr "mode" "DI")])
e075ae69 5316
1c27d4b2
JH
5317;; Convert lea to the lea pattern to avoid flags dependency.
5318(define_split
9b70259d
JH
5319 [(set (match_operand:DI 0 "register_operand" "")
5320 (plus:DI (match_operand:DI 1 "register_operand" "")
5321 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
8bc527af 5322 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 5323 "TARGET_64BIT && reload_completed
abe24fb3 5324 && true_regnum (operands[0]) != true_regnum (operands[1])"
9b70259d
JH
5325 [(set (match_dup 0)
5326 (plus:DI (match_dup 1)
5327 (match_dup 2)))]
5328 "")
1c27d4b2 5329
9b70259d 5330(define_insn "*adddi_2_rex64"
42fabf21 5331 [(set (reg FLAGS_REG)
16189740 5332 (compare
9b70259d
JH
5333 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5334 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
e075ae69 5335 (const_int 0)))
9b70259d
JH
5336 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5337 (plus:DI (match_dup 1) (match_dup 2)))]
5338 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5339 && ix86_binary_operator_ok (PLUS, DImode, operands)
e075ae69 5340 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5341 ought but a memory context. */
e075ae69 5342 && ! pic_symbolic_operand (operands[2], VOIDmode)"
886c62d1 5343{
e075ae69 5344 switch (get_attr_type (insn))
96f218bb 5345 {
e075ae69
RH
5346 case TYPE_INCDEC:
5347 if (! rtx_equal_p (operands[0], operands[1]))
5348 abort ();
5349 if (operands[2] == const1_rtx)
0f40f9f7 5350 return "inc{q}\t%0";
e075ae69 5351 else if (operands[2] == constm1_rtx)
0f40f9f7 5352 return "dec{q}\t%0";
96f218bb 5353 else
9b70259d 5354 abort ();
96f218bb 5355
e075ae69
RH
5356 default:
5357 if (! rtx_equal_p (operands[0], operands[1]))
5358 abort ();
9b70259d 5359 /* ???? We ought to handle there the 32bit case too
5bdc5878 5360 - do we need new constraint? */
e075ae69
RH
5361 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5363 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5364 /* Avoid overflows. */
0f40f9f7 5365 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
e075ae69
RH
5366 && (INTVAL (operands[2]) == 128
5367 || (INTVAL (operands[2]) < 0
5368 && INTVAL (operands[2]) != -128)))
5369 {
5370 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5371 return "sub{q}\t{%2, %0|%0, %2}";
e075ae69 5372 }
0f40f9f7 5373 return "add{q}\t{%2, %0|%0, %2}";
9c530261 5374 }
0f40f9f7 5375}
e075ae69 5376 [(set (attr "type")
9b70259d 5377 (if_then_else (match_operand:DI 2 "incdec_operand" "")
e075ae69 5378 (const_string "incdec")
6ef67412 5379 (const_string "alu")))
9b70259d 5380 (set_attr "mode" "DI")])
e075ae69 5381
e74061a9 5382(define_insn "*adddi_3_rex64"
42fabf21 5383 [(set (reg FLAGS_REG)
9b70259d
JH
5384 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5385 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5386 (clobber (match_scratch:DI 0 "=r"))]
e74061a9
JH
5387 "TARGET_64BIT
5388 && ix86_match_ccmode (insn, CCZmode)
d90ffc8d
JH
5389 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5390 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5391 ought but a memory context. */
d90ffc8d 5392 && ! pic_symbolic_operand (operands[2], VOIDmode)"
d90ffc8d
JH
5393{
5394 switch (get_attr_type (insn))
5395 {
5396 case TYPE_INCDEC:
5397 if (! rtx_equal_p (operands[0], operands[1]))
5398 abort ();
5399 if (operands[2] == const1_rtx)
0f40f9f7 5400 return "inc{q}\t%0";
d90ffc8d 5401 else if (operands[2] == constm1_rtx)
0f40f9f7 5402 return "dec{q}\t%0";
d90ffc8d 5403 else
9b70259d 5404 abort ();
d90ffc8d
JH
5405
5406 default:
5407 if (! rtx_equal_p (operands[0], operands[1]))
5408 abort ();
9b70259d 5409 /* ???? We ought to handle there the 32bit case too
5bdc5878 5410 - do we need new constraint? */
d90ffc8d
JH
5411 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5412 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5413 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5414 /* Avoid overflows. */
0f40f9f7 5415 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
d90ffc8d
JH
5416 && (INTVAL (operands[2]) == 128
5417 || (INTVAL (operands[2]) < 0
5418 && INTVAL (operands[2]) != -128)))
5419 {
5420 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5421 return "sub{q}\t{%2, %0|%0, %2}";
d90ffc8d 5422 }
0f40f9f7 5423 return "add{q}\t{%2, %0|%0, %2}";
d90ffc8d 5424 }
0f40f9f7 5425}
d90ffc8d 5426 [(set (attr "type")
9b70259d 5427 (if_then_else (match_operand:DI 2 "incdec_operand" "")
d90ffc8d
JH
5428 (const_string "incdec")
5429 (const_string "alu")))
9b70259d 5430 (set_attr "mode" "DI")])
d90ffc8d 5431
9b70259d 5432; For comparisons against 1, -1 and 128, we may generate better code
7e08e190
JH
5433; by converting cmp to add, inc or dec as done by peephole2. This pattern
5434; is matched then. We can't accept general immediate, because for
5435; case of overflows, the result is messed up.
9b70259d 5436; This pattern also don't hold of 0x8000000000000000, since the value overflows
7e08e190 5437; when negated.
d6a7951f 5438; Also carry flag is reversed compared to cmp, so this conversion is valid
7e08e190 5439; only for comparisons not depending on it.
e74061a9 5440(define_insn "*adddi_4_rex64"
42fabf21 5441 [(set (reg FLAGS_REG)
9b70259d
JH
5442 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5443 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5444 (clobber (match_scratch:DI 0 "=rm"))]
e74061a9
JH
5445 "TARGET_64BIT
5446 && ix86_match_ccmode (insn, CCGCmode)"
7e08e190
JH
5447{
5448 switch (get_attr_type (insn))
5449 {
5450 case TYPE_INCDEC:
5451 if (operands[2] == constm1_rtx)
0f40f9f7 5452 return "inc{q}\t%0";
7e08e190 5453 else if (operands[2] == const1_rtx)
0f40f9f7 5454 return "dec{q}\t%0";
7e08e190
JH
5455 else
5456 abort();
e075ae69 5457
7e08e190
JH
5458 default:
5459 if (! rtx_equal_p (operands[0], operands[1]))
5460 abort ();
5461 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5462 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5463 if ((INTVAL (operands[2]) == -128
5464 || (INTVAL (operands[2]) > 0
ef6257cd
JH
5465 && INTVAL (operands[2]) != 128))
5466 /* Avoid overflows. */
0f40f9f7
ZW
5467 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5468 return "sub{q}\t{%2, %0|%0, %2}";
7e08e190 5469 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5470 return "add{q}\t{%2, %0|%0, %2}";
7e08e190 5471 }
0f40f9f7 5472}
7e08e190 5473 [(set (attr "type")
9b70259d 5474 (if_then_else (match_operand:DI 2 "incdec_operand" "")
7e08e190
JH
5475 (const_string "incdec")
5476 (const_string "alu")))
9b70259d 5477 (set_attr "mode" "DI")])
d90ffc8d 5478
e74061a9 5479(define_insn "*adddi_5_rex64"
42fabf21 5480 [(set (reg FLAGS_REG)
9076b9c1 5481 (compare
9b70259d
JH
5482 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5483 (match_operand:DI 2 "x86_64_general_operand" "rme"))
9076b9c1 5484 (const_int 0)))
9b70259d 5485 (clobber (match_scratch:DI 0 "=r"))]
e74061a9
JH
5486 "TARGET_64BIT
5487 && ix86_match_ccmode (insn, CCGOCmode)
9076b9c1
JH
5488 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5489 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5490 ought but a memory context. */
9076b9c1 5491 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9076b9c1
JH
5492{
5493 switch (get_attr_type (insn))
5494 {
5495 case TYPE_INCDEC:
5496 if (! rtx_equal_p (operands[0], operands[1]))
5497 abort ();
5498 if (operands[2] == const1_rtx)
0f40f9f7 5499 return "inc{q}\t%0";
9076b9c1 5500 else if (operands[2] == constm1_rtx)
0f40f9f7 5501 return "dec{q}\t%0";
9076b9c1
JH
5502 else
5503 abort();
5504
5505 default:
5506 if (! rtx_equal_p (operands[0], operands[1]))
5507 abort ();
5508 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5509 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5510 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5511 /* Avoid overflows. */
0f40f9f7 5512 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
9076b9c1
JH
5513 && (INTVAL (operands[2]) == 128
5514 || (INTVAL (operands[2]) < 0
5515 && INTVAL (operands[2]) != -128)))
5516 {
5517 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5518 return "sub{q}\t{%2, %0|%0, %2}";
9076b9c1 5519 }
0f40f9f7 5520 return "add{q}\t{%2, %0|%0, %2}";
9076b9c1 5521 }
0f40f9f7 5522}
9076b9c1 5523 [(set (attr "type")
9b70259d 5524 (if_then_else (match_operand:DI 2 "incdec_operand" "")
9076b9c1
JH
5525 (const_string "incdec")
5526 (const_string "alu")))
9b70259d 5527 (set_attr "mode" "DI")])
2ae0f82c 5528
e075ae69 5529
9b70259d
JH
5530(define_insn "*addsi_1"
5531 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
9a9286af 5533 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
8bc527af 5534 (clobber (reg:CC FLAGS_REG))]
9b70259d 5535 "ix86_binary_operator_ok (PLUS, SImode, operands)"
58787064
JH
5536{
5537 switch (get_attr_type (insn))
5538 {
5539 case TYPE_LEA:
9b70259d 5540 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 5541 return "lea{l}\t{%a2, %0|%0, %a2}";
9b70259d 5542
58787064 5543 case TYPE_INCDEC:
9b70259d
JH
5544 if (! rtx_equal_p (operands[0], operands[1]))
5545 abort ();
58787064 5546 if (operands[2] == const1_rtx)
0f40f9f7 5547 return "inc{l}\t%0";
9b70259d 5548 else if (operands[2] == constm1_rtx)
0f40f9f7 5549 return "dec{l}\t%0";
9b70259d
JH
5550 else
5551 abort();
58787064
JH
5552
5553 default:
9b70259d
JH
5554 if (! rtx_equal_p (operands[0], operands[1]))
5555 abort ();
5556
58787064
JH
5557 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5558 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5559 if (GET_CODE (operands[2]) == CONST_INT
5560 && (INTVAL (operands[2]) == 128
5561 || (INTVAL (operands[2]) < 0
5562 && INTVAL (operands[2]) != -128)))
9b70259d
JH
5563 {
5564 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5565 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5566 }
0f40f9f7 5567 return "add{l}\t{%2, %0|%0, %2}";
58787064 5568 }
0f40f9f7 5569}
58787064 5570 [(set (attr "type")
9b70259d
JH
5571 (cond [(eq_attr "alternative" "2")
5572 (const_string "lea")
5573 ; Current assemblers are broken and do not allow @GOTOFF in
5574 ; ought but a memory context.
5575 (match_operand:SI 2 "pic_symbolic_operand" "")
5576 (const_string "lea")
5577 (match_operand:SI 2 "incdec_operand" "")
5578 (const_string "incdec")
5579 ]
5580 (const_string "alu")))
5581 (set_attr "mode" "SI")])
58787064 5582
9b70259d
JH
5583;; Convert lea to the lea pattern to avoid flags dependency.
5584(define_split
5585 [(set (match_operand 0 "register_operand" "")
5586 (plus (match_operand 1 "register_operand" "")
5587 (match_operand 2 "nonmemory_operand" "")))
8bc527af 5588 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
5589 "reload_completed
5590 && true_regnum (operands[0]) != true_regnum (operands[1])"
5591 [(const_int 0)]
9b70259d
JH
5592{
5593 rtx pat;
5594 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5595 may confuse gen_lowpart. */
5596 if (GET_MODE (operands[0]) != Pmode)
5597 {
5598 operands[1] = gen_lowpart (Pmode, operands[1]);
5599 operands[2] = gen_lowpart (Pmode, operands[2]);
5600 }
5601 operands[0] = gen_lowpart (SImode, operands[0]);
5602 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5603 if (Pmode != SImode)
5604 pat = gen_rtx_SUBREG (SImode, pat, 0);
5605 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5606 DONE;
0f40f9f7 5607})
9b70259d
JH
5608
5609;; It may seem that nonimmediate operand is proper one for operand 1.
5610;; The addsi_1 pattern allows nonimmediate operand at that place and
5611;; we take care in ix86_binary_operator_ok to not allow two memory
5612;; operands so proper swapping will be done in reload. This allow
5613;; patterns constructed from addsi_1 to match.
5614(define_insn "addsi_1_zext"
5615 [(set (match_operand:DI 0 "register_operand" "=r,r")
5616 (zero_extend:DI
5617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
9a9286af 5618 (match_operand:SI 2 "general_operand" "rmni,lni"))))
8bc527af 5619 (clobber (reg:CC FLAGS_REG))]
9b70259d 5620 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
886c62d1 5621{
e075ae69 5622 switch (get_attr_type (insn))
7c802a40 5623 {
9b70259d
JH
5624 case TYPE_LEA:
5625 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 5626 return "lea{l}\t{%a2, %k0|%k0, %a2}";
9b70259d 5627
e075ae69
RH
5628 case TYPE_INCDEC:
5629 if (operands[2] == const1_rtx)
0f40f9f7 5630 return "inc{l}\t%k0";
9b70259d 5631 else if (operands[2] == constm1_rtx)
0f40f9f7 5632 return "dec{l}\t%k0";
9b70259d
JH
5633 else
5634 abort();
5635
5636 default:
5637 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5638 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5639 if (GET_CODE (operands[2]) == CONST_INT
5640 && (INTVAL (operands[2]) == 128
5641 || (INTVAL (operands[2]) < 0
5642 && INTVAL (operands[2]) != -128)))
5643 {
5644 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5645 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 5646 }
0f40f9f7 5647 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 5648 }
0f40f9f7 5649}
9b70259d
JH
5650 [(set (attr "type")
5651 (cond [(eq_attr "alternative" "1")
5652 (const_string "lea")
5653 ; Current assemblers are broken and do not allow @GOTOFF in
5654 ; ought but a memory context.
5655 (match_operand:SI 2 "pic_symbolic_operand" "")
5656 (const_string "lea")
5657 (match_operand:SI 2 "incdec_operand" "")
5658 (const_string "incdec")
5659 ]
5660 (const_string "alu")))
5661 (set_attr "mode" "SI")])
5662
5663;; Convert lea to the lea pattern to avoid flags dependency.
5664(define_split
5665 [(set (match_operand:DI 0 "register_operand" "")
5666 (zero_extend:DI
5667 (plus:SI (match_operand:SI 1 "register_operand" "")
5668 (match_operand:SI 2 "nonmemory_operand" ""))))
8bc527af 5669 (clobber (reg:CC FLAGS_REG))]
bc8a6d63 5670 "TARGET_64BIT && reload_completed
9b70259d
JH
5671 && true_regnum (operands[0]) != true_regnum (operands[1])"
5672 [(set (match_dup 0)
5673 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
9b70259d
JH
5674{
5675 operands[1] = gen_lowpart (Pmode, operands[1]);
5676 operands[2] = gen_lowpart (Pmode, operands[2]);
0f40f9f7 5677})
9b70259d
JH
5678
5679(define_insn "*addsi_2"
42fabf21 5680 [(set (reg FLAGS_REG)
9b70259d
JH
5681 (compare
5682 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5683 (match_operand:SI 2 "general_operand" "rmni,rni"))
5684 (const_int 0)))
5685 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5686 (plus:SI (match_dup 1) (match_dup 2)))]
5687 "ix86_match_ccmode (insn, CCGOCmode)
5688 && ix86_binary_operator_ok (PLUS, SImode, operands)
5689 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5690 ought but a memory context. */
9b70259d 5691 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
5692{
5693 switch (get_attr_type (insn))
5694 {
5695 case TYPE_INCDEC:
5696 if (! rtx_equal_p (operands[0], operands[1]))
5697 abort ();
5698 if (operands[2] == const1_rtx)
0f40f9f7 5699 return "inc{l}\t%0";
9b70259d 5700 else if (operands[2] == constm1_rtx)
0f40f9f7 5701 return "dec{l}\t%0";
9b70259d
JH
5702 else
5703 abort();
5704
5705 default:
5706 if (! rtx_equal_p (operands[0], operands[1]))
5707 abort ();
5708 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5709 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5710 if (GET_CODE (operands[2]) == CONST_INT
5711 && (INTVAL (operands[2]) == 128
5712 || (INTVAL (operands[2]) < 0
5713 && INTVAL (operands[2]) != -128)))
5714 {
5715 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5716 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5717 }
0f40f9f7 5718 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 5719 }
0f40f9f7 5720}
9b70259d
JH
5721 [(set (attr "type")
5722 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5723 (const_string "incdec")
5724 (const_string "alu")))
5725 (set_attr "mode" "SI")])
5726
5727;; See comment for addsi_1_zext why we do use nonimmediate_operand
5728(define_insn "*addsi_2_zext"
42fabf21 5729 [(set (reg FLAGS_REG)
9b70259d
JH
5730 (compare
5731 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5732 (match_operand:SI 2 "general_operand" "rmni"))
5733 (const_int 0)))
5734 (set (match_operand:DI 0 "register_operand" "=r")
5735 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5736 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5737 && ix86_binary_operator_ok (PLUS, SImode, operands)
5738 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5739 ought but a memory context. */
9b70259d 5740 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
5741{
5742 switch (get_attr_type (insn))
5743 {
5744 case TYPE_INCDEC:
5745 if (operands[2] == const1_rtx)
0f40f9f7 5746 return "inc{l}\t%k0";
9b70259d 5747 else if (operands[2] == constm1_rtx)
0f40f9f7 5748 return "dec{l}\t%k0";
9b70259d
JH
5749 else
5750 abort();
5751
5752 default:
5753 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5754 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5755 if (GET_CODE (operands[2]) == CONST_INT
5756 && (INTVAL (operands[2]) == 128
5757 || (INTVAL (operands[2]) < 0
5758 && INTVAL (operands[2]) != -128)))
5759 {
5760 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5761 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 5762 }
0f40f9f7 5763 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 5764 }
0f40f9f7 5765}
9b70259d
JH
5766 [(set (attr "type")
5767 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5768 (const_string "incdec")
5769 (const_string "alu")))
5770 (set_attr "mode" "SI")])
5771
5772(define_insn "*addsi_3"
42fabf21 5773 [(set (reg FLAGS_REG)
9b70259d
JH
5774 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5775 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5776 (clobber (match_scratch:SI 0 "=r"))]
5777 "ix86_match_ccmode (insn, CCZmode)
5778 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5779 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5780 ought but a memory context. */
9b70259d 5781 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
5782{
5783 switch (get_attr_type (insn))
5784 {
5785 case TYPE_INCDEC:
5786 if (! rtx_equal_p (operands[0], operands[1]))
5787 abort ();
5788 if (operands[2] == const1_rtx)
0f40f9f7 5789 return "inc{l}\t%0";
9b70259d 5790 else if (operands[2] == constm1_rtx)
0f40f9f7 5791 return "dec{l}\t%0";
9b70259d
JH
5792 else
5793 abort();
5794
5795 default:
5796 if (! rtx_equal_p (operands[0], operands[1]))
5797 abort ();
5798 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5800 if (GET_CODE (operands[2]) == CONST_INT
5801 && (INTVAL (operands[2]) == 128
5802 || (INTVAL (operands[2]) < 0
5803 && INTVAL (operands[2]) != -128)))
5804 {
5805 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5806 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5807 }
0f40f9f7 5808 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 5809 }
0f40f9f7 5810}
9b70259d
JH
5811 [(set (attr "type")
5812 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5813 (const_string "incdec")
5814 (const_string "alu")))
5815 (set_attr "mode" "SI")])
5816
5817;; See comment for addsi_1_zext why we do use nonimmediate_operand
5818(define_insn "*addsi_3_zext"
42fabf21 5819 [(set (reg FLAGS_REG)
9b70259d
JH
5820 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5821 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5822 (set (match_operand:DI 0 "register_operand" "=r")
5823 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5824 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5825 && ix86_binary_operator_ok (PLUS, SImode, operands)
5826 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5827 ought but a memory context. */
9b70259d 5828 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
5829{
5830 switch (get_attr_type (insn))
5831 {
5832 case TYPE_INCDEC:
5833 if (operands[2] == const1_rtx)
0f40f9f7 5834 return "inc{l}\t%k0";
9b70259d 5835 else if (operands[2] == constm1_rtx)
0f40f9f7 5836 return "dec{l}\t%k0";
9b70259d
JH
5837 else
5838 abort();
5839
5840 default:
5841 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5843 if (GET_CODE (operands[2]) == CONST_INT
5844 && (INTVAL (operands[2]) == 128
5845 || (INTVAL (operands[2]) < 0
5846 && INTVAL (operands[2]) != -128)))
5847 {
5848 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5849 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 5850 }
0f40f9f7 5851 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 5852 }
0f40f9f7 5853}
9b70259d
JH
5854 [(set (attr "type")
5855 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5856 (const_string "incdec")
5857 (const_string "alu")))
5858 (set_attr "mode" "SI")])
5859
4aae8a9a 5860; For comparisons against 1, -1 and 128, we may generate better code
9b70259d
JH
5861; by converting cmp to add, inc or dec as done by peephole2. This pattern
5862; is matched then. We can't accept general immediate, because for
5863; case of overflows, the result is messed up.
5864; This pattern also don't hold of 0x80000000, since the value overflows
5865; when negated.
d6a7951f 5866; Also carry flag is reversed compared to cmp, so this conversion is valid
9b70259d
JH
5867; only for comparisons not depending on it.
5868(define_insn "*addsi_4"
42fabf21 5869 [(set (reg FLAGS_REG)
9b70259d
JH
5870 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5871 (match_operand:SI 2 "const_int_operand" "n")))
5872 (clobber (match_scratch:SI 0 "=rm"))]
5873 "ix86_match_ccmode (insn, CCGCmode)
5874 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
9b70259d
JH
5875{
5876 switch (get_attr_type (insn))
5877 {
5878 case TYPE_INCDEC:
5879 if (operands[2] == constm1_rtx)
0f40f9f7 5880 return "inc{l}\t%0";
9b70259d 5881 else if (operands[2] == const1_rtx)
0f40f9f7 5882 return "dec{l}\t%0";
9b70259d
JH
5883 else
5884 abort();
5885
5886 default:
5887 if (! rtx_equal_p (operands[0], operands[1]))
5888 abort ();
5889 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5890 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5891 if ((INTVAL (operands[2]) == -128
5892 || (INTVAL (operands[2]) > 0
5893 && INTVAL (operands[2]) != 128)))
0f40f9f7 5894 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5895 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5896 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 5897 }
0f40f9f7 5898}
9b70259d
JH
5899 [(set (attr "type")
5900 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "SI")])
5904
5905(define_insn "*addsi_5"
42fabf21 5906 [(set (reg FLAGS_REG)
9b70259d
JH
5907 (compare
5908 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5909 (match_operand:SI 2 "general_operand" "rmni"))
5910 (const_int 0)))
5911 (clobber (match_scratch:SI 0 "=r"))]
5912 "ix86_match_ccmode (insn, CCGOCmode)
5913 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5914 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5915 ought but a memory context. */
9b70259d 5916 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
5917{
5918 switch (get_attr_type (insn))
5919 {
5920 case TYPE_INCDEC:
5921 if (! rtx_equal_p (operands[0], operands[1]))
5922 abort ();
5923 if (operands[2] == const1_rtx)
0f40f9f7 5924 return "inc{l}\t%0";
9b70259d 5925 else if (operands[2] == constm1_rtx)
0f40f9f7 5926 return "dec{l}\t%0";
9b70259d
JH
5927 else
5928 abort();
5929
5930 default:
5931 if (! rtx_equal_p (operands[0], operands[1]))
5932 abort ();
5933 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5934 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5935 if (GET_CODE (operands[2]) == CONST_INT
5936 && (INTVAL (operands[2]) == 128
5937 || (INTVAL (operands[2]) < 0
5938 && INTVAL (operands[2]) != -128)))
5939 {
5940 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5941 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5942 }
0f40f9f7 5943 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 5944 }
0f40f9f7 5945}
9b70259d
JH
5946 [(set (attr "type")
5947 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5948 (const_string "incdec")
5949 (const_string "alu")))
5950 (set_attr "mode" "SI")])
5951
5952(define_expand "addhi3"
5953 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5954 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5955 (match_operand:HI 2 "general_operand" "")))
8bc527af 5956 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
5957 "TARGET_HIMODE_MATH"
5958 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5959
5960;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5961;; type optimizations enabled by define-splits. This is not important
5962;; for PII, and in fact harmful because of partial register stalls.
5963
5964(define_insn "*addhi_1_lea"
5965 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5966 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
9a9286af 5967 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
8bc527af 5968 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
5969 "!TARGET_PARTIAL_REG_STALL
5970 && ix86_binary_operator_ok (PLUS, HImode, operands)"
9b70259d
JH
5971{
5972 switch (get_attr_type (insn))
5973 {
5974 case TYPE_LEA:
0f40f9f7 5975 return "#";
9b70259d
JH
5976 case TYPE_INCDEC:
5977 if (operands[2] == const1_rtx)
0f40f9f7 5978 return "inc{w}\t%0";
2f41793e 5979 else if (operands[2] == constm1_rtx)
0f40f9f7 5980 return "dec{w}\t%0";
9b70259d
JH
5981 abort();
5982
5983 default:
5984 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5985 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5986 if (GET_CODE (operands[2]) == CONST_INT
5987 && (INTVAL (operands[2]) == 128
5988 || (INTVAL (operands[2]) < 0
5989 && INTVAL (operands[2]) != -128)))
5990 {
5991 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5992 return "sub{w}\t{%2, %0|%0, %2}";
9b70259d 5993 }
0f40f9f7 5994 return "add{w}\t{%2, %0|%0, %2}";
9b70259d 5995 }
0f40f9f7 5996}
9b70259d
JH
5997 [(set (attr "type")
5998 (if_then_else (eq_attr "alternative" "2")
5999 (const_string "lea")
6000 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6001 (const_string "incdec")
6002 (const_string "alu"))))
6003 (set_attr "mode" "HI,HI,SI")])
6004
6005(define_insn "*addhi_1"
6006 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6007 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6008 (match_operand:HI 2 "general_operand" "ri,rm")))
8bc527af 6009 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
6010 "TARGET_PARTIAL_REG_STALL
6011 && ix86_binary_operator_ok (PLUS, HImode, operands)"
9b70259d
JH
6012{
6013 switch (get_attr_type (insn))
6014 {
6015 case TYPE_INCDEC:
6016 if (operands[2] == const1_rtx)
0f40f9f7 6017 return "inc{w}\t%0";
2f41793e 6018 else if (operands[2] == constm1_rtx)
0f40f9f7 6019 return "dec{w}\t%0";
e075ae69 6020 abort();
7c802a40 6021
e075ae69
RH
6022 default:
6023 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6024 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6025 if (GET_CODE (operands[2]) == CONST_INT
6026 && (INTVAL (operands[2]) == 128
6027 || (INTVAL (operands[2]) < 0
6028 && INTVAL (operands[2]) != -128)))
6029 {
6030 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6031 return "sub{w}\t{%2, %0|%0, %2}";
e075ae69 6032 }
0f40f9f7 6033 return "add{w}\t{%2, %0|%0, %2}";
7c802a40 6034 }
0f40f9f7 6035}
e075ae69
RH
6036 [(set (attr "type")
6037 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6038 (const_string "incdec")
6ef67412
JH
6039 (const_string "alu")))
6040 (set_attr "mode" "HI")])
7c802a40 6041
e075ae69 6042(define_insn "*addhi_2"
42fabf21 6043 [(set (reg FLAGS_REG)
16189740 6044 (compare
e075ae69
RH
6045 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6046 (match_operand:HI 2 "general_operand" "rmni,rni"))
6047 (const_int 0)))
6048 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6049 (plus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 6050 "ix86_match_ccmode (insn, CCGOCmode)
16189740 6051 && ix86_binary_operator_ok (PLUS, HImode, operands)"
e075ae69
RH
6052{
6053 switch (get_attr_type (insn))
b980bec0 6054 {
e075ae69
RH
6055 case TYPE_INCDEC:
6056 if (operands[2] == const1_rtx)
0f40f9f7 6057 return "inc{w}\t%0";
2f41793e 6058 else if (operands[2] == constm1_rtx)
0f40f9f7 6059 return "dec{w}\t%0";
e075ae69 6060 abort();
b980bec0 6061
e075ae69
RH
6062 default:
6063 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6065 if (GET_CODE (operands[2]) == CONST_INT
6066 && (INTVAL (operands[2]) == 128
6067 || (INTVAL (operands[2]) < 0
6068 && INTVAL (operands[2]) != -128)))
6069 {
6070 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6071 return "sub{w}\t{%2, %0|%0, %2}";
e075ae69 6072 }
0f40f9f7 6073 return "add{w}\t{%2, %0|%0, %2}";
b980bec0 6074 }
0f40f9f7 6075}
e075ae69
RH
6076 [(set (attr "type")
6077 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078 (const_string "incdec")
6ef67412
JH
6079 (const_string "alu")))
6080 (set_attr "mode" "HI")])
e075ae69
RH
6081
6082(define_insn "*addhi_3"
42fabf21 6083 [(set (reg FLAGS_REG)
7e08e190
JH
6084 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6085 (match_operand:HI 1 "nonimmediate_operand" "%0")))
d90ffc8d 6086 (clobber (match_scratch:HI 0 "=r"))]
7e08e190 6087 "ix86_match_ccmode (insn, CCZmode)
d90ffc8d 6088 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
d90ffc8d
JH
6089{
6090 switch (get_attr_type (insn))
6091 {
6092 case TYPE_INCDEC:
6093 if (operands[2] == const1_rtx)
0f40f9f7 6094 return "inc{w}\t%0";
2f41793e 6095 else if (operands[2] == constm1_rtx)
0f40f9f7 6096 return "dec{w}\t%0";
d90ffc8d
JH
6097 abort();
6098
6099 default:
6100 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6102 if (GET_CODE (operands[2]) == CONST_INT
6103 && (INTVAL (operands[2]) == 128
6104 || (INTVAL (operands[2]) < 0
6105 && INTVAL (operands[2]) != -128)))
6106 {
6107 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6108 return "sub{w}\t{%2, %0|%0, %2}";
d90ffc8d 6109 }
0f40f9f7 6110 return "add{w}\t{%2, %0|%0, %2}";
d90ffc8d 6111 }
0f40f9f7 6112}
d90ffc8d
JH
6113 [(set (attr "type")
6114 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6115 (const_string "incdec")
6116 (const_string "alu")))
6117 (set_attr "mode" "HI")])
6118
7e08e190 6119; See comments above addsi_3_imm for details.
d90ffc8d 6120(define_insn "*addhi_4"
42fabf21 6121 [(set (reg FLAGS_REG)
7e08e190
JH
6122 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6123 (match_operand:HI 2 "const_int_operand" "n")))
6124 (clobber (match_scratch:HI 0 "=rm"))]
6125 "ix86_match_ccmode (insn, CCGCmode)
6126 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7e08e190
JH
6127{
6128 switch (get_attr_type (insn))
6129 {
6130 case TYPE_INCDEC:
2f41793e 6131 if (operands[2] == constm1_rtx)
0f40f9f7 6132 return "inc{w}\t%0";
7e08e190 6133 else if (operands[2] == const1_rtx)
0f40f9f7 6134 return "dec{w}\t%0";
7e08e190
JH
6135 else
6136 abort();
6137
6138 default:
6139 if (! rtx_equal_p (operands[0], operands[1]))
6140 abort ();
6141 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6143 if ((INTVAL (operands[2]) == -128
6144 || (INTVAL (operands[2]) > 0
6145 && INTVAL (operands[2]) != 128)))
0f40f9f7 6146 return "sub{w}\t{%2, %0|%0, %2}";
7e08e190 6147 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6148 return "add{w}\t{%2, %0|%0, %2}";
7e08e190 6149 }
0f40f9f7 6150}
7e08e190
JH
6151 [(set (attr "type")
6152 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6153 (const_string "incdec")
6154 (const_string "alu")))
6155 (set_attr "mode" "SI")])
b980bec0 6156
d90ffc8d 6157
7e08e190 6158(define_insn "*addhi_5"
42fabf21 6159 [(set (reg FLAGS_REG)
9076b9c1
JH
6160 (compare
6161 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6162 (match_operand:HI 2 "general_operand" "rmni"))
6163 (const_int 0)))
6164 (clobber (match_scratch:HI 0 "=r"))]
6165 "ix86_match_ccmode (insn, CCGOCmode)
6166 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9076b9c1
JH
6167{
6168 switch (get_attr_type (insn))
6169 {
6170 case TYPE_INCDEC:
6171 if (operands[2] == const1_rtx)
0f40f9f7 6172 return "inc{w}\t%0";
2f41793e 6173 else if (operands[2] == constm1_rtx)
0f40f9f7 6174 return "dec{w}\t%0";
9076b9c1
JH
6175 abort();
6176
6177 default:
6178 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6179 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6180 if (GET_CODE (operands[2]) == CONST_INT
6181 && (INTVAL (operands[2]) == 128
6182 || (INTVAL (operands[2]) < 0
6183 && INTVAL (operands[2]) != -128)))
6184 {
6185 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6186 return "sub{w}\t{%2, %0|%0, %2}";
9076b9c1 6187 }
0f40f9f7 6188 return "add{w}\t{%2, %0|%0, %2}";
9076b9c1 6189 }
0f40f9f7 6190}
9076b9c1
JH
6191 [(set (attr "type")
6192 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6193 (const_string "incdec")
6194 (const_string "alu")))
6195 (set_attr "mode" "HI")])
6196
e075ae69 6197(define_expand "addqi3"
4cbfbb1b
JH
6198 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6199 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
e075ae69 6200 (match_operand:QI 2 "general_operand" "")))
8bc527af 6201 (clobber (reg:CC FLAGS_REG))])]
d9f32422 6202 "TARGET_QIMODE_MATH"
e075ae69
RH
6203 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6204
6205;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
6206(define_insn "*addqi_1_lea"
6207 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6208 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
9a9286af 6209 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
8bc527af 6210 (clobber (reg:CC FLAGS_REG))]
58787064
JH
6211 "!TARGET_PARTIAL_REG_STALL
6212 && ix86_binary_operator_ok (PLUS, QImode, operands)"
58787064
JH
6213{
6214 int widen = (which_alternative == 2);
6215 switch (get_attr_type (insn))
6216 {
6217 case TYPE_LEA:
0f40f9f7 6218 return "#";
58787064
JH
6219 case TYPE_INCDEC:
6220 if (operands[2] == const1_rtx)
0f40f9f7 6221 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
2f41793e 6222 else if (operands[2] == constm1_rtx)
0f40f9f7 6223 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
58787064
JH
6224 abort();
6225
6226 default:
6227 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6228 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6229 if (GET_CODE (operands[2]) == CONST_INT
6230 && (INTVAL (operands[2]) == 128
6231 || (INTVAL (operands[2]) < 0
6232 && INTVAL (operands[2]) != -128)))
6233 {
6234 operands[2] = GEN_INT (-INTVAL (operands[2]));
6235 if (widen)
0f40f9f7 6236 return "sub{l}\t{%2, %k0|%k0, %2}";
58787064 6237 else
0f40f9f7 6238 return "sub{b}\t{%2, %0|%0, %2}";
58787064
JH
6239 }
6240 if (widen)
0f40f9f7 6241 return "add{l}\t{%k2, %k0|%k0, %k2}";
58787064 6242 else
0f40f9f7 6243 return "add{b}\t{%2, %0|%0, %2}";
58787064 6244 }
0f40f9f7 6245}
58787064
JH
6246 [(set (attr "type")
6247 (if_then_else (eq_attr "alternative" "3")
6248 (const_string "lea")
adc88131 6249 (if_then_else (match_operand:QI 2 "incdec_operand" "")
58787064
JH
6250 (const_string "incdec")
6251 (const_string "alu"))))
adc88131 6252 (set_attr "mode" "QI,QI,SI,SI")])
58787064 6253
e075ae69 6254(define_insn "*addqi_1"
7c6b971d 6255 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 6256 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 6257 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8bc527af 6258 (clobber (reg:CC FLAGS_REG))]
58787064
JH
6259 "TARGET_PARTIAL_REG_STALL
6260 && ix86_binary_operator_ok (PLUS, QImode, operands)"
e075ae69
RH
6261{
6262 int widen = (which_alternative == 2);
6263 switch (get_attr_type (insn))
5bc7cd8e 6264 {
e075ae69
RH
6265 case TYPE_INCDEC:
6266 if (operands[2] == const1_rtx)
0f40f9f7 6267 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
2f41793e 6268 else if (operands[2] == constm1_rtx)
0f40f9f7 6269 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
e075ae69 6270 abort();
5bc7cd8e 6271
e075ae69
RH
6272 default:
6273 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6274 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6275 if (GET_CODE (operands[2]) == CONST_INT
6276 && (INTVAL (operands[2]) == 128
6277 || (INTVAL (operands[2]) < 0
6278 && INTVAL (operands[2]) != -128)))
5bc7cd8e 6279 {
e075ae69
RH
6280 operands[2] = GEN_INT (-INTVAL (operands[2]));
6281 if (widen)
0f40f9f7 6282 return "sub{l}\t{%2, %k0|%k0, %2}";
e075ae69 6283 else
0f40f9f7 6284 return "sub{b}\t{%2, %0|%0, %2}";
5bc7cd8e 6285 }
e075ae69 6286 if (widen)
0f40f9f7 6287 return "add{l}\t{%k2, %k0|%k0, %k2}";
e075ae69 6288 else
0f40f9f7 6289 return "add{b}\t{%2, %0|%0, %2}";
5bc7cd8e 6290 }
0f40f9f7 6291}
e075ae69
RH
6292 [(set (attr "type")
6293 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294 (const_string "incdec")
6ef67412
JH
6295 (const_string "alu")))
6296 (set_attr "mode" "QI,QI,SI")])
e075ae69 6297
2f41793e
JH
6298(define_insn "*addqi_1_slp"
6299 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1b245ade
JH
6300 (plus:QI (match_dup 0)
6301 (match_operand:QI 1 "general_operand" "qn,qnm")))
8bc527af 6302 (clobber (reg:CC FLAGS_REG))]
2f41793e 6303 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade 6304 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f41793e
JH
6305{
6306 switch (get_attr_type (insn))
6307 {
6308 case TYPE_INCDEC:
95199202 6309 if (operands[1] == const1_rtx)
2f41793e 6310 return "inc{b}\t%0";
95199202 6311 else if (operands[1] == constm1_rtx)
2f41793e
JH
6312 return "dec{b}\t%0";
6313 abort();
6314
6315 default:
6316 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
95199202
JH
6317 if (GET_CODE (operands[1]) == CONST_INT
6318 && INTVAL (operands[1]) < 0)
2f41793e 6319 {
79551a56 6320 operands[1] = GEN_INT (-INTVAL (operands[1]));
1b245ade 6321 return "sub{b}\t{%1, %0|%0, %1}";
2f41793e 6322 }
1b245ade 6323 return "add{b}\t{%1, %0|%0, %1}";
2f41793e
JH
6324 }
6325}
6326 [(set (attr "type")
ba3ed8d8 6327 (if_then_else (match_operand:QI 1 "incdec_operand" "")
2f41793e 6328 (const_string "incdec")
95199202 6329 (const_string "alu1")))
2f41793e
JH
6330 (set_attr "mode" "QI")])
6331
e075ae69 6332(define_insn "*addqi_2"
42fabf21 6333 [(set (reg FLAGS_REG)
16189740 6334 (compare
e075ae69
RH
6335 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6336 (match_operand:QI 2 "general_operand" "qmni,qni"))
6337 (const_int 0)))
6338 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6339 (plus:QI (match_dup 1) (match_dup 2)))]
9076b9c1 6340 "ix86_match_ccmode (insn, CCGOCmode)
16189740 6341 && ix86_binary_operator_ok (PLUS, QImode, operands)"
e075ae69
RH
6342{
6343 switch (get_attr_type (insn))
6344 {
6345 case TYPE_INCDEC:
6346 if (operands[2] == const1_rtx)
0f40f9f7 6347 return "inc{b}\t%0";
e075ae69
RH
6348 else if (operands[2] == constm1_rtx
6349 || (GET_CODE (operands[2]) == CONST_INT
6350 && INTVAL (operands[2]) == 255))
0f40f9f7 6351 return "dec{b}\t%0";
e075ae69 6352 abort();
5bc7cd8e 6353
e075ae69
RH
6354 default:
6355 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6356 if (GET_CODE (operands[2]) == CONST_INT
6357 && INTVAL (operands[2]) < 0)
6358 {
6359 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6360 return "sub{b}\t{%2, %0|%0, %2}";
e075ae69 6361 }
0f40f9f7 6362 return "add{b}\t{%2, %0|%0, %2}";
e075ae69 6363 }
0f40f9f7 6364}
e075ae69
RH
6365 [(set (attr "type")
6366 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6367 (const_string "incdec")
6ef67412
JH
6368 (const_string "alu")))
6369 (set_attr "mode" "QI")])
e075ae69
RH
6370
6371(define_insn "*addqi_3"
42fabf21 6372 [(set (reg FLAGS_REG)
7e08e190
JH
6373 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6374 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6375 (clobber (match_scratch:QI 0 "=q"))]
6376 "ix86_match_ccmode (insn, CCZmode)
d90ffc8d 6377 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
d90ffc8d
JH
6378{
6379 switch (get_attr_type (insn))
6380 {
6381 case TYPE_INCDEC:
6382 if (operands[2] == const1_rtx)
0f40f9f7 6383 return "inc{b}\t%0";
d90ffc8d
JH
6384 else if (operands[2] == constm1_rtx
6385 || (GET_CODE (operands[2]) == CONST_INT
6386 && INTVAL (operands[2]) == 255))
0f40f9f7 6387 return "dec{b}\t%0";
d90ffc8d
JH
6388 abort();
6389
6390 default:
6391 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6392 if (GET_CODE (operands[2]) == CONST_INT
6393 && INTVAL (operands[2]) < 0)
6394 {
6395 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6396 return "sub{b}\t{%2, %0|%0, %2}";
d90ffc8d 6397 }
0f40f9f7 6398 return "add{b}\t{%2, %0|%0, %2}";
d90ffc8d 6399 }
0f40f9f7 6400}
d90ffc8d
JH
6401 [(set (attr "type")
6402 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6403 (const_string "incdec")
6404 (const_string "alu")))
6405 (set_attr "mode" "QI")])
6406
7e08e190 6407; See comments above addsi_3_imm for details.
d90ffc8d 6408(define_insn "*addqi_4"
42fabf21 6409 [(set (reg FLAGS_REG)
7e08e190
JH
6410 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6411 (match_operand:QI 2 "const_int_operand" "n")))
6412 (clobber (match_scratch:QI 0 "=qm"))]
6413 "ix86_match_ccmode (insn, CCGCmode)
6414 && (INTVAL (operands[2]) & 0xff) != 0x80"
7e08e190
JH
6415{
6416 switch (get_attr_type (insn))
6417 {
6418 case TYPE_INCDEC:
6419 if (operands[2] == constm1_rtx
6420 || (GET_CODE (operands[2]) == CONST_INT
6421 && INTVAL (operands[2]) == 255))
0f40f9f7 6422 return "inc{b}\t%0";
7e08e190 6423 else if (operands[2] == const1_rtx)
0f40f9f7 6424 return "dec{b}\t%0";
7e08e190
JH
6425 else
6426 abort();
6427
6428 default:
6429 if (! rtx_equal_p (operands[0], operands[1]))
6430 abort ();
6431 if (INTVAL (operands[2]) < 0)
6432 {
6433 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6434 return "add{b}\t{%2, %0|%0, %2}";
7e08e190 6435 }
0f40f9f7 6436 return "sub{b}\t{%2, %0|%0, %2}";
7e08e190 6437 }
0f40f9f7 6438}
7e08e190
JH
6439 [(set (attr "type")
6440 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6441 (const_string "incdec")
6442 (const_string "alu")))
6ef67412 6443 (set_attr "mode" "QI")])
886c62d1 6444
9dcbdc7e 6445
d90ffc8d 6446(define_insn "*addqi_5"
42fabf21 6447 [(set (reg FLAGS_REG)
9076b9c1
JH
6448 (compare
6449 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6450 (match_operand:QI 2 "general_operand" "qmni"))
6451 (const_int 0)))
7e08e190 6452 (clobber (match_scratch:QI 0 "=q"))]
9076b9c1
JH
6453 "ix86_match_ccmode (insn, CCGOCmode)
6454 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9076b9c1
JH
6455{
6456 switch (get_attr_type (insn))
6457 {
6458 case TYPE_INCDEC:
6459 if (operands[2] == const1_rtx)
0f40f9f7 6460 return "inc{b}\t%0";
9076b9c1
JH
6461 else if (operands[2] == constm1_rtx
6462 || (GET_CODE (operands[2]) == CONST_INT
6463 && INTVAL (operands[2]) == 255))
0f40f9f7 6464 return "dec{b}\t%0";
9076b9c1
JH
6465 abort();
6466
6467 default:
6468 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6469 if (GET_CODE (operands[2]) == CONST_INT
6470 && INTVAL (operands[2]) < 0)
6471 {
6472 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6473 return "sub{b}\t{%2, %0|%0, %2}";
9076b9c1 6474 }
0f40f9f7 6475 return "add{b}\t{%2, %0|%0, %2}";
9076b9c1 6476 }
0f40f9f7 6477}
9076b9c1
JH
6478 [(set (attr "type")
6479 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6480 (const_string "incdec")
6481 (const_string "alu")))
6482 (set_attr "mode" "QI")])
6483
e075ae69
RH
6484
6485(define_insn "addqi_ext_1"
3522082b 6486 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6487 (const_int 8)
6488 (const_int 8))
6489 (plus:SI
6490 (zero_extract:SI
6491 (match_operand 1 "ext_register_operand" "0")
6492 (const_int 8)
6493 (const_int 8))
3522082b 6494 (match_operand:QI 2 "general_operand" "Qmn")))
8bc527af 6495 (clobber (reg:CC FLAGS_REG))]
d2836273 6496 "!TARGET_64BIT"
d2836273
JH
6497{
6498 switch (get_attr_type (insn))
6499 {
6500 case TYPE_INCDEC:
6501 if (operands[2] == const1_rtx)
0f40f9f7 6502 return "inc{b}\t%h0";
d2836273
JH
6503 else if (operands[2] == constm1_rtx
6504 || (GET_CODE (operands[2]) == CONST_INT
6505 && INTVAL (operands[2]) == 255))
0f40f9f7 6506 return "dec{b}\t%h0";
d2836273
JH
6507 abort();
6508
6509 default:
0f40f9f7 6510 return "add{b}\t{%2, %h0|%h0, %2}";
d2836273 6511 }
0f40f9f7 6512}
d2836273
JH
6513 [(set (attr "type")
6514 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6515 (const_string "incdec")
6516 (const_string "alu")))
6517 (set_attr "mode" "QI")])
6518
6519(define_insn "*addqi_ext_1_rex64"
6520 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6521 (const_int 8)
6522 (const_int 8))
6523 (plus:SI
6524 (zero_extract:SI
6525 (match_operand 1 "ext_register_operand" "0")
6526 (const_int 8)
6527 (const_int 8))
6528 (match_operand:QI 2 "nonmemory_operand" "Qn")))
8bc527af 6529 (clobber (reg:CC FLAGS_REG))]
d2836273 6530 "TARGET_64BIT"
e075ae69
RH
6531{
6532 switch (get_attr_type (insn))
6533 {
6534 case TYPE_INCDEC:
6535 if (operands[2] == const1_rtx)
0f40f9f7 6536 return "inc{b}\t%h0";
e075ae69
RH
6537 else if (operands[2] == constm1_rtx
6538 || (GET_CODE (operands[2]) == CONST_INT
6539 && INTVAL (operands[2]) == 255))
0f40f9f7 6540 return "dec{b}\t%h0";
e075ae69 6541 abort();
886c62d1 6542
e075ae69 6543 default:
0f40f9f7 6544 return "add{b}\t{%2, %h0|%h0, %2}";
e075ae69 6545 }
0f40f9f7 6546}
e075ae69
RH
6547 [(set (attr "type")
6548 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6549 (const_string "incdec")
6ef67412
JH
6550 (const_string "alu")))
6551 (set_attr "mode" "QI")])
e075ae69
RH
6552
6553(define_insn "*addqi_ext_2"
d2836273 6554 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6555 (const_int 8)
6556 (const_int 8))
6557 (plus:SI
6558 (zero_extract:SI
6559 (match_operand 1 "ext_register_operand" "%0")
6560 (const_int 8)
6561 (const_int 8))
6562 (zero_extract:SI
d2836273 6563 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
6564 (const_int 8)
6565 (const_int 8))))
8bc527af 6566 (clobber (reg:CC FLAGS_REG))]
e075ae69 6567 ""
0f40f9f7 6568 "add{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
6569 [(set_attr "type" "alu")
6570 (set_attr "mode" "QI")])
886c62d1 6571
886c62d1
JVA
6572;; The patterns that match these are at the end of this file.
6573
4fb21e90
JVA
6574(define_expand "addxf3"
6575 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
6576 (plus:XF (match_operand:XF 1 "register_operand" "")
6577 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
6578 "TARGET_80387"
6579 "")
6580
886c62d1
JVA
6581(define_expand "adddf3"
6582 [(set (match_operand:DF 0 "register_operand" "")
06a964de 6583 (plus:DF (match_operand:DF 1 "register_operand" "")
886c62d1 6584 (match_operand:DF 2 "nonimmediate_operand" "")))]
965f5423 6585 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
886c62d1
JVA
6586 "")
6587
6588(define_expand "addsf3"
6589 [(set (match_operand:SF 0 "register_operand" "")
06a964de 6590 (plus:SF (match_operand:SF 1 "register_operand" "")
886c62d1 6591 (match_operand:SF 2 "nonimmediate_operand" "")))]
965f5423 6592 "TARGET_80387 || TARGET_SSE_MATH"
886c62d1
JVA
6593 "")
6594\f
e075ae69 6595;; Subtract instructions
a269a03c 6596
e075ae69 6597;; %%% splits for subsidi3
2ae0f82c 6598
9b70259d
JH
6599(define_expand "subdi3"
6600 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6601 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6602 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 6603 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
6604 ""
6605 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6606
6607(define_insn "*subdi3_1"
e075ae69 6608 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4cbfbb1b 6609 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
e075ae69 6610 (match_operand:DI 2 "general_operand" "roiF,riF")))
8bc527af 6611 (clobber (reg:CC FLAGS_REG))]
43146684 6612 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
e075ae69 6613 "#")
9c530261 6614
e075ae69
RH
6615(define_split
6616 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4cbfbb1b 6617 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
e075ae69 6618 (match_operand:DI 2 "general_operand" "")))
8bc527af 6619 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 6620 "!TARGET_64BIT && reload_completed"
8bc527af 6621 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
e075ae69
RH
6622 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6623 (parallel [(set (match_dup 3)
6624 (minus:SI (match_dup 4)
8bc527af 6625 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9dcbdc7e 6626 (match_dup 5))))
8bc527af 6627 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
6628 "split_di (operands+0, 1, operands+0, operands+3);
6629 split_di (operands+1, 1, operands+1, operands+4);
6630 split_di (operands+2, 1, operands+2, operands+5);")
6631
9b70259d
JH
6632(define_insn "subdi3_carry_rex64"
6633 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6634 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
9b74f3ea 6635 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
9b70259d 6636 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
8bc527af 6637 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 6638 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 6639 "sbb{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6640 [(set_attr "type" "alu")
6641 (set_attr "pent_pair" "pu")
9b70259d
JH
6642 (set_attr "mode" "DI")])
6643
6644(define_insn "*subdi_1_rex64"
6645 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6646 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6647 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8bc527af 6648 (clobber (reg:CC FLAGS_REG))]
9b70259d 6649 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 6650 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "DI")])
6653
6654(define_insn "*subdi_2_rex64"
42fabf21 6655 [(set (reg FLAGS_REG)
9b70259d
JH
6656 (compare
6657 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6658 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6659 (const_int 0)))
6660 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6661 (minus:DI (match_dup 1) (match_dup 2)))]
6662 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6663 && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 6664 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6665 [(set_attr "type" "alu")
6666 (set_attr "mode" "DI")])
6667
6668(define_insn "*subdi_3_rex63"
42fabf21 6669 [(set (reg FLAGS_REG)
9b70259d
JH
6670 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6671 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6672 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6673 (minus:DI (match_dup 1) (match_dup 2)))]
6674 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6675 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6676 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6677 [(set_attr "type" "alu")
6678 (set_attr "mode" "DI")])
6679
7b52eede 6680(define_insn "subqi3_carry"
d67e96cf 6681 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7b52eede 6682 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
e6e81735 6683 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
d67e96cf 6684 (match_operand:QI 2 "general_operand" "qi,qm"))))
8bc527af 6685 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
6686 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6687 "sbb{b}\t{%2, %0|%0, %2}"
6688 [(set_attr "type" "alu")
6689 (set_attr "pent_pair" "pu")
7b52eede
JH
6690 (set_attr "mode" "QI")])
6691
6692(define_insn "subhi3_carry"
6693 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6694 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
e6e81735 6695 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7b52eede 6696 (match_operand:HI 2 "general_operand" "ri,rm"))))
8bc527af 6697 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
6698 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6699 "sbb{w}\t{%2, %0|%0, %2}"
6700 [(set_attr "type" "alu")
6701 (set_attr "pent_pair" "pu")
7b52eede 6702 (set_attr "mode" "HI")])
9b70259d 6703
7e08e190 6704(define_insn "subsi3_carry"
e075ae69
RH
6705 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6706 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
e6e81735 6707 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9dcbdc7e 6708 (match_operand:SI 2 "general_operand" "ri,rm"))))
8bc527af 6709 (clobber (reg:CC FLAGS_REG))]
d525dfdf 6710 "ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6711 "sbb{l}\t{%2, %0|%0, %2}"
e075ae69
RH
6712 [(set_attr "type" "alu")
6713 (set_attr "pent_pair" "pu")
6ef67412 6714 (set_attr "mode" "SI")])
886c62d1 6715
9b70259d
JH
6716(define_insn "subsi3_carry_zext"
6717 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6718 (zero_extend:DI
6719 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
e6e81735 6720 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9b70259d 6721 (match_operand:SI 2 "general_operand" "ri,rm")))))
8bc527af 6722 (clobber (reg:CC FLAGS_REG))]
9b70259d 6723 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6724 "sbb{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
6725 [(set_attr "type" "alu")
6726 (set_attr "pent_pair" "pu")
9b70259d
JH
6727 (set_attr "mode" "SI")])
6728
2ae0f82c 6729(define_expand "subsi3"
e075ae69
RH
6730 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6731 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6732 (match_operand:SI 2 "general_operand" "")))
8bc527af 6733 (clobber (reg:CC FLAGS_REG))])]
886c62d1 6734 ""
e075ae69 6735 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
2ae0f82c 6736
e075ae69 6737(define_insn "*subsi_1"
2ae0f82c
SC
6738 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6739 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
e075ae69 6740 (match_operand:SI 2 "general_operand" "ri,rm")))
8bc527af 6741 (clobber (reg:CC FLAGS_REG))]
e075ae69 6742 "ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6743 "sub{l}\t{%2, %0|%0, %2}"
6ef67412
JH
6744 [(set_attr "type" "alu")
6745 (set_attr "mode" "SI")])
e075ae69 6746
9b70259d
JH
6747(define_insn "*subsi_1_zext"
6748 [(set (match_operand:DI 0 "register_operand" "=r")
6749 (zero_extend:DI
6750 (minus:SI (match_operand:SI 1 "register_operand" "0")
6751 (match_operand:SI 2 "general_operand" "rim"))))
8bc527af 6752 (clobber (reg:CC FLAGS_REG))]
9b70259d 6753 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6754 "sub{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
6755 [(set_attr "type" "alu")
6756 (set_attr "mode" "SI")])
6757
e075ae69 6758(define_insn "*subsi_2"
42fabf21 6759 [(set (reg FLAGS_REG)
16189740 6760 (compare
e075ae69
RH
6761 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6762 (match_operand:SI 2 "general_operand" "ri,rm"))
6763 (const_int 0)))
6764 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6765 (minus:SI (match_dup 1) (match_dup 2)))]
9076b9c1 6766 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 6767 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6768 "sub{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
6769 [(set_attr "type" "alu")
6770 (set_attr "mode" "SI")])
6771
9b70259d 6772(define_insn "*subsi_2_zext"
42fabf21 6773 [(set (reg FLAGS_REG)
9b70259d
JH
6774 (compare
6775 (minus:SI (match_operand:SI 1 "register_operand" "0")
6776 (match_operand:SI 2 "general_operand" "rim"))
6777 (const_int 0)))
6778 (set (match_operand:DI 0 "register_operand" "=r")
6779 (zero_extend:DI
6780 (minus:SI (match_dup 1)
6781 (match_dup 2))))]
6782 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6783 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6784 "sub{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
6785 [(set_attr "type" "alu")
6786 (set_attr "mode" "SI")])
6787
d90ffc8d 6788(define_insn "*subsi_3"
42fabf21 6789 [(set (reg FLAGS_REG)
d90ffc8d
JH
6790 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6791 (match_operand:SI 2 "general_operand" "ri,rm")))
6792 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6793 (minus:SI (match_dup 1) (match_dup 2)))]
16189740
RH
6794 "ix86_match_ccmode (insn, CCmode)
6795 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6796 "sub{l}\t{%2, %0|%0, %2}"
6ef67412
JH
6797 [(set_attr "type" "alu")
6798 (set_attr "mode" "SI")])
886c62d1 6799
9b70259d 6800(define_insn "*subsi_3_zext"
42fabf21 6801 [(set (reg FLAGS_REG)
10e9fecc 6802 (compare (match_operand:SI 1 "register_operand" "0")
9b70259d
JH
6803 (match_operand:SI 2 "general_operand" "rim")))
6804 (set (match_operand:DI 0 "register_operand" "=r")
6805 (zero_extend:DI
6806 (minus:SI (match_dup 1)
6807 (match_dup 2))))]
8362f420 6808 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
9b70259d 6809 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6810 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6811 [(set_attr "type" "alu")
6812 (set_attr "mode" "DI")])
6813
2ae0f82c 6814(define_expand "subhi3"
4cbfbb1b 6815 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
e075ae69
RH
6816 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6817 (match_operand:HI 2 "general_operand" "")))
8bc527af 6818 (clobber (reg:CC FLAGS_REG))])]
d9f32422 6819 "TARGET_HIMODE_MATH"
e075ae69 6820 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
2ae0f82c 6821
e075ae69 6822(define_insn "*subhi_1"
2ae0f82c 6823 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
87fd1847 6824 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
e075ae69 6825 (match_operand:HI 2 "general_operand" "ri,rm")))
8bc527af 6826 (clobber (reg:CC FLAGS_REG))]
2ae0f82c 6827 "ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 6828 "sub{w}\t{%2, %0|%0, %2}"
6ef67412
JH
6829 [(set_attr "type" "alu")
6830 (set_attr "mode" "HI")])
e075ae69
RH
6831
6832(define_insn "*subhi_2"
42fabf21 6833 [(set (reg FLAGS_REG)
16189740 6834 (compare
e075ae69
RH
6835 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6836 (match_operand:HI 2 "general_operand" "ri,rm"))
6837 (const_int 0)))
6838 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6839 (minus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 6840 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 6841 && ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 6842 "sub{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
6843 [(set_attr "type" "alu")
6844 (set_attr "mode" "HI")])
6845
6846(define_insn "*subhi_3"
42fabf21 6847 [(set (reg FLAGS_REG)
d90ffc8d
JH
6848 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6849 (match_operand:HI 2 "general_operand" "ri,rm")))
6850 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6851 (minus:HI (match_dup 1) (match_dup 2)))]
16189740
RH
6852 "ix86_match_ccmode (insn, CCmode)
6853 && ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 6854 "sub{w}\t{%2, %0|%0, %2}"
6ef67412
JH
6855 [(set_attr "type" "alu")
6856 (set_attr "mode" "HI")])
886c62d1 6857
2ae0f82c 6858(define_expand "subqi3"
4cbfbb1b
JH
6859 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6860 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
e075ae69 6861 (match_operand:QI 2 "general_operand" "")))
8bc527af 6862 (clobber (reg:CC FLAGS_REG))])]
d9f32422 6863 "TARGET_QIMODE_MATH"
e075ae69 6864 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
2ae0f82c 6865
e075ae69 6866(define_insn "*subqi_1"
2ae0f82c
SC
6867 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6868 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
e075ae69 6869 (match_operand:QI 2 "general_operand" "qn,qmn")))
8bc527af 6870 (clobber (reg:CC FLAGS_REG))]
e075ae69 6871 "ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 6872 "sub{b}\t{%2, %0|%0, %2}"
6ef67412
JH
6873 [(set_attr "type" "alu")
6874 (set_attr "mode" "QI")])
e075ae69 6875
2f41793e
JH
6876(define_insn "*subqi_1_slp"
6877 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1b245ade
JH
6878 (minus:QI (match_dup 0)
6879 (match_operand:QI 1 "general_operand" "qn,qmn")))
8bc527af 6880 (clobber (reg:CC FLAGS_REG))]
2f41793e 6881 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade
JH
6882 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6883 "sub{b}\t{%1, %0|%0, %1}"
95199202 6884 [(set_attr "type" "alu1")
2f41793e
JH
6885 (set_attr "mode" "QI")])
6886
e075ae69 6887(define_insn "*subqi_2"
42fabf21 6888 [(set (reg FLAGS_REG)
16189740 6889 (compare
e075ae69
RH
6890 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6891 (match_operand:QI 2 "general_operand" "qi,qm"))
6892 (const_int 0)))
6893 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6894 (minus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 6895 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 6896 && ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 6897 "sub{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
6898 [(set_attr "type" "alu")
6899 (set_attr "mode" "QI")])
6900
6901(define_insn "*subqi_3"
42fabf21 6902 [(set (reg FLAGS_REG)
d90ffc8d
JH
6903 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6904 (match_operand:QI 2 "general_operand" "qi,qm")))
6905 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6906 (minus:HI (match_dup 1) (match_dup 2)))]
16189740
RH
6907 "ix86_match_ccmode (insn, CCmode)
6908 && ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 6909 "sub{b}\t{%2, %0|%0, %2}"
6ef67412
JH
6910 [(set_attr "type" "alu")
6911 (set_attr "mode" "QI")])
2ae0f82c 6912
886c62d1
JVA
6913;; The patterns that match these are at the end of this file.
6914
4fb21e90
JVA
6915(define_expand "subxf3"
6916 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
6917 (minus:XF (match_operand:XF 1 "register_operand" "")
6918 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
6919 "TARGET_80387"
6920 "")
6921
886c62d1
JVA
6922(define_expand "subdf3"
6923 [(set (match_operand:DF 0 "register_operand" "")
06a964de 6924 (minus:DF (match_operand:DF 1 "register_operand" "")
886c62d1 6925 (match_operand:DF 2 "nonimmediate_operand" "")))]
965f5423 6926 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
886c62d1
JVA
6927 "")
6928
6929(define_expand "subsf3"
6930 [(set (match_operand:SF 0 "register_operand" "")
06a964de 6931 (minus:SF (match_operand:SF 1 "register_operand" "")
886c62d1 6932 (match_operand:SF 2 "nonimmediate_operand" "")))]
965f5423 6933 "TARGET_80387 || TARGET_SSE_MATH"
886c62d1
JVA
6934 "")
6935\f
e075ae69 6936;; Multiply instructions
886c62d1 6937
9b70259d
JH
6938(define_expand "muldi3"
6939 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6940 (mult:DI (match_operand:DI 1 "register_operand" "")
6941 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 6942 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
6943 "TARGET_64BIT"
6944 "")
6945
6946(define_insn "*muldi3_1_rex64"
6947 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
f56e86bd 6948 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
9b70259d 6949 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
8bc527af 6950 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
6951 "TARGET_64BIT
6952 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9b70259d 6953 "@
0f40f9f7
ZW
6954 imul{q}\t{%2, %1, %0|%0, %1, %2}
6955 imul{q}\t{%2, %1, %0|%0, %1, %2}
6956 imul{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6957 [(set_attr "type" "imul")
6958 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
6959 (set (attr "athlon_decode")
6960 (cond [(eq_attr "cpu" "athlon")
6961 (const_string "vector")
6962 (eq_attr "alternative" "1")
6963 (const_string "vector")
6964 (and (eq_attr "alternative" "2")
6965 (match_operand 1 "memory_operand" ""))
6966 (const_string "vector")]
6967 (const_string "direct")))
9b70259d
JH
6968 (set_attr "mode" "DI")])
6969
d525dfdf
JH
6970(define_expand "mulsi3"
6971 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6972 (mult:SI (match_operand:SI 1 "register_operand" "")
6973 (match_operand:SI 2 "general_operand" "")))
8bc527af 6974 (clobber (reg:CC FLAGS_REG))])]
d525dfdf
JH
6975 ""
6976 "")
6977
6978(define_insn "*mulsi3_1"
e075ae69 6979 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
f56e86bd 6980 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
e075ae69 6981 (match_operand:SI 2 "general_operand" "K,i,mr")))
8bc527af 6982 (clobber (reg:CC FLAGS_REG))]
d525dfdf 6983 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
e075ae69 6984 "@
0f40f9f7
ZW
6985 imul{l}\t{%2, %1, %0|%0, %1, %2}
6986 imul{l}\t{%2, %1, %0|%0, %1, %2}
6987 imul{l}\t{%2, %0|%0, %2}"
e075ae69 6988 [(set_attr "type" "imul")
6ef67412 6989 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
6990 (set (attr "athlon_decode")
6991 (cond [(eq_attr "cpu" "athlon")
6992 (const_string "vector")
6993 (eq_attr "alternative" "1")
6994 (const_string "vector")
6995 (and (eq_attr "alternative" "2")
6996 (match_operand 1 "memory_operand" ""))
6997 (const_string "vector")]
6998 (const_string "direct")))
6ef67412 6999 (set_attr "mode" "SI")])
886c62d1 7000
9b70259d
JH
7001(define_insn "*mulsi3_1_zext"
7002 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7003 (zero_extend:DI
f56e86bd 7004 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9b70259d 7005 (match_operand:SI 2 "general_operand" "K,i,mr"))))
8bc527af 7006 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
7007 "TARGET_64BIT
7008 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9b70259d 7009 "@
0f40f9f7
ZW
7010 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7011 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7012 imul{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
7013 [(set_attr "type" "imul")
7014 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
7015 (set (attr "athlon_decode")
7016 (cond [(eq_attr "cpu" "athlon")
7017 (const_string "vector")
7018 (eq_attr "alternative" "1")
7019 (const_string "vector")
7020 (and (eq_attr "alternative" "2")
7021 (match_operand 1 "memory_operand" ""))
7022 (const_string "vector")]
7023 (const_string "direct")))
9b70259d
JH
7024 (set_attr "mode" "SI")])
7025
d525dfdf
JH
7026(define_expand "mulhi3"
7027 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7028 (mult:HI (match_operand:HI 1 "register_operand" "")
7029 (match_operand:HI 2 "general_operand" "")))
8bc527af 7030 (clobber (reg:CC FLAGS_REG))])]
d9f32422 7031 "TARGET_HIMODE_MATH"
d525dfdf
JH
7032 "")
7033
7034(define_insn "*mulhi3_1"
6ef67412 7035 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
f56e86bd 7036 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6ef67412 7037 (match_operand:HI 2 "general_operand" "K,i,mr")))
8bc527af 7038 (clobber (reg:CC FLAGS_REG))]
d525dfdf 7039 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
e075ae69 7040 "@
0f40f9f7
ZW
7041 imul{w}\t{%2, %1, %0|%0, %1, %2}
7042 imul{w}\t{%2, %1, %0|%0, %1, %2}
7043 imul{w}\t{%2, %0|%0, %2}"
6ef67412
JH
7044 [(set_attr "type" "imul")
7045 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
7046 (set (attr "athlon_decode")
7047 (cond [(eq_attr "cpu" "athlon")
7048 (const_string "vector")
7049 (eq_attr "alternative" "1,2")
7050 (const_string "vector")]
7051 (const_string "direct")))
6ef67412 7052 (set_attr "mode" "HI")])
886c62d1 7053
558740bf
JH
7054(define_expand "mulqi3"
7055 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7056 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7057 (match_operand:QI 2 "register_operand" "")))
8bc527af 7058 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7059 "TARGET_QIMODE_MATH"
7060 "")
7061
7062(define_insn "*mulqi3_1"
765a46f9 7063 [(set (match_operand:QI 0 "register_operand" "=a")
558740bf 7064 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
765a46f9 7065 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8bc527af 7066 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7067 "TARGET_QIMODE_MATH
7068 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7069 "mul{b}\t%2"
6ef67412
JH
7070 [(set_attr "type" "imul")
7071 (set_attr "length_immediate" "0")
f56e86bd
JH
7072 (set (attr "athlon_decode")
7073 (if_then_else (eq_attr "cpu" "athlon")
7074 (const_string "vector")
7075 (const_string "direct")))
6ef67412 7076 (set_attr "mode" "QI")])
765a46f9 7077
558740bf
JH
7078(define_expand "umulqihi3"
7079 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7080 (mult:HI (zero_extend:HI
7081 (match_operand:QI 1 "nonimmediate_operand" ""))
7082 (zero_extend:HI
7083 (match_operand:QI 2 "register_operand" ""))))
8bc527af 7084 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7085 "TARGET_QIMODE_MATH"
7086 "")
7087
7088(define_insn "*umulqihi3_1"
2ae0f82c 7089 [(set (match_operand:HI 0 "register_operand" "=a")
558740bf 7090 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
e075ae69 7091 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8bc527af 7092 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7093 "TARGET_QIMODE_MATH
7094 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7095 "mul{b}\t%2"
6ef67412
JH
7096 [(set_attr "type" "imul")
7097 (set_attr "length_immediate" "0")
f56e86bd
JH
7098 (set (attr "athlon_decode")
7099 (if_then_else (eq_attr "cpu" "athlon")
7100 (const_string "vector")
7101 (const_string "direct")))
6ef67412 7102 (set_attr "mode" "QI")])
886c62d1 7103
558740bf
JH
7104(define_expand "mulqihi3"
7105 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7106 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7107 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8bc527af 7108 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7109 "TARGET_QIMODE_MATH"
7110 "")
7111
7112(define_insn "*mulqihi3_insn"
2ae0f82c 7113 [(set (match_operand:HI 0 "register_operand" "=a")
558740bf 7114 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
e075ae69 7115 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8bc527af 7116 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7117 "TARGET_QIMODE_MATH
7118 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7119 "imul{b}\t%2"
6ef67412
JH
7120 [(set_attr "type" "imul")
7121 (set_attr "length_immediate" "0")
f56e86bd
JH
7122 (set (attr "athlon_decode")
7123 (if_then_else (eq_attr "cpu" "athlon")
7124 (const_string "vector")
7125 (const_string "direct")))
6ef67412 7126 (set_attr "mode" "QI")])
4b71cd6e 7127
558740bf
JH
7128(define_expand "umulditi3"
7129 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7130 (mult:TI (zero_extend:TI
7131 (match_operand:DI 1 "nonimmediate_operand" ""))
7132 (zero_extend:TI
7133 (match_operand:DI 2 "register_operand" ""))))
8bc527af 7134 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7135 "TARGET_64BIT"
7136 "")
7137
7138(define_insn "*umulditi3_insn"
9b70259d 7139 [(set (match_operand:TI 0 "register_operand" "=A")
558740bf 7140 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
9b70259d 7141 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8bc527af 7142 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7143 "TARGET_64BIT
7144 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7145 "mul{q}\t%2"
1e07edd3 7146 [(set_attr "type" "imul")
1e07edd3 7147 (set_attr "length_immediate" "0")
f56e86bd
JH
7148 (set (attr "athlon_decode")
7149 (if_then_else (eq_attr "cpu" "athlon")
7150 (const_string "vector")
7151 (const_string "double")))
9b70259d 7152 (set_attr "mode" "DI")])
1e07edd3
JH
7153
7154;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
558740bf
JH
7155(define_expand "umulsidi3"
7156 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7157 (mult:DI (zero_extend:DI
7158 (match_operand:SI 1 "nonimmediate_operand" ""))
7159 (zero_extend:DI
7160 (match_operand:SI 2 "register_operand" ""))))
8bc527af 7161 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7162 "!TARGET_64BIT"
7163 "")
7164
7165(define_insn "*umulsidi3_insn"
4b71cd6e 7166 [(set (match_operand:DI 0 "register_operand" "=A")
558740bf 7167 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
e075ae69 7168 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8bc527af 7169 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7170 "!TARGET_64BIT
7171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7172 "mul{l}\t%2"
e075ae69 7173 [(set_attr "type" "imul")
6ef67412 7174 (set_attr "length_immediate" "0")
f56e86bd
JH
7175 (set (attr "athlon_decode")
7176 (if_then_else (eq_attr "cpu" "athlon")
7177 (const_string "vector")
7178 (const_string "double")))
6ef67412 7179 (set_attr "mode" "SI")])
4b71cd6e 7180
558740bf
JH
7181(define_expand "mulditi3"
7182 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7183 (mult:TI (sign_extend:TI
7184 (match_operand:DI 1 "nonimmediate_operand" ""))
7185 (sign_extend:TI
7186 (match_operand:DI 2 "register_operand" ""))))
8bc527af 7187 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7188 "TARGET_64BIT"
7189 "")
7190
7191(define_insn "*mulditi3_insn"
9b70259d 7192 [(set (match_operand:TI 0 "register_operand" "=A")
558740bf 7193 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
9b70259d 7194 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8bc527af 7195 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7196 "TARGET_64BIT
7197 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7198 "imul{q}\t%2"
9b70259d
JH
7199 [(set_attr "type" "imul")
7200 (set_attr "length_immediate" "0")
f56e86bd
JH
7201 (set (attr "athlon_decode")
7202 (if_then_else (eq_attr "cpu" "athlon")
7203 (const_string "vector")
7204 (const_string "double")))
9b70259d
JH
7205 (set_attr "mode" "DI")])
7206
558740bf
JH
7207(define_expand "mulsidi3"
7208 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7209 (mult:DI (sign_extend:DI
7210 (match_operand:SI 1 "nonimmediate_operand" ""))
7211 (sign_extend:DI
7212 (match_operand:SI 2 "register_operand" ""))))
8bc527af 7213 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7214 "!TARGET_64BIT"
7215 "")
7216
7217(define_insn "*mulsidi3_insn"
4b71cd6e 7218 [(set (match_operand:DI 0 "register_operand" "=A")
558740bf 7219 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
e075ae69 7220 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8bc527af 7221 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7222 "!TARGET_64BIT
7223 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7224 "imul{l}\t%2"
6ef67412
JH
7225 [(set_attr "type" "imul")
7226 (set_attr "length_immediate" "0")
f56e86bd
JH
7227 (set (attr "athlon_decode")
7228 (if_then_else (eq_attr "cpu" "athlon")
7229 (const_string "vector")
7230 (const_string "double")))
6ef67412 7231 (set_attr "mode" "SI")])
2f2a49e8 7232
558740bf
JH
7233(define_expand "umuldi3_highpart"
7234 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7235 (truncate:DI
7236 (lshiftrt:TI
7237 (mult:TI (zero_extend:TI
7238 (match_operand:DI 1 "nonimmediate_operand" ""))
7239 (zero_extend:TI
7240 (match_operand:DI 2 "register_operand" "")))
7241 (const_int 64))))
7242 (clobber (match_scratch:DI 3 ""))
8bc527af 7243 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7244 "TARGET_64BIT"
7245 "")
7246
9b70259d
JH
7247(define_insn "*umuldi3_highpart_rex64"
7248 [(set (match_operand:DI 0 "register_operand" "=d")
7249 (truncate:DI
7250 (lshiftrt:TI
7251 (mult:TI (zero_extend:TI
558740bf 7252 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9b70259d
JH
7253 (zero_extend:TI
7254 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7255 (const_int 64))))
558740bf 7256 (clobber (match_scratch:DI 3 "=1"))
8bc527af 7257 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7258 "TARGET_64BIT
7259 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7260 "mul{q}\t%2"
9b70259d 7261 [(set_attr "type" "imul")
9b70259d 7262 (set_attr "length_immediate" "0")
f56e86bd
JH
7263 (set (attr "athlon_decode")
7264 (if_then_else (eq_attr "cpu" "athlon")
7265 (const_string "vector")
7266 (const_string "double")))
9b70259d
JH
7267 (set_attr "mode" "DI")])
7268
558740bf
JH
7269(define_expand "umulsi3_highpart"
7270 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7271 (truncate:SI
7272 (lshiftrt:DI
7273 (mult:DI (zero_extend:DI
7274 (match_operand:SI 1 "nonimmediate_operand" ""))
7275 (zero_extend:DI
7276 (match_operand:SI 2 "register_operand" "")))
7277 (const_int 32))))
7278 (clobber (match_scratch:SI 3 ""))
8bc527af 7279 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7280 ""
7281 "")
7282
7283(define_insn "*umulsi3_highpart_insn"
2f2a49e8 7284 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
7285 (truncate:SI
7286 (lshiftrt:DI
7287 (mult:DI (zero_extend:DI
558740bf 7288 (match_operand:SI 1 "nonimmediate_operand" "%a"))
e075ae69
RH
7289 (zero_extend:DI
7290 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7291 (const_int 32))))
558740bf 7292 (clobber (match_scratch:SI 3 "=1"))
8bc527af 7293 (clobber (reg:CC FLAGS_REG))]
558740bf 7294 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
0f40f9f7 7295 "mul{l}\t%2"
32ee7d1d 7296 [(set_attr "type" "imul")
32ee7d1d 7297 (set_attr "length_immediate" "0")
f56e86bd
JH
7298 (set (attr "athlon_decode")
7299 (if_then_else (eq_attr "cpu" "athlon")
7300 (const_string "vector")
7301 (const_string "double")))
32ee7d1d
JH
7302 (set_attr "mode" "SI")])
7303
7304(define_insn "*umulsi3_highpart_zext"
7305 [(set (match_operand:DI 0 "register_operand" "=d")
7306 (zero_extend:DI (truncate:SI
7307 (lshiftrt:DI
7308 (mult:DI (zero_extend:DI
558740bf 7309 (match_operand:SI 1 "nonimmediate_operand" "%a"))
32ee7d1d
JH
7310 (zero_extend:DI
7311 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7312 (const_int 32)))))
558740bf 7313 (clobber (match_scratch:SI 3 "=1"))
8bc527af 7314 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7315 "TARGET_64BIT
7316 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7317 "mul{l}\t%2"
e075ae69 7318 [(set_attr "type" "imul")
6ef67412 7319 (set_attr "length_immediate" "0")
f56e86bd
JH
7320 (set (attr "athlon_decode")
7321 (if_then_else (eq_attr "cpu" "athlon")
7322 (const_string "vector")
7323 (const_string "double")))
6ef67412 7324 (set_attr "mode" "SI")])
2f2a49e8 7325
558740bf
JH
7326(define_expand "smuldi3_highpart"
7327 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7328 (truncate:DI
7329 (lshiftrt:TI
7330 (mult:TI (sign_extend:TI
7331 (match_operand:DI 1 "nonimmediate_operand" ""))
7332 (sign_extend:TI
7333 (match_operand:DI 2 "register_operand" "")))
7334 (const_int 64))))
7335 (clobber (match_scratch:DI 3 ""))
8bc527af 7336 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7337 "TARGET_64BIT"
7338 "")
7339
9b70259d
JH
7340(define_insn "*smuldi3_highpart_rex64"
7341 [(set (match_operand:DI 0 "register_operand" "=d")
7342 (truncate:DI
7343 (lshiftrt:TI
7344 (mult:TI (sign_extend:TI
558740bf 7345 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9b70259d
JH
7346 (sign_extend:TI
7347 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7348 (const_int 64))))
558740bf 7349 (clobber (match_scratch:DI 3 "=1"))
8bc527af 7350 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7351 "TARGET_64BIT
7352 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7353 "imul{q}\t%2"
9b70259d 7354 [(set_attr "type" "imul")
f56e86bd
JH
7355 (set (attr "athlon_decode")
7356 (if_then_else (eq_attr "cpu" "athlon")
7357 (const_string "vector")
7358 (const_string "double")))
9b70259d
JH
7359 (set_attr "mode" "DI")])
7360
558740bf
JH
7361(define_expand "smulsi3_highpart"
7362 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7363 (truncate:SI
7364 (lshiftrt:DI
7365 (mult:DI (sign_extend:DI
7366 (match_operand:SI 1 "nonimmediate_operand" ""))
7367 (sign_extend:DI
7368 (match_operand:SI 2 "register_operand" "")))
7369 (const_int 32))))
7370 (clobber (match_scratch:SI 3 ""))
8bc527af 7371 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7372 ""
7373 "")
7374
7375(define_insn "*smulsi3_highpart_insn"
2f2a49e8 7376 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
7377 (truncate:SI
7378 (lshiftrt:DI
7379 (mult:DI (sign_extend:DI
558740bf 7380 (match_operand:SI 1 "nonimmediate_operand" "%a"))
e075ae69
RH
7381 (sign_extend:DI
7382 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7383 (const_int 32))))
558740bf 7384 (clobber (match_scratch:SI 3 "=1"))
8bc527af 7385 (clobber (reg:CC FLAGS_REG))]
558740bf 7386 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
0f40f9f7 7387 "imul{l}\t%2"
e075ae69 7388 [(set_attr "type" "imul")
f56e86bd
JH
7389 (set (attr "athlon_decode")
7390 (if_then_else (eq_attr "cpu" "athlon")
7391 (const_string "vector")
7392 (const_string "double")))
6ef67412 7393 (set_attr "mode" "SI")])
4b71cd6e 7394
9b70259d
JH
7395(define_insn "*smulsi3_highpart_zext"
7396 [(set (match_operand:DI 0 "register_operand" "=d")
7397 (zero_extend:DI (truncate:SI
7398 (lshiftrt:DI
7399 (mult:DI (sign_extend:DI
558740bf 7400 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9b70259d
JH
7401 (sign_extend:DI
7402 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7403 (const_int 32)))))
558740bf 7404 (clobber (match_scratch:SI 3 "=1"))
8bc527af 7405 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7406 "TARGET_64BIT
7407 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7408 "imul{l}\t%2"
9b70259d 7409 [(set_attr "type" "imul")
f56e86bd
JH
7410 (set (attr "athlon_decode")
7411 (if_then_else (eq_attr "cpu" "athlon")
7412 (const_string "vector")
7413 (const_string "double")))
9b70259d
JH
7414 (set_attr "mode" "SI")])
7415
886c62d1
JVA
7416;; The patterns that match these are at the end of this file.
7417
4fb21e90
JVA
7418(define_expand "mulxf3"
7419 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
7420 (mult:XF (match_operand:XF 1 "register_operand" "")
7421 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
7422 "TARGET_80387"
7423 "")
7424
886c62d1
JVA
7425(define_expand "muldf3"
7426 [(set (match_operand:DF 0 "register_operand" "")
2ae0f82c 7427 (mult:DF (match_operand:DF 1 "register_operand" "")
886c62d1 7428 (match_operand:DF 2 "nonimmediate_operand" "")))]
965f5423 7429 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
886c62d1
JVA
7430 "")
7431
7432(define_expand "mulsf3"
7433 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 7434 (mult:SF (match_operand:SF 1 "register_operand" "")
886c62d1 7435 (match_operand:SF 2 "nonimmediate_operand" "")))]
965f5423 7436 "TARGET_80387 || TARGET_SSE_MATH"
886c62d1
JVA
7437 "")
7438\f
e075ae69 7439;; Divide instructions
886c62d1
JVA
7440
7441(define_insn "divqi3"
2ae0f82c
SC
7442 [(set (match_operand:QI 0 "register_operand" "=a")
7443 (div:QI (match_operand:HI 1 "register_operand" "0")
e075ae69 7444 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8bc527af 7445 (clobber (reg:CC FLAGS_REG))]
d9f32422 7446 "TARGET_QIMODE_MATH"
0f40f9f7 7447 "idiv{b}\t%2"
e075ae69 7448 [(set_attr "type" "idiv")
56bab446 7449 (set_attr "mode" "QI")])
886c62d1
JVA
7450
7451(define_insn "udivqi3"
2ae0f82c
SC
7452 [(set (match_operand:QI 0 "register_operand" "=a")
7453 (udiv:QI (match_operand:HI 1 "register_operand" "0")
e075ae69 7454 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8bc527af 7455 (clobber (reg:CC FLAGS_REG))]
d9f32422 7456 "TARGET_QIMODE_MATH"
0f40f9f7 7457 "div{b}\t%2"
e075ae69 7458 [(set_attr "type" "idiv")
56bab446 7459 (set_attr "mode" "QI")])
886c62d1
JVA
7460
7461;; The patterns that match these are at the end of this file.
7462
4fb21e90
JVA
7463(define_expand "divxf3"
7464 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
7465 (div:XF (match_operand:XF 1 "register_operand" "")
7466 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
7467 "TARGET_80387"
7468 "")
7469
a78cb986
SC
7470(define_expand "divdf3"
7471 [(set (match_operand:DF 0 "register_operand" "")
7472 (div:DF (match_operand:DF 1 "register_operand" "")
7473 (match_operand:DF 2 "nonimmediate_operand" "")))]
965f5423 7474 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
a78cb986
SC
7475 "")
7476
886c62d1
JVA
7477(define_expand "divsf3"
7478 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 7479 (div:SF (match_operand:SF 1 "register_operand" "")
886c62d1 7480 (match_operand:SF 2 "nonimmediate_operand" "")))]
965f5423 7481 "TARGET_80387 || TARGET_SSE_MATH"
886c62d1
JVA
7482 "")
7483\f
7484;; Remainder instructions.
9b70259d
JH
7485
7486(define_expand "divmoddi4"
7487 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7488 (div:DI (match_operand:DI 1 "register_operand" "")
7489 (match_operand:DI 2 "nonimmediate_operand" "")))
7490 (set (match_operand:DI 3 "register_operand" "")
7491 (mod:DI (match_dup 1) (match_dup 2)))
8bc527af 7492 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
7493 "TARGET_64BIT"
7494 "")
7495
7496;; Allow to come the parameter in eax or edx to avoid extra moves.
d1f87653 7497;; Penalize eax case slightly because it results in worse scheduling
9b70259d
JH
7498;; of code.
7499(define_insn "*divmoddi4_nocltd_rex64"
7500 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7501 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7502 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7503 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7504 (mod:DI (match_dup 2) (match_dup 3)))
8bc527af 7505 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
7506 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7507 "#"
7508 [(set_attr "type" "multi")])
7509
7510(define_insn "*divmoddi4_cltd_rex64"
7511 [(set (match_operand:DI 0 "register_operand" "=a")
7512 (div:DI (match_operand:DI 2 "register_operand" "a")
7513 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7514 (set (match_operand:DI 1 "register_operand" "=&d")
7515 (mod:DI (match_dup 2) (match_dup 3)))
8bc527af 7516 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
7517 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7518 "#"
7519 [(set_attr "type" "multi")])
7520
7521(define_insn "*divmoddi_noext_rex64"
7522 [(set (match_operand:DI 0 "register_operand" "=a")
7523 (div:DI (match_operand:DI 1 "register_operand" "0")
7524 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7525 (set (match_operand:DI 3 "register_operand" "=d")
7526 (mod:DI (match_dup 1) (match_dup 2)))
7527 (use (match_operand:DI 4 "register_operand" "3"))
8bc527af 7528 (clobber (reg:CC FLAGS_REG))]
9b70259d 7529 "TARGET_64BIT"
0f40f9f7 7530 "idiv{q}\t%2"
9b70259d 7531 [(set_attr "type" "idiv")
56bab446 7532 (set_attr "mode" "DI")])
9b70259d
JH
7533
7534(define_split
7535 [(set (match_operand:DI 0 "register_operand" "")
7536 (div:DI (match_operand:DI 1 "register_operand" "")
7537 (match_operand:DI 2 "nonimmediate_operand" "")))
7538 (set (match_operand:DI 3 "register_operand" "")
7539 (mod:DI (match_dup 1) (match_dup 2)))
8bc527af 7540 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
7541 "TARGET_64BIT && reload_completed"
7542 [(parallel [(set (match_dup 3)
7543 (ashiftrt:DI (match_dup 4) (const_int 63)))
8bc527af 7544 (clobber (reg:CC FLAGS_REG))])
9b70259d
JH
7545 (parallel [(set (match_dup 0)
7546 (div:DI (reg:DI 0) (match_dup 2)))
7547 (set (match_dup 3)
7548 (mod:DI (reg:DI 0) (match_dup 2)))
7549 (use (match_dup 3))
8bc527af 7550 (clobber (reg:CC FLAGS_REG))])]
9b70259d 7551{
9cd10576 7552 /* Avoid use of cltd in favor of a mov+shift. */
9b70259d
JH
7553 if (!TARGET_USE_CLTD && !optimize_size)
7554 {
7555 if (true_regnum (operands[1]))
7556 emit_move_insn (operands[0], operands[1]);
7557 else
7558 emit_move_insn (operands[3], operands[1]);
7559 operands[4] = operands[3];
7560 }
7561 else
7562 {
7563 if (true_regnum (operands[1]))
7564 abort();
7565 operands[4] = operands[1];
7566 }
0f40f9f7 7567})
9b70259d
JH
7568
7569
40745eec
JH
7570(define_expand "divmodsi4"
7571 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7572 (div:SI (match_operand:SI 1 "register_operand" "")
7573 (match_operand:SI 2 "nonimmediate_operand" "")))
7574 (set (match_operand:SI 3 "register_operand" "")
7575 (mod:SI (match_dup 1) (match_dup 2)))
8bc527af 7576 (clobber (reg:CC FLAGS_REG))])]
40745eec
JH
7577 ""
7578 "")
7579
7580;; Allow to come the parameter in eax or edx to avoid extra moves.
d1f87653 7581;; Penalize eax case slightly because it results in worse scheduling
40745eec
JH
7582;; of code.
7583(define_insn "*divmodsi4_nocltd"
7584 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7585 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7586 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7587 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7588 (mod:SI (match_dup 2) (match_dup 3)))
8bc527af 7589 (clobber (reg:CC FLAGS_REG))]
40745eec
JH
7590 "!optimize_size && !TARGET_USE_CLTD"
7591 "#"
7592 [(set_attr "type" "multi")])
886c62d1 7593
40745eec 7594(define_insn "*divmodsi4_cltd"
2bb7a0f5 7595 [(set (match_operand:SI 0 "register_operand" "=a")
40745eec
JH
7596 (div:SI (match_operand:SI 2 "register_operand" "a")
7597 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7598 (set (match_operand:SI 1 "register_operand" "=&d")
7599 (mod:SI (match_dup 2) (match_dup 3)))
8bc527af 7600 (clobber (reg:CC FLAGS_REG))]
40745eec
JH
7601 "optimize_size || TARGET_USE_CLTD"
7602 "#"
e075ae69
RH
7603 [(set_attr "type" "multi")])
7604
6343a50e 7605(define_insn "*divmodsi_noext"
e075ae69 7606 [(set (match_operand:SI 0 "register_operand" "=a")
40745eec 7607 (div:SI (match_operand:SI 1 "register_operand" "0")
e075ae69
RH
7608 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7609 (set (match_operand:SI 3 "register_operand" "=d")
7610 (mod:SI (match_dup 1) (match_dup 2)))
40745eec 7611 (use (match_operand:SI 4 "register_operand" "3"))
8bc527af 7612 (clobber (reg:CC FLAGS_REG))]
e075ae69 7613 ""
0f40f9f7 7614 "idiv{l}\t%2"
e075ae69 7615 [(set_attr "type" "idiv")
56bab446 7616 (set_attr "mode" "SI")])
e075ae69
RH
7617
7618(define_split
7619 [(set (match_operand:SI 0 "register_operand" "")
7620 (div:SI (match_operand:SI 1 "register_operand" "")
7621 (match_operand:SI 2 "nonimmediate_operand" "")))
7622 (set (match_operand:SI 3 "register_operand" "")
7623 (mod:SI (match_dup 1) (match_dup 2)))
8bc527af 7624 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
7625 "reload_completed"
7626 [(parallel [(set (match_dup 3)
7627 (ashiftrt:SI (match_dup 4) (const_int 31)))
8bc527af 7628 (clobber (reg:CC FLAGS_REG))])
e075ae69 7629 (parallel [(set (match_dup 0)
40745eec 7630 (div:SI (reg:SI 0) (match_dup 2)))
e075ae69 7631 (set (match_dup 3)
40745eec 7632 (mod:SI (reg:SI 0) (match_dup 2)))
e075ae69 7633 (use (match_dup 3))
8bc527af 7634 (clobber (reg:CC FLAGS_REG))])]
886c62d1 7635{
9cd10576 7636 /* Avoid use of cltd in favor of a mov+shift. */
40745eec 7637 if (!TARGET_USE_CLTD && !optimize_size)
e075ae69 7638 {
40745eec
JH
7639 if (true_regnum (operands[1]))
7640 emit_move_insn (operands[0], operands[1]);
7641 else
7642 emit_move_insn (operands[3], operands[1]);
e075ae69
RH
7643 operands[4] = operands[3];
7644 }
7645 else
40745eec
JH
7646 {
7647 if (true_regnum (operands[1]))
7648 abort();
7649 operands[4] = operands[1];
7650 }
0f40f9f7 7651})
e075ae69 7652;; %%% Split me.
886c62d1 7653(define_insn "divmodhi4"
2bb7a0f5
RS
7654 [(set (match_operand:HI 0 "register_operand" "=a")
7655 (div:HI (match_operand:HI 1 "register_operand" "0")
2ae0f82c 7656 (match_operand:HI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 7657 (set (match_operand:HI 3 "register_operand" "=&d")
e075ae69 7658 (mod:HI (match_dup 1) (match_dup 2)))
8bc527af 7659 (clobber (reg:CC FLAGS_REG))]
d9f32422 7660 "TARGET_HIMODE_MATH"
0f40f9f7 7661 "cwtd\;idiv{w}\t%2"
6ef67412
JH
7662 [(set_attr "type" "multi")
7663 (set_attr "length_immediate" "0")
7664 (set_attr "mode" "SI")])
886c62d1 7665
9b70259d
JH
7666(define_insn "udivmoddi4"
7667 [(set (match_operand:DI 0 "register_operand" "=a")
7668 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7669 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7670 (set (match_operand:DI 3 "register_operand" "=&d")
7671 (umod:DI (match_dup 1) (match_dup 2)))
8bc527af 7672 (clobber (reg:CC FLAGS_REG))]
9b70259d 7673 "TARGET_64BIT"
0f40f9f7 7674 "xor{q}\t%3, %3\;div{q}\t%2"
9b70259d
JH
7675 [(set_attr "type" "multi")
7676 (set_attr "length_immediate" "0")
7677 (set_attr "mode" "DI")])
7678
7679(define_insn "*udivmoddi4_noext"
7680 [(set (match_operand:DI 0 "register_operand" "=a")
7681 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7682 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7683 (set (match_operand:DI 3 "register_operand" "=d")
7684 (umod:DI (match_dup 1) (match_dup 2)))
7685 (use (match_dup 3))
8bc527af 7686 (clobber (reg:CC FLAGS_REG))]
9b70259d 7687 "TARGET_64BIT"
0f40f9f7 7688 "div{q}\t%2"
9b70259d 7689 [(set_attr "type" "idiv")
9b70259d
JH
7690 (set_attr "mode" "DI")])
7691
7692(define_split
7693 [(set (match_operand:DI 0 "register_operand" "")
7694 (udiv:DI (match_operand:DI 1 "register_operand" "")
7695 (match_operand:DI 2 "nonimmediate_operand" "")))
7696 (set (match_operand:DI 3 "register_operand" "")
7697 (umod:DI (match_dup 1) (match_dup 2)))
8bc527af 7698 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 7699 "TARGET_64BIT && reload_completed"
9b70259d
JH
7700 [(set (match_dup 3) (const_int 0))
7701 (parallel [(set (match_dup 0)
7702 (udiv:DI (match_dup 1) (match_dup 2)))
7703 (set (match_dup 3)
7704 (umod:DI (match_dup 1) (match_dup 2)))
7705 (use (match_dup 3))
8bc527af 7706 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
7707 "")
7708
886c62d1 7709(define_insn "udivmodsi4"
2bb7a0f5
RS
7710 [(set (match_operand:SI 0 "register_operand" "=a")
7711 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 7712 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 7713 (set (match_operand:SI 3 "register_operand" "=&d")
e075ae69 7714 (umod:SI (match_dup 1) (match_dup 2)))
8bc527af 7715 (clobber (reg:CC FLAGS_REG))]
886c62d1 7716 ""
0f40f9f7 7717 "xor{l}\t%3, %3\;div{l}\t%2"
6ef67412
JH
7718 [(set_attr "type" "multi")
7719 (set_attr "length_immediate" "0")
7720 (set_attr "mode" "SI")])
886c62d1 7721
6343a50e 7722(define_insn "*udivmodsi4_noext"
2bb7a0f5 7723 [(set (match_operand:SI 0 "register_operand" "=a")
e075ae69 7724 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 7725 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 7726 (set (match_operand:SI 3 "register_operand" "=d")
e075ae69
RH
7727 (umod:SI (match_dup 1) (match_dup 2)))
7728 (use (match_dup 3))
8bc527af 7729 (clobber (reg:CC FLAGS_REG))]
886c62d1 7730 ""
0f40f9f7 7731 "div{l}\t%2"
e075ae69 7732 [(set_attr "type" "idiv")
6ef67412 7733 (set_attr "mode" "SI")])
886c62d1 7734
e075ae69
RH
7735(define_split
7736 [(set (match_operand:SI 0 "register_operand" "")
7737 (udiv:SI (match_operand:SI 1 "register_operand" "")
7738 (match_operand:SI 2 "nonimmediate_operand" "")))
7739 (set (match_operand:SI 3 "register_operand" "")
7740 (umod:SI (match_dup 1) (match_dup 2)))
8bc527af 7741 (clobber (reg:CC FLAGS_REG))]
e075ae69 7742 "reload_completed"
591702de 7743 [(set (match_dup 3) (const_int 0))
e075ae69
RH
7744 (parallel [(set (match_dup 0)
7745 (udiv:SI (match_dup 1) (match_dup 2)))
7746 (set (match_dup 3)
7747 (umod:SI (match_dup 1) (match_dup 2)))
7748 (use (match_dup 3))
8bc527af 7749 (clobber (reg:CC FLAGS_REG))])]
e075ae69 7750 "")
886c62d1 7751
e075ae69 7752(define_expand "udivmodhi4"
591702de 7753 [(set (match_dup 4) (const_int 0))
40745eec
JH
7754 (parallel [(set (match_operand:HI 0 "register_operand" "")
7755 (udiv:HI (match_operand:HI 1 "register_operand" "")
7756 (match_operand:HI 2 "nonimmediate_operand" "")))
7757 (set (match_operand:HI 3 "register_operand" "")
e075ae69
RH
7758 (umod:HI (match_dup 1) (match_dup 2)))
7759 (use (match_dup 4))
8bc527af 7760 (clobber (reg:CC FLAGS_REG))])]
d9f32422 7761 "TARGET_HIMODE_MATH"
e075ae69 7762 "operands[4] = gen_reg_rtx (HImode);")
886c62d1 7763
6343a50e 7764(define_insn "*udivmodhi_noext"
e075ae69
RH
7765 [(set (match_operand:HI 0 "register_operand" "=a")
7766 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7767 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7768 (set (match_operand:HI 3 "register_operand" "=d")
7769 (umod:HI (match_dup 1) (match_dup 2)))
7770 (use (match_operand:HI 4 "register_operand" "3"))
8bc527af 7771 (clobber (reg:CC FLAGS_REG))]
e075ae69 7772 ""
0f40f9f7 7773 "div{w}\t%2"
e075ae69 7774 [(set_attr "type" "idiv")
56bab446 7775 (set_attr "mode" "HI")])
e075ae69 7776
1e5f1716 7777;; We cannot use div/idiv for double division, because it causes
e075ae69
RH
7778;; "division by zero" on the overflow and that's not what we expect
7779;; from truncate. Because true (non truncating) double division is
7780;; never generated, we can't create this insn anyway.
7781;
7782;(define_insn ""
7783; [(set (match_operand:SI 0 "register_operand" "=a")
7784; (truncate:SI
7785; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7786; (zero_extend:DI
7787; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7788; (set (match_operand:SI 3 "register_operand" "=d")
7789; (truncate:SI
7790; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8bc527af 7791; (clobber (reg:CC FLAGS_REG))]
e075ae69 7792; ""
0f40f9f7 7793; "div{l}\t{%2, %0|%0, %2}"
56bab446 7794; [(set_attr "type" "idiv")])
886c62d1 7795\f
e075ae69
RH
7796;;- Logical AND instructions
7797
7798;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7799;; Note that this excludes ah.
7800
9b70259d 7801(define_insn "*testdi_1_rex64"
42fabf21 7802 [(set (reg FLAGS_REG)
9b70259d 7803 (compare
2bac97f7 7804 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
e1fea6ee 7805 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
9b70259d 7806 (const_int 0)))]
e1fea6ee
JH
7807 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7808 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9b70259d 7809 "@
5a0855a0
JJ
7810 test{l}\t{%k1, %k0|%k0, %k1}
7811 test{l}\t{%k1, %k0|%k0, %k1}
7812 test{q}\t{%1, %0|%0, %1}
7813 test{q}\t{%1, %0|%0, %1}
0f40f9f7 7814 test{q}\t{%1, %0|%0, %1}"
9b70259d
JH
7815 [(set_attr "type" "test")
7816 (set_attr "modrm" "0,1,0,1,1")
7817 (set_attr "mode" "SI,SI,DI,DI,DI")
7818 (set_attr "pent_pair" "uv,np,uv,np,uv")])
9076b9c1
JH
7819
7820(define_insn "testsi_1"
42fabf21 7821 [(set (reg FLAGS_REG)
9076b9c1 7822 (compare
2bac97f7 7823 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
e1fea6ee 7824 (match_operand:SI 1 "general_operand" "in,in,rin"))
16189740 7825 (const_int 0)))]
e1fea6ee
JH
7826 "ix86_match_ccmode (insn, CCNOmode)
7827 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 7828 "test{l}\t{%1, %0|%0, %1}"
6ef67412
JH
7829 [(set_attr "type" "test")
7830 (set_attr "modrm" "0,1,1")
7831 (set_attr "mode" "SI")
e075ae69
RH
7832 (set_attr "pent_pair" "uv,np,uv")])
7833
9076b9c1 7834(define_expand "testsi_ccno_1"
8bc527af 7835 [(set (reg:CCNO FLAGS_REG)
16189740 7836 (compare:CCNO
9076b9c1
JH
7837 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7838 (match_operand:SI 1 "nonmemory_operand" ""))
16189740 7839 (const_int 0)))]
a1cbdd7f 7840 ""
9076b9c1 7841 "")
16189740
RH
7842
7843(define_insn "*testhi_1"
42fabf21 7844 [(set (reg FLAGS_REG)
2bac97f7 7845 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
e1fea6ee 7846 (match_operand:HI 1 "general_operand" "n,n,rn"))
16189740 7847 (const_int 0)))]
e1fea6ee
JH
7848 "ix86_match_ccmode (insn, CCNOmode)
7849 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 7850 "test{w}\t{%1, %0|%0, %1}"
6ef67412
JH
7851 [(set_attr "type" "test")
7852 (set_attr "modrm" "0,1,1")
7853 (set_attr "mode" "HI")
e075ae69
RH
7854 (set_attr "pent_pair" "uv,np,uv")])
7855
9076b9c1 7856(define_expand "testqi_ccz_1"
8bc527af 7857 [(set (reg:CCZ FLAGS_REG)
9076b9c1
JH
7858 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7859 (match_operand:QI 1 "nonmemory_operand" ""))
7860 (const_int 0)))]
16189740 7861 ""
9076b9c1 7862 "")
16189740 7863
88d60956 7864(define_insn "*testqi_1_maybe_si"
93330ea1 7865 [(set (reg FLAGS_REG)
88d60956
RH
7866 (compare
7867 (and:QI
7868 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7869 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7870 (const_int 0)))]
7871 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7872 && ix86_match_ccmode (insn,
7873 GET_CODE (operands[1]) == CONST_INT
7874 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
adc88131
JJ
7875{
7876 if (which_alternative == 3)
7877 {
88d60956 7878 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
adc88131 7879 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
0f40f9f7 7880 return "test{l}\t{%1, %k0|%k0, %1}";
adc88131 7881 }
0f40f9f7
ZW
7882 return "test{b}\t{%1, %0|%0, %1}";
7883}
6ef67412
JH
7884 [(set_attr "type" "test")
7885 (set_attr "modrm" "0,1,1,1")
7886 (set_attr "mode" "QI,QI,QI,SI")
7887 (set_attr "pent_pair" "uv,np,uv,np")])
e075ae69 7888
88d60956
RH
7889(define_insn "*testqi_1"
7890 [(set (reg FLAGS_REG)
7891 (compare
7892 (and:QI
7893 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7894 (match_operand:QI 1 "general_operand" "n,n,qn"))
7895 (const_int 0)))]
7896 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7897 && ix86_match_ccmode (insn, CCNOmode)"
7898 "test{b}\t{%1, %0|%0, %1}"
7899 [(set_attr "type" "test")
7900 (set_attr "modrm" "0,1,1")
7901 (set_attr "mode" "QI")
7902 (set_attr "pent_pair" "uv,np,uv")])
7903
9076b9c1 7904(define_expand "testqi_ext_ccno_0"
8bc527af 7905 [(set (reg:CCNO FLAGS_REG)
9076b9c1 7906 (compare:CCNO
16189740
RH
7907 (and:SI
7908 (zero_extract:SI
9076b9c1 7909 (match_operand 0 "ext_register_operand" "")
16189740
RH
7910 (const_int 8)
7911 (const_int 8))
9076b9c1 7912 (match_operand 1 "const_int_operand" ""))
16189740 7913 (const_int 0)))]
9076b9c1
JH
7914 ""
7915 "")
e075ae69 7916
9076b9c1 7917(define_insn "*testqi_ext_0"
42fabf21 7918 [(set (reg FLAGS_REG)
9076b9c1 7919 (compare
e075ae69
RH
7920 (and:SI
7921 (zero_extract:SI
d2836273 7922 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
7923 (const_int 8)
7924 (const_int 8))
7925 (match_operand 1 "const_int_operand" "n"))
7926 (const_int 0)))]
2f41793e 7927 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7928 "test{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
7929 [(set_attr "type" "test")
7930 (set_attr "mode" "QI")
7931 (set_attr "length_immediate" "1")
e075ae69
RH
7932 (set_attr "pent_pair" "np")])
7933
7934(define_insn "*testqi_ext_1"
42fabf21 7935 [(set (reg FLAGS_REG)
16189740 7936 (compare
e075ae69
RH
7937 (and:SI
7938 (zero_extract:SI
d2836273 7939 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
7940 (const_int 8)
7941 (const_int 8))
7942 (zero_extend:SI
e1fea6ee 7943 (match_operand:QI 1 "general_operand" "Qm")))
e075ae69 7944 (const_int 0)))]
e1fea6ee
JH
7945 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7946 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 7947 "test{b}\t{%1, %h0|%h0, %1}"
d2836273
JH
7948 [(set_attr "type" "test")
7949 (set_attr "mode" "QI")])
7950
7951(define_insn "*testqi_ext_1_rex64"
42fabf21 7952 [(set (reg FLAGS_REG)
d2836273
JH
7953 (compare
7954 (and:SI
7955 (zero_extract:SI
7956 (match_operand 0 "ext_register_operand" "Q")
7957 (const_int 8)
7958 (const_int 8))
7959 (zero_extend:SI
3522082b 7960 (match_operand:QI 1 "register_operand" "Q")))
d2836273
JH
7961 (const_int 0)))]
7962 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7963 "test{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
7964 [(set_attr "type" "test")
7965 (set_attr "mode" "QI")])
e075ae69
RH
7966
7967(define_insn "*testqi_ext_2"
42fabf21 7968 [(set (reg FLAGS_REG)
16189740 7969 (compare
e075ae69
RH
7970 (and:SI
7971 (zero_extract:SI
d2836273 7972 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
7973 (const_int 8)
7974 (const_int 8))
7975 (zero_extract:SI
d2836273 7976 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
7977 (const_int 8)
7978 (const_int 8)))
7979 (const_int 0)))]
16189740 7980 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7981 "test{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
7982 [(set_attr "type" "test")
7983 (set_attr "mode" "QI")])
e075ae69
RH
7984
7985;; Combine likes to form bit extractions for some tests. Humor it.
6343a50e 7986(define_insn "*testqi_ext_3"
42fabf21 7987 [(set (reg FLAGS_REG)
16189740
RH
7988 (compare (zero_extract:SI
7989 (match_operand 0 "nonimmediate_operand" "rm")
7990 (match_operand:SI 1 "const_int_operand" "")
7991 (match_operand:SI 2 "const_int_operand" ""))
7992 (const_int 0)))]
7993 "ix86_match_ccmode (insn, CCNOmode)
7994 && (GET_MODE (operands[0]) == SImode
9b70259d
JH
7995 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7996 || GET_MODE (operands[0]) == HImode
7997 || GET_MODE (operands[0]) == QImode)"
7998 "#")
7999
8000(define_insn "*testqi_ext_3_rex64"
42fabf21 8001 [(set (reg FLAGS_REG)
9b70259d
JH
8002 (compare (zero_extract:DI
8003 (match_operand 0 "nonimmediate_operand" "rm")
8004 (match_operand:DI 1 "const_int_operand" "")
8005 (match_operand:DI 2 "const_int_operand" ""))
8006 (const_int 0)))]
1b0c37d7
ZW
8007 "TARGET_64BIT
8008 && ix86_match_ccmode (insn, CCNOmode)
f5143c46 8009 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
44cf5b6a
JH
8010 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8011 /* Ensure that resulting mask is zero or sign extended operand. */
8012 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8013 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8014 && INTVAL (operands[1]) > 32))
9b70259d
JH
8015 && (GET_MODE (operands[0]) == SImode
8016 || GET_MODE (operands[0]) == DImode
16189740
RH
8017 || GET_MODE (operands[0]) == HImode
8018 || GET_MODE (operands[0]) == QImode)"
e075ae69 8019 "#")
4fce8e83 8020
e075ae69 8021(define_split
25da5dc7
RH
8022 [(set (match_operand 0 "flags_reg_operand" "")
8023 (match_operator 1 "compare_operator"
8024 [(zero_extract
8025 (match_operand 2 "nonimmediate_operand" "")
8026 (match_operand 3 "const_int_operand" "")
8027 (match_operand 4 "const_int_operand" ""))
8028 (const_int 0)]))]
16189740 8029 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7 8030 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
e075ae69 8031{
25da5dc7
RH
8032 rtx val = operands[2];
8033 HOST_WIDE_INT len = INTVAL (operands[3]);
8034 HOST_WIDE_INT pos = INTVAL (operands[4]);
e075ae69 8035 HOST_WIDE_INT mask;
592188a5 8036 enum machine_mode mode, submode;
886c62d1 8037
25da5dc7
RH
8038 mode = GET_MODE (val);
8039 if (GET_CODE (val) == MEM)
5bc7cd8e 8040 {
e075ae69
RH
8041 /* ??? Combine likes to put non-volatile mem extractions in QImode
8042 no matter the size of the test. So find a mode that works. */
25da5dc7 8043 if (! MEM_VOLATILE_P (val))
e075ae69
RH
8044 {
8045 mode = smallest_mode_for_size (pos + len, MODE_INT);
25da5dc7 8046 val = adjust_address (val, mode, 0);
e075ae69 8047 }
5bc7cd8e 8048 }
25da5dc7
RH
8049 else if (GET_CODE (val) == SUBREG
8050 && (submode = GET_MODE (SUBREG_REG (val)),
592188a5
RH
8051 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8052 && pos + len <= GET_MODE_BITSIZE (submode))
8053 {
8054 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8055 mode = submode;
25da5dc7 8056 val = SUBREG_REG (val);
592188a5 8057 }
e075ae69 8058 else if (mode == HImode && pos + len <= 8)
5bc7cd8e 8059 {
e075ae69
RH
8060 /* Small HImode tests can be converted to QImode. */
8061 mode = QImode;
25da5dc7 8062 val = gen_lowpart (QImode, val);
5bc7cd8e
SC
8063 }
8064
e075ae69
RH
8065 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8066 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
886c62d1 8067
25da5dc7 8068 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
0f40f9f7 8069})
886c62d1 8070
6c81a490
JH
8071;; Convert HImode/SImode test instructions with immediate to QImode ones.
8072;; i386 does not allow to encode test with 8bit sign extended immediate, so
8073;; this is relatively important trick.
d1f87653 8074;; Do the conversion only post-reload to avoid limiting of the register class
6c81a490
JH
8075;; to QI regs.
8076(define_split
25da5dc7
RH
8077 [(set (match_operand 0 "flags_reg_operand" "")
8078 (match_operator 1 "compare_operator"
8079 [(and (match_operand 2 "register_operand" "")
8080 (match_operand 3 "const_int_operand" ""))
8081 (const_int 0)]))]
2f41793e 8082 "reload_completed
25da5dc7
RH
8083 && QI_REG_P (operands[2])
8084 && GET_MODE (operands[2]) != QImode
6c81a490 8085 && ((ix86_match_ccmode (insn, CCZmode)
25da5dc7 8086 && !(INTVAL (operands[3]) & ~(255 << 8)))
6c81a490 8087 || (ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
8088 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8089 [(set (match_dup 0)
8090 (match_op_dup 1
8091 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8092 (match_dup 3))
8093 (const_int 0)]))]
8094 "operands[2] = gen_lowpart (SImode, operands[2]);
8095 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
6c81a490
JH
8096
8097(define_split
25da5dc7
RH
8098 [(set (match_operand 0 "flags_reg_operand" "")
8099 (match_operator 1 "compare_operator"
8100 [(and (match_operand 2 "nonimmediate_operand" "")
8101 (match_operand 3 "const_int_operand" ""))
8102 (const_int 0)]))]
2f41793e 8103 "reload_completed
25da5dc7
RH
8104 && GET_MODE (operands[2]) != QImode
8105 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
6c81a490 8106 && ((ix86_match_ccmode (insn, CCZmode)
25da5dc7 8107 && !(INTVAL (operands[3]) & ~255))
6c81a490 8108 || (ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
8109 && !(INTVAL (operands[3]) & ~127)))"
8110 [(set (match_dup 0)
8111 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8112 (const_int 0)]))]
8113 "operands[2] = gen_lowpart (QImode, operands[2]);
8114 operands[3] = gen_lowpart (QImode, operands[3]);")
6c81a490
JH
8115
8116
e075ae69
RH
8117;; %%% This used to optimize known byte-wide and operations to memory,
8118;; and sometimes to QImode registers. If this is considered useful,
8119;; it should be done with splitters.
8120
9b70259d
JH
8121(define_expand "anddi3"
8122 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8123 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8124 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8bc527af 8125 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8126 "TARGET_64BIT"
8127 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8128
8129(define_insn "*anddi_1_rex64"
8130 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8131 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8132 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8bc527af 8133 (clobber (reg:CC FLAGS_REG))]
9b70259d 8134 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9b70259d
JH
8135{
8136 switch (get_attr_type (insn))
8137 {
8138 case TYPE_IMOVX:
8139 {
8140 enum machine_mode mode;
8141
8142 if (GET_CODE (operands[2]) != CONST_INT)
8143 abort ();
8144 if (INTVAL (operands[2]) == 0xff)
8145 mode = QImode;
8146 else if (INTVAL (operands[2]) == 0xffff)
8147 mode = HImode;
8148 else
8149 abort ();
8150
8151 operands[1] = gen_lowpart (mode, operands[1]);
8152 if (mode == QImode)
0f40f9f7 8153 return "movz{bq|x}\t{%1,%0|%0, %1}";
9b70259d 8154 else
0f40f9f7 8155 return "movz{wq|x}\t{%1,%0|%0, %1}";
9b70259d
JH
8156 }
8157
8158 default:
8159 if (! rtx_equal_p (operands[0], operands[1]))
8160 abort ();
8161 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 8162 return "and{l}\t{%k2, %k0|%k0, %k2}";
9b70259d 8163 else
0f40f9f7 8164 return "and{q}\t{%2, %0|%0, %2}";
9b70259d 8165 }
0f40f9f7 8166}
9b70259d
JH
8167 [(set_attr "type" "alu,alu,alu,imovx")
8168 (set_attr "length_immediate" "*,*,*,0")
8169 (set_attr "mode" "SI,DI,DI,DI")])
8170
8171(define_insn "*anddi_2"
42fabf21 8172 [(set (reg FLAGS_REG)
9b70259d
JH
8173 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8174 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8175 (const_int 0)))
8176 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8177 (and:DI (match_dup 1) (match_dup 2)))]
8178 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8179 && ix86_binary_operator_ok (AND, DImode, operands)"
8180 "@
5a0855a0
JJ
8181 and{l}\t{%k2, %k0|%k0, %k2}
8182 and{q}\t{%2, %0|%0, %2}
0f40f9f7 8183 and{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8184 [(set_attr "type" "alu")
8185 (set_attr "mode" "SI,DI,DI")])
8186
e075ae69
RH
8187(define_expand "andsi3"
8188 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8189 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8190 (match_operand:SI 2 "general_operand" "")))
8bc527af 8191 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
8192 ""
8193 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8194
8195(define_insn "*andsi_1"
8196 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8197 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8198 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8bc527af 8199 (clobber (reg:CC FLAGS_REG))]
e075ae69 8200 "ix86_binary_operator_ok (AND, SImode, operands)"
886c62d1 8201{
e075ae69 8202 switch (get_attr_type (insn))
886c62d1 8203 {
e075ae69
RH
8204 case TYPE_IMOVX:
8205 {
8206 enum machine_mode mode;
5bc7cd8e 8207
e075ae69
RH
8208 if (GET_CODE (operands[2]) != CONST_INT)
8209 abort ();
8210 if (INTVAL (operands[2]) == 0xff)
8211 mode = QImode;
8212 else if (INTVAL (operands[2]) == 0xffff)
8213 mode = HImode;
8214 else
8215 abort ();
8216
8217 operands[1] = gen_lowpart (mode, operands[1]);
8218 if (mode == QImode)
0f40f9f7 8219 return "movz{bl|x}\t{%1,%0|%0, %1}";
e075ae69 8220 else
0f40f9f7 8221 return "movz{wl|x}\t{%1,%0|%0, %1}";
e075ae69 8222 }
5bc7cd8e 8223
e075ae69
RH
8224 default:
8225 if (! rtx_equal_p (operands[0], operands[1]))
8226 abort ();
0f40f9f7 8227 return "and{l}\t{%2, %0|%0, %2}";
886c62d1 8228 }
0f40f9f7 8229}
6ef67412
JH
8230 [(set_attr "type" "alu,alu,imovx")
8231 (set_attr "length_immediate" "*,*,0")
8232 (set_attr "mode" "SI")])
8233
8234(define_split
05b432db 8235 [(set (match_operand 0 "register_operand" "")
9b70259d
JH
8236 (and (match_dup 0)
8237 (const_int -65536)))
8bc527af 8238 (clobber (reg:CC FLAGS_REG))]
285464d0 8239 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
6ef67412
JH
8240 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8241 "operands[1] = gen_lowpart (HImode, operands[0]);")
8242
8243(define_split
3522082b 8244 [(set (match_operand 0 "ext_register_operand" "")
5e1a2fc7 8245 (and (match_dup 0)
9b70259d 8246 (const_int -256)))
8bc527af 8247 (clobber (reg:CC FLAGS_REG))]
05b432db 8248 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
6ef67412
JH
8249 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8250 "operands[1] = gen_lowpart (QImode, operands[0]);")
8251
8252(define_split
3522082b 8253 [(set (match_operand 0 "ext_register_operand" "")
6ef67412
JH
8254 (and (match_dup 0)
8255 (const_int -65281)))
8bc527af 8256 (clobber (reg:CC FLAGS_REG))]
05b432db 8257 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
6ef67412
JH
8258 [(parallel [(set (zero_extract:SI (match_dup 0)
8259 (const_int 8)
8260 (const_int 8))
8261 (xor:SI
8262 (zero_extract:SI (match_dup 0)
8263 (const_int 8)
8264 (const_int 8))
8265 (zero_extract:SI (match_dup 0)
8266 (const_int 8)
8267 (const_int 8))))
8bc527af 8268 (clobber (reg:CC FLAGS_REG))])]
6ef67412 8269 "operands[0] = gen_lowpart (SImode, operands[0]);")
e075ae69 8270
9b70259d
JH
8271;; See comment for addsi_1_zext why we do use nonimmediate_operand
8272(define_insn "*andsi_1_zext"
8273 [(set (match_operand:DI 0 "register_operand" "=r")
8274 (zero_extend:DI
8275 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8276 (match_operand:SI 2 "general_operand" "rim"))))
8bc527af 8277 (clobber (reg:CC FLAGS_REG))]
9b70259d 8278 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 8279 "and{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8280 [(set_attr "type" "alu")
8281 (set_attr "mode" "SI")])
8282
e075ae69 8283(define_insn "*andsi_2"
42fabf21 8284 [(set (reg FLAGS_REG)
16189740
RH
8285 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8286 (match_operand:SI 2 "general_operand" "rim,ri"))
8287 (const_int 0)))
e075ae69
RH
8288 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8289 (and:SI (match_dup 1) (match_dup 2)))]
16189740
RH
8290 "ix86_match_ccmode (insn, CCNOmode)
8291 && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 8292 "and{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "SI")])
e075ae69 8295
9b70259d
JH
8296;; See comment for addsi_1_zext why we do use nonimmediate_operand
8297(define_insn "*andsi_2_zext"
42fabf21 8298 [(set (reg FLAGS_REG)
9b70259d
JH
8299 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8300 (match_operand:SI 2 "general_operand" "rim"))
8301 (const_int 0)))
8302 (set (match_operand:DI 0 "register_operand" "=r")
8303 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8304 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8305 && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 8306 "and{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8307 [(set_attr "type" "alu")
8308 (set_attr "mode" "SI")])
8309
e075ae69
RH
8310(define_expand "andhi3"
8311 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8312 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8313 (match_operand:HI 2 "general_operand" "")))
8bc527af 8314 (clobber (reg:CC FLAGS_REG))]
d9f32422 8315 "TARGET_HIMODE_MATH"
e075ae69
RH
8316 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8317
8318(define_insn "*andhi_1"
8319 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8320 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8321 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8bc527af 8322 (clobber (reg:CC FLAGS_REG))]
e075ae69 8323 "ix86_binary_operator_ok (AND, HImode, operands)"
886c62d1 8324{
e075ae69 8325 switch (get_attr_type (insn))
886c62d1 8326 {
e075ae69
RH
8327 case TYPE_IMOVX:
8328 if (GET_CODE (operands[2]) != CONST_INT)
8329 abort ();
8330 if (INTVAL (operands[2]) == 0xff)
0f40f9f7 8331 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
e075ae69 8332 abort ();
886c62d1 8333
e075ae69
RH
8334 default:
8335 if (! rtx_equal_p (operands[0], operands[1]))
8336 abort ();
886c62d1 8337
0f40f9f7 8338 return "and{w}\t{%2, %0|%0, %2}";
5bc7cd8e 8339 }
0f40f9f7 8340}
6ef67412
JH
8341 [(set_attr "type" "alu,alu,imovx")
8342 (set_attr "length_immediate" "*,*,0")
8343 (set_attr "mode" "HI,HI,SI")])
5bc7cd8e 8344
e075ae69 8345(define_insn "*andhi_2"
42fabf21 8346 [(set (reg FLAGS_REG)
16189740
RH
8347 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8348 (match_operand:HI 2 "general_operand" "rim,ri"))
8349 (const_int 0)))
e075ae69
RH
8350 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8351 (and:HI (match_dup 1) (match_dup 2)))]
16189740
RH
8352 "ix86_match_ccmode (insn, CCNOmode)
8353 && ix86_binary_operator_ok (AND, HImode, operands)"
0f40f9f7 8354 "and{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8355 [(set_attr "type" "alu")
8356 (set_attr "mode" "HI")])
5bc7cd8e 8357
e075ae69
RH
8358(define_expand "andqi3"
8359 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8360 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8361 (match_operand:QI 2 "general_operand" "")))
8bc527af 8362 (clobber (reg:CC FLAGS_REG))]
d9f32422 8363 "TARGET_QIMODE_MATH"
e075ae69
RH
8364 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8365
8366;; %%% Potential partial reg stall on alternative 2. What to do?
8367(define_insn "*andqi_1"
7c6b971d 8368 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 8369 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 8370 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8bc527af 8371 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
8372 "ix86_binary_operator_ok (AND, QImode, operands)"
8373 "@
0f40f9f7
ZW
8374 and{b}\t{%2, %0|%0, %2}
8375 and{b}\t{%2, %0|%0, %2}
8376 and{l}\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
8377 [(set_attr "type" "alu")
8378 (set_attr "mode" "QI,QI,SI")])
e075ae69 8379
a1b8572c
JH
8380(define_insn "*andqi_1_slp"
8381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8382 (and:QI (match_dup 0)
8383 (match_operand:QI 1 "general_operand" "qi,qmi")))
8bc527af 8384 (clobber (reg:CC FLAGS_REG))]
1b245ade
JH
8385 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8386 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 8387 "and{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8388 [(set_attr "type" "alu1")
8389 (set_attr "mode" "QI")])
8390
88d60956 8391(define_insn "*andqi_2_maybe_si"
42fabf21 8392 [(set (reg FLAGS_REG)
16189740 8393 (compare (and:QI
88d60956
RH
8394 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8395 (match_operand:QI 2 "general_operand" "qim,qi,i"))
16189740 8396 (const_int 0)))
e075ae69
RH
8397 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8398 (and:QI (match_dup 1) (match_dup 2)))]
88d60956
RH
8399 "ix86_binary_operator_ok (AND, QImode, operands)
8400 && ix86_match_ccmode (insn,
8401 GET_CODE (operands[2]) == CONST_INT
8402 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
adc88131
JJ
8403{
8404 if (which_alternative == 2)
8405 {
88d60956 8406 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
adc88131 8407 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
0f40f9f7 8408 return "and{l}\t{%2, %k0|%k0, %2}";
adc88131 8409 }
0f40f9f7
ZW
8410 return "and{b}\t{%2, %0|%0, %2}";
8411}
6ef67412
JH
8412 [(set_attr "type" "alu")
8413 (set_attr "mode" "QI,QI,SI")])
e075ae69 8414
88d60956
RH
8415(define_insn "*andqi_2"
8416 [(set (reg FLAGS_REG)
8417 (compare (and:QI
8418 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8419 (match_operand:QI 2 "general_operand" "qim,qi"))
8420 (const_int 0)))
8421 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8422 (and:QI (match_dup 1) (match_dup 2)))]
8423 "ix86_match_ccmode (insn, CCNOmode)
8424 && ix86_binary_operator_ok (AND, QImode, operands)"
8425 "and{b}\t{%2, %0|%0, %2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "mode" "QI")])
8428
a1b8572c 8429(define_insn "*andqi_2_slp"
42fabf21 8430 [(set (reg FLAGS_REG)
a1b8572c
JH
8431 (compare (and:QI
8432 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8433 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8434 (const_int 0)))
8435 (set (strict_low_part (match_dup 0))
8436 (and:QI (match_dup 0) (match_dup 1)))]
2f41793e 8437 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade
JH
8438 && ix86_match_ccmode (insn, CCNOmode)
8439 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 8440 "and{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8441 [(set_attr "type" "alu1")
8442 (set_attr "mode" "QI")])
8443
e075ae69
RH
8444;; ??? A bug in recog prevents it from recognizing a const_int as an
8445;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8446;; for a QImode operand, which of course failed.
8447
8448(define_insn "andqi_ext_0"
d2836273 8449 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8450 (const_int 8)
8451 (const_int 8))
8452 (and:SI
8453 (zero_extract:SI
8454 (match_operand 1 "ext_register_operand" "0")
8455 (const_int 8)
8456 (const_int 8))
8457 (match_operand 2 "const_int_operand" "n")))
8bc527af 8458 (clobber (reg:CC FLAGS_REG))]
2f41793e 8459 ""
0f40f9f7 8460 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8461 [(set_attr "type" "alu")
8462 (set_attr "length_immediate" "1")
8463 (set_attr "mode" "QI")])
e075ae69
RH
8464
8465;; Generated by peephole translating test to and. This shows up
8466;; often in fp comparisons.
8467
8468(define_insn "*andqi_ext_0_cc"
42fabf21 8469 [(set (reg FLAGS_REG)
16189740 8470 (compare
e075ae69
RH
8471 (and:SI
8472 (zero_extract:SI
084e679a 8473 (match_operand 1 "ext_register_operand" "0")
3522082b 8474 (const_int 8)
e075ae69
RH
8475 (const_int 8))
8476 (match_operand 2 "const_int_operand" "n"))
8477 (const_int 0)))
d2836273 8478 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8479 (const_int 8)
8480 (const_int 8))
8481 (and:SI
8482 (zero_extract:SI
8483 (match_dup 1)
8484 (const_int 8)
8485 (const_int 8))
8486 (match_dup 2)))]
2f41793e 8487 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8488 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8489 [(set_attr "type" "alu")
8490 (set_attr "length_immediate" "1")
8491 (set_attr "mode" "QI")])
e075ae69
RH
8492
8493(define_insn "*andqi_ext_1"
d2836273 8494 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8495 (const_int 8)
8496 (const_int 8))
8497 (and:SI
8498 (zero_extract:SI
8499 (match_operand 1 "ext_register_operand" "0")
8500 (const_int 8)
8501 (const_int 8))
8502 (zero_extend:SI
d2836273 8503 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 8504 (clobber (reg:CC FLAGS_REG))]
d2836273 8505 "!TARGET_64BIT"
0f40f9f7 8506 "and{b}\t{%2, %h0|%h0, %2}"
d2836273
JH
8507 [(set_attr "type" "alu")
8508 (set_attr "length_immediate" "0")
8509 (set_attr "mode" "QI")])
8510
8511(define_insn "*andqi_ext_1_rex64"
8512 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8513 (const_int 8)
8514 (const_int 8))
8515 (and:SI
8516 (zero_extract:SI
8517 (match_operand 1 "ext_register_operand" "0")
8518 (const_int 8)
8519 (const_int 8))
8520 (zero_extend:SI
3522082b 8521 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 8522 (clobber (reg:CC FLAGS_REG))]
d2836273 8523 "TARGET_64BIT"
0f40f9f7 8524 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8525 [(set_attr "type" "alu")
8526 (set_attr "length_immediate" "0")
8527 (set_attr "mode" "QI")])
e075ae69
RH
8528
8529(define_insn "*andqi_ext_2"
d2836273 8530 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8531 (const_int 8)
8532 (const_int 8))
8533 (and:SI
8534 (zero_extract:SI
8535 (match_operand 1 "ext_register_operand" "%0")
8536 (const_int 8)
8537 (const_int 8))
8538 (zero_extract:SI
d2836273 8539 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
8540 (const_int 8)
8541 (const_int 8))))
8bc527af 8542 (clobber (reg:CC FLAGS_REG))]
e075ae69 8543 ""
0f40f9f7 8544 "and{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
8545 [(set_attr "type" "alu")
8546 (set_attr "length_immediate" "0")
8547 (set_attr "mode" "QI")])
2f41793e
JH
8548
8549;; Convert wide AND instructions with immediate operand to shorter QImode
8550;; equivalents when possible.
d1f87653 8551;; Don't do the splitting with memory operands, since it introduces risk
2f41793e
JH
8552;; of memory mismatch stalls. We may want to do the splitting for optimizing
8553;; for size, but that can (should?) be handled by generic code instead.
8554(define_split
8555 [(set (match_operand 0 "register_operand" "")
8556 (and (match_operand 1 "register_operand" "")
8557 (match_operand 2 "const_int_operand" "")))
8bc527af 8558 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8559 "reload_completed
8560 && QI_REG_P (operands[0])
8561 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8562 && !(~INTVAL (operands[2]) & ~(255 << 8))
8563 && GET_MODE (operands[0]) != QImode"
8564 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8565 (and:SI (zero_extract:SI (match_dup 1)
8566 (const_int 8) (const_int 8))
8567 (match_dup 2)))
8bc527af 8568 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8569 "operands[0] = gen_lowpart (SImode, operands[0]);
8570 operands[1] = gen_lowpart (SImode, operands[1]);
8571 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8572
8573;; Since AND can be encoded with sign extended immediate, this is only
8574;; profitable when 7th bit is not set.
8575(define_split
8576 [(set (match_operand 0 "register_operand" "")
8577 (and (match_operand 1 "general_operand" "")
8578 (match_operand 2 "const_int_operand" "")))
8bc527af 8579 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8580 "reload_completed
8581 && ANY_QI_REG_P (operands[0])
8582 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8583 && !(~INTVAL (operands[2]) & ~255)
8584 && !(INTVAL (operands[2]) & 128)
8585 && GET_MODE (operands[0]) != QImode"
8586 [(parallel [(set (strict_low_part (match_dup 0))
8587 (and:QI (match_dup 1)
8588 (match_dup 2)))
8bc527af 8589 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8590 "operands[0] = gen_lowpart (QImode, operands[0]);
8591 operands[1] = gen_lowpart (QImode, operands[1]);
8592 operands[2] = gen_lowpart (QImode, operands[2]);")
886c62d1 8593\f
e075ae69 8594;; Logical inclusive OR instructions
57dbca5e 8595
e075ae69
RH
8596;; %%% This used to optimize known byte-wide and operations to memory.
8597;; If this is considered useful, it should be done with splitters.
8598
9b70259d
JH
8599(define_expand "iordi3"
8600 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8601 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8602 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 8603 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8604 "TARGET_64BIT"
8605 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8606
8607(define_insn "*iordi_1_rex64"
8608 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8609 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8610 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8bc527af 8611 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8612 "TARGET_64BIT
8613 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 8614 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8615 [(set_attr "type" "alu")
8616 (set_attr "mode" "DI")])
8617
8618(define_insn "*iordi_2_rex64"
42fabf21 8619 [(set (reg FLAGS_REG)
9b70259d
JH
8620 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8621 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8622 (const_int 0)))
8623 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8624 (ior:DI (match_dup 1) (match_dup 2)))]
8625 "TARGET_64BIT
8626 && ix86_match_ccmode (insn, CCNOmode)
8627 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 8628 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8629 [(set_attr "type" "alu")
8630 (set_attr "mode" "DI")])
8631
8632(define_insn "*iordi_3_rex64"
42fabf21 8633 [(set (reg FLAGS_REG)
9b70259d
JH
8634 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8635 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8636 (const_int 0)))
8637 (clobber (match_scratch:DI 0 "=r"))]
8638 "TARGET_64BIT
8639 && ix86_match_ccmode (insn, CCNOmode)
8640 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 8641 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "DI")])
8644
8645
e075ae69
RH
8646(define_expand "iorsi3"
8647 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8648 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8649 (match_operand:SI 2 "general_operand" "")))
8bc527af 8650 (clobber (reg:CC FLAGS_REG))]
57dbca5e 8651 ""
e075ae69
RH
8652 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8653
8654(define_insn "*iorsi_1"
8655 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8656 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8657 (match_operand:SI 2 "general_operand" "ri,rmi")))
8bc527af 8658 (clobber (reg:CC FLAGS_REG))]
e075ae69 8659 "ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8660 "or{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
e075ae69 8663
9b70259d
JH
8664;; See comment for addsi_1_zext why we do use nonimmediate_operand
8665(define_insn "*iorsi_1_zext"
8666 [(set (match_operand:DI 0 "register_operand" "=rm")
8667 (zero_extend:DI
8668 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669 (match_operand:SI 2 "general_operand" "rim"))))
8bc527af 8670 (clobber (reg:CC FLAGS_REG))]
9b70259d 8671 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8672 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8673 [(set_attr "type" "alu")
8674 (set_attr "mode" "SI")])
8675
8676(define_insn "*iorsi_1_zext_imm"
8677 [(set (match_operand:DI 0 "register_operand" "=rm")
8678 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8679 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8bc527af 8680 (clobber (reg:CC FLAGS_REG))]
9b70259d 8681 "TARGET_64BIT"
0f40f9f7 8682 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8683 [(set_attr "type" "alu")
8684 (set_attr "mode" "SI")])
8685
e075ae69 8686(define_insn "*iorsi_2"
42fabf21 8687 [(set (reg FLAGS_REG)
16189740
RH
8688 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8689 (match_operand:SI 2 "general_operand" "rim,ri"))
8690 (const_int 0)))
e075ae69
RH
8691 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8692 (ior:SI (match_dup 1) (match_dup 2)))]
16189740
RH
8693 "ix86_match_ccmode (insn, CCNOmode)
8694 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8695 "or{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8696 [(set_attr "type" "alu")
8697 (set_attr "mode" "SI")])
e075ae69 8698
9b70259d
JH
8699;; See comment for addsi_1_zext why we do use nonimmediate_operand
8700;; ??? Special case for immediate operand is missing - it is tricky.
8701(define_insn "*iorsi_2_zext"
42fabf21 8702 [(set (reg FLAGS_REG)
9b70259d
JH
8703 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8704 (match_operand:SI 2 "general_operand" "rim"))
8705 (const_int 0)))
8706 (set (match_operand:DI 0 "register_operand" "=r")
8707 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8708 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8709 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8710 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8711 [(set_attr "type" "alu")
8712 (set_attr "mode" "SI")])
8713
8714(define_insn "*iorsi_2_zext_imm"
42fabf21 8715 [(set (reg FLAGS_REG)
9b70259d
JH
8716 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8717 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8718 (const_int 0)))
8719 (set (match_operand:DI 0 "register_operand" "=r")
8720 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8721 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8722 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8723 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8724 [(set_attr "type" "alu")
8725 (set_attr "mode" "SI")])
8726
d90ffc8d 8727(define_insn "*iorsi_3"
42fabf21 8728 [(set (reg FLAGS_REG)
d90ffc8d
JH
8729 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8730 (match_operand:SI 2 "general_operand" "rim"))
8731 (const_int 0)))
8732 (clobber (match_scratch:SI 0 "=r"))]
8733 "ix86_match_ccmode (insn, CCNOmode)
8734 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 8735 "or{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8736 [(set_attr "type" "alu")
8737 (set_attr "mode" "SI")])
8738
e075ae69
RH
8739(define_expand "iorhi3"
8740 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8741 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8742 (match_operand:HI 2 "general_operand" "")))
8bc527af 8743 (clobber (reg:CC FLAGS_REG))]
d9f32422 8744 "TARGET_HIMODE_MATH"
e075ae69
RH
8745 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8746
8747(define_insn "*iorhi_1"
8748 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8749 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8750 (match_operand:HI 2 "general_operand" "rmi,ri")))
8bc527af 8751 (clobber (reg:CC FLAGS_REG))]
e075ae69 8752 "ix86_binary_operator_ok (IOR, HImode, operands)"
0f40f9f7 8753 "or{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8754 [(set_attr "type" "alu")
8755 (set_attr "mode" "HI")])
e075ae69 8756
e075ae69 8757(define_insn "*iorhi_2"
42fabf21 8758 [(set (reg FLAGS_REG)
16189740
RH
8759 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8760 (match_operand:HI 2 "general_operand" "rim,ri"))
8761 (const_int 0)))
e075ae69
RH
8762 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8763 (ior:HI (match_dup 1) (match_dup 2)))]
16189740
RH
8764 "ix86_match_ccmode (insn, CCNOmode)
8765 && ix86_binary_operator_ok (IOR, HImode, operands)"
0f40f9f7 8766 "or{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "HI")])
e075ae69 8769
d90ffc8d 8770(define_insn "*iorhi_3"
42fabf21 8771 [(set (reg FLAGS_REG)
d90ffc8d
JH
8772 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8773 (match_operand:HI 2 "general_operand" "rim"))
8774 (const_int 0)))
8775 (clobber (match_scratch:HI 0 "=r"))]
8776 "ix86_match_ccmode (insn, CCNOmode)
8777 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 8778 "or{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8779 [(set_attr "type" "alu")
8780 (set_attr "mode" "HI")])
8781
e075ae69
RH
8782(define_expand "iorqi3"
8783 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8784 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8785 (match_operand:QI 2 "general_operand" "")))
8bc527af 8786 (clobber (reg:CC FLAGS_REG))]
d9f32422 8787 "TARGET_QIMODE_MATH"
e075ae69
RH
8788 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8789
8790;; %%% Potential partial reg stall on alternative 2. What to do?
8791(define_insn "*iorqi_1"
7c6b971d 8792 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
e075ae69 8793 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 8794 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8bc527af 8795 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
8796 "ix86_binary_operator_ok (IOR, QImode, operands)"
8797 "@
0f40f9f7
ZW
8798 or{b}\t{%2, %0|%0, %2}
8799 or{b}\t{%2, %0|%0, %2}
8800 or{l}\t{%k2, %k0|%k0, %k2}"
6ef67412 8801 [(set_attr "type" "alu")
a1b8572c
JH
8802 (set_attr "mode" "QI,QI,SI")])
8803
8804(define_insn "*iorqi_1_slp"
8805 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8806 (ior:QI (match_dup 0)
8807 (match_operand:QI 1 "general_operand" "qmi,qi")))
8bc527af 8808 (clobber (reg:CC FLAGS_REG))]
1b245ade
JH
8809 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8810 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 8811 "or{b}\t{%1, %0|%0, %1}"
a1b8572c 8812 [(set_attr "type" "alu1")
6ef67412 8813 (set_attr "mode" "QI")])
e075ae69
RH
8814
8815(define_insn "*iorqi_2"
42fabf21 8816 [(set (reg FLAGS_REG)
16189740
RH
8817 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8818 (match_operand:QI 2 "general_operand" "qim,qi"))
8819 (const_int 0)))
e075ae69
RH
8820 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8821 (ior:QI (match_dup 1) (match_dup 2)))]
16189740
RH
8822 "ix86_match_ccmode (insn, CCNOmode)
8823 && ix86_binary_operator_ok (IOR, QImode, operands)"
0f40f9f7 8824 "or{b}\t{%2, %0|%0, %2}"
6ef67412
JH
8825 [(set_attr "type" "alu")
8826 (set_attr "mode" "QI")])
d90ffc8d 8827
a1b8572c 8828(define_insn "*iorqi_2_slp"
42fabf21 8829 [(set (reg FLAGS_REG)
a1b8572c
JH
8830 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8831 (match_operand:QI 1 "general_operand" "qim,qi"))
8832 (const_int 0)))
8833 (set (strict_low_part (match_dup 0))
8834 (ior:QI (match_dup 0) (match_dup 1)))]
2f41793e 8835 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade
JH
8836 && ix86_match_ccmode (insn, CCNOmode)
8837 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 8838 "or{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8839 [(set_attr "type" "alu1")
8840 (set_attr "mode" "QI")])
8841
d90ffc8d 8842(define_insn "*iorqi_3"
42fabf21 8843 [(set (reg FLAGS_REG)
d90ffc8d
JH
8844 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8845 (match_operand:QI 2 "general_operand" "qim"))
8846 (const_int 0)))
7e08e190 8847 (clobber (match_scratch:QI 0 "=q"))]
d90ffc8d
JH
8848 "ix86_match_ccmode (insn, CCNOmode)
8849 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 8850 "or{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8851 [(set_attr "type" "alu")
8852 (set_attr "mode" "QI")])
8853
2f41793e
JH
8854(define_insn "iorqi_ext_0"
8855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8856 (const_int 8)
8857 (const_int 8))
8858 (ior:SI
8859 (zero_extract:SI
8860 (match_operand 1 "ext_register_operand" "0")
8861 (const_int 8)
8862 (const_int 8))
8863 (match_operand 2 "const_int_operand" "n")))
8bc527af 8864 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8865 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8866 "or{b}\t{%2, %h0|%h0, %2}"
8867 [(set_attr "type" "alu")
8868 (set_attr "length_immediate" "1")
8869 (set_attr "mode" "QI")])
8870
8871(define_insn "*iorqi_ext_1"
8872 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8873 (const_int 8)
8874 (const_int 8))
8875 (ior:SI
8876 (zero_extract:SI
8877 (match_operand 1 "ext_register_operand" "0")
8878 (const_int 8)
8879 (const_int 8))
8880 (zero_extend:SI
8881 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 8882 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8883 "!TARGET_64BIT
8884 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8885 "or{b}\t{%2, %h0|%h0, %2}"
8886 [(set_attr "type" "alu")
8887 (set_attr "length_immediate" "0")
8888 (set_attr "mode" "QI")])
8889
8890(define_insn "*iorqi_ext_1_rex64"
8891 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8892 (const_int 8)
8893 (const_int 8))
8894 (ior:SI
8895 (zero_extract:SI
8896 (match_operand 1 "ext_register_operand" "0")
8897 (const_int 8)
8898 (const_int 8))
8899 (zero_extend:SI
8900 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 8901 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8902 "TARGET_64BIT
8903 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8904 "or{b}\t{%2, %h0|%h0, %2}"
8905 [(set_attr "type" "alu")
8906 (set_attr "length_immediate" "0")
8907 (set_attr "mode" "QI")])
8908
8909(define_insn "*iorqi_ext_2"
8910 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8911 (const_int 8)
8912 (const_int 8))
8913 (ior:SI
8914 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8915 (const_int 8)
8916 (const_int 8))
8917 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8918 (const_int 8)
8919 (const_int 8))))
8bc527af 8920 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8921 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8922 "ior{b}\t{%h2, %h0|%h0, %h2}"
8923 [(set_attr "type" "alu")
8924 (set_attr "length_immediate" "0")
8925 (set_attr "mode" "QI")])
8926
8927(define_split
8928 [(set (match_operand 0 "register_operand" "")
8929 (ior (match_operand 1 "register_operand" "")
8930 (match_operand 2 "const_int_operand" "")))
8bc527af 8931 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8932 "reload_completed
8933 && QI_REG_P (operands[0])
8934 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8935 && !(INTVAL (operands[2]) & ~(255 << 8))
8936 && GET_MODE (operands[0]) != QImode"
8937 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8938 (ior:SI (zero_extract:SI (match_dup 1)
8939 (const_int 8) (const_int 8))
8940 (match_dup 2)))
8bc527af 8941 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8942 "operands[0] = gen_lowpart (SImode, operands[0]);
8943 operands[1] = gen_lowpart (SImode, operands[1]);
8944 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8945
8946;; Since OR can be encoded with sign extended immediate, this is only
8947;; profitable when 7th bit is set.
8948(define_split
8949 [(set (match_operand 0 "register_operand" "")
8950 (ior (match_operand 1 "general_operand" "")
8951 (match_operand 2 "const_int_operand" "")))
8bc527af 8952 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8953 "reload_completed
8954 && ANY_QI_REG_P (operands[0])
8955 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8956 && !(INTVAL (operands[2]) & ~255)
8957 && (INTVAL (operands[2]) & 128)
8958 && GET_MODE (operands[0]) != QImode"
8959 [(parallel [(set (strict_low_part (match_dup 0))
8960 (ior:QI (match_dup 1)
8961 (match_dup 2)))
8bc527af 8962 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8963 "operands[0] = gen_lowpart (QImode, operands[0]);
8964 operands[1] = gen_lowpart (QImode, operands[1]);
8965 operands[2] = gen_lowpart (QImode, operands[2]);")
e075ae69
RH
8966\f
8967;; Logical XOR instructions
a269a03c 8968
e075ae69
RH
8969;; %%% This used to optimize known byte-wide and operations to memory.
8970;; If this is considered useful, it should be done with splitters.
57dbca5e 8971
9b70259d
JH
8972(define_expand "xordi3"
8973 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8974 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8975 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 8976 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8977 "TARGET_64BIT"
8978 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8979
8980(define_insn "*xordi_1_rex64"
8981 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8982 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8983 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8bc527af 8984 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8985 "TARGET_64BIT
8986 && ix86_binary_operator_ok (XOR, DImode, operands)"
8987 "@
5a0855a0 8988 xor{q}\t{%2, %0|%0, %2}
0f40f9f7 8989 xor{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8990 [(set_attr "type" "alu")
8991 (set_attr "mode" "DI,DI")])
8992
8993(define_insn "*xordi_2_rex64"
42fabf21 8994 [(set (reg FLAGS_REG)
9b70259d
JH
8995 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8996 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8997 (const_int 0)))
8998 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8999 (xor:DI (match_dup 1) (match_dup 2)))]
9000 "TARGET_64BIT
9001 && ix86_match_ccmode (insn, CCNOmode)
9002 && ix86_binary_operator_ok (XOR, DImode, operands)"
9003 "@
5a0855a0 9004 xor{q}\t{%2, %0|%0, %2}
0f40f9f7 9005 xor{q}\t{%2, %0|%0, %2}"
9b70259d
JH
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "DI,DI")])
9008
9009(define_insn "*xordi_3_rex64"
42fabf21 9010 [(set (reg FLAGS_REG)
9b70259d
JH
9011 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9012 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9013 (const_int 0)))
9014 (clobber (match_scratch:DI 0 "=r"))]
9015 "TARGET_64BIT
9016 && ix86_match_ccmode (insn, CCNOmode)
9017 && ix86_binary_operator_ok (XOR, DImode, operands)"
0f40f9f7 9018 "xor{q}\t{%2, %0|%0, %2}"
9b70259d
JH
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "DI")])
9021
e075ae69
RH
9022(define_expand "xorsi3"
9023 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9024 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9025 (match_operand:SI 2 "general_operand" "")))
8bc527af 9026 (clobber (reg:CC FLAGS_REG))]
57dbca5e 9027 ""
e075ae69 9028 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
a269a03c 9029
e075ae69
RH
9030(define_insn "*xorsi_1"
9031 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9032 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9033 (match_operand:SI 2 "general_operand" "ri,rm")))
8bc527af 9034 (clobber (reg:CC FLAGS_REG))]
e075ae69 9035 "ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9036 "xor{l}\t{%2, %0|%0, %2}"
6ef67412
JH
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "SI")])
e075ae69 9039
9b70259d
JH
9040;; See comment for addsi_1_zext why we do use nonimmediate_operand
9041;; Add speccase for immediates
9042(define_insn "*xorsi_1_zext"
9043 [(set (match_operand:DI 0 "register_operand" "=r")
9044 (zero_extend:DI
9045 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9046 (match_operand:SI 2 "general_operand" "rim"))))
8bc527af 9047 (clobber (reg:CC FLAGS_REG))]
9b70259d 9048 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9049 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
9050 [(set_attr "type" "alu")
9051 (set_attr "mode" "SI")])
9052
9053(define_insn "*xorsi_1_zext_imm"
9054 [(set (match_operand:DI 0 "register_operand" "=r")
9055 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9056 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8bc527af 9057 (clobber (reg:CC FLAGS_REG))]
9b70259d 9058 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9059 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
9060 [(set_attr "type" "alu")
9061 (set_attr "mode" "SI")])
9062
e075ae69 9063(define_insn "*xorsi_2"
42fabf21 9064 [(set (reg FLAGS_REG)
16189740
RH
9065 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9066 (match_operand:SI 2 "general_operand" "rim,ri"))
9067 (const_int 0)))
e075ae69
RH
9068 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9069 (xor:SI (match_dup 1) (match_dup 2)))]
16189740
RH
9070 "ix86_match_ccmode (insn, CCNOmode)
9071 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9072 "xor{l}\t{%2, %0|%0, %2}"
6ef67412
JH
9073 [(set_attr "type" "alu")
9074 (set_attr "mode" "SI")])
e075ae69 9075
9b70259d
JH
9076;; See comment for addsi_1_zext why we do use nonimmediate_operand
9077;; ??? Special case for immediate operand is missing - it is tricky.
9078(define_insn "*xorsi_2_zext"
42fabf21 9079 [(set (reg FLAGS_REG)
9b70259d
JH
9080 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9081 (match_operand:SI 2 "general_operand" "rim"))
9082 (const_int 0)))
9083 (set (match_operand:DI 0 "register_operand" "=r")
9084 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9085 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9086 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9087 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
9088 [(set_attr "type" "alu")
9089 (set_attr "mode" "SI")])
9090
9091(define_insn "*xorsi_2_zext_imm"
42fabf21 9092 [(set (reg FLAGS_REG)
9b70259d
JH
9093 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9094 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9095 (const_int 0)))
9096 (set (match_operand:DI 0 "register_operand" "=r")
9097 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9099 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9100 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
9101 [(set_attr "type" "alu")
9102 (set_attr "mode" "SI")])
9103
d90ffc8d 9104(define_insn "*xorsi_3"
42fabf21 9105 [(set (reg FLAGS_REG)
d90ffc8d
JH
9106 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9107 (match_operand:SI 2 "general_operand" "rim"))
9108 (const_int 0)))
9109 (clobber (match_scratch:SI 0 "=r"))]
9110 "ix86_match_ccmode (insn, CCNOmode)
9111 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 9112 "xor{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
9113 [(set_attr "type" "alu")
9114 (set_attr "mode" "SI")])
9115
e075ae69
RH
9116(define_expand "xorhi3"
9117 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9118 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9119 (match_operand:HI 2 "general_operand" "")))
8bc527af 9120 (clobber (reg:CC FLAGS_REG))]
d9f32422 9121 "TARGET_HIMODE_MATH"
e075ae69
RH
9122 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9123
9124(define_insn "*xorhi_1"
9125 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9126 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9127 (match_operand:HI 2 "general_operand" "rmi,ri")))
8bc527af 9128 (clobber (reg:CC FLAGS_REG))]
e075ae69 9129 "ix86_binary_operator_ok (XOR, HImode, operands)"
0f40f9f7 9130 "xor{w}\t{%2, %0|%0, %2}"
6ef67412
JH
9131 [(set_attr "type" "alu")
9132 (set_attr "mode" "HI")])
57dbca5e 9133
e075ae69 9134(define_insn "*xorhi_2"
42fabf21 9135 [(set (reg FLAGS_REG)
16189740
RH
9136 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9137 (match_operand:HI 2 "general_operand" "rim,ri"))
9138 (const_int 0)))
e075ae69
RH
9139 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9140 (xor:HI (match_dup 1) (match_dup 2)))]
16189740
RH
9141 "ix86_match_ccmode (insn, CCNOmode)
9142 && ix86_binary_operator_ok (XOR, HImode, operands)"
0f40f9f7 9143 "xor{w}\t{%2, %0|%0, %2}"
6ef67412
JH
9144 [(set_attr "type" "alu")
9145 (set_attr "mode" "HI")])
e075ae69 9146
d90ffc8d 9147(define_insn "*xorhi_3"
42fabf21 9148 [(set (reg FLAGS_REG)
d90ffc8d
JH
9149 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9150 (match_operand:HI 2 "general_operand" "rim"))
9151 (const_int 0)))
9152 (clobber (match_scratch:HI 0 "=r"))]
9153 "ix86_match_ccmode (insn, CCNOmode)
9154 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 9155 "xor{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
9156 [(set_attr "type" "alu")
9157 (set_attr "mode" "HI")])
9158
e075ae69
RH
9159(define_expand "xorqi3"
9160 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9161 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9162 (match_operand:QI 2 "general_operand" "")))
8bc527af 9163 (clobber (reg:CC FLAGS_REG))]
d9f32422 9164 "TARGET_QIMODE_MATH"
e075ae69
RH
9165 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9166
9167;; %%% Potential partial reg stall on alternative 2. What to do?
9168(define_insn "*xorqi_1"
7c6b971d 9169 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
e075ae69 9170 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 9171 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8bc527af 9172 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
9173 "ix86_binary_operator_ok (XOR, QImode, operands)"
9174 "@
0f40f9f7
ZW
9175 xor{b}\t{%2, %0|%0, %2}
9176 xor{b}\t{%2, %0|%0, %2}
9177 xor{l}\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
9178 [(set_attr "type" "alu")
9179 (set_attr "mode" "QI,QI,SI")])
9180
b6bb1d56
JH
9181(define_insn "*xorqi_1_slp"
9182 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9183 (xor:QI (match_dup 0)
9184 (match_operand:QI 1 "general_operand" "qi,qmi")))
8bc527af 9185 (clobber (reg:CC FLAGS_REG))]
1b245ade
JH
9186 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9187 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
b6bb1d56
JH
9188 "xor{b}\t{%1, %0|%0, %1}"
9189 [(set_attr "type" "alu1")
9190 (set_attr "mode" "QI")])
9191
2f41793e
JH
9192(define_insn "xorqi_ext_0"
9193 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9194 (const_int 8)
9195 (const_int 8))
9196 (xor:SI
9197 (zero_extract:SI
9198 (match_operand 1 "ext_register_operand" "0")
9199 (const_int 8)
9200 (const_int 8))
9201 (match_operand 2 "const_int_operand" "n")))
8bc527af 9202 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
9203 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9204 "xor{b}\t{%2, %h0|%h0, %2}"
9205 [(set_attr "type" "alu")
9206 (set_attr "length_immediate" "1")
9207 (set_attr "mode" "QI")])
9208
a4414093 9209(define_insn "*xorqi_ext_1"
2f41793e
JH
9210 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9211 (const_int 8)
9212 (const_int 8))
9213 (xor:SI
9214 (zero_extract:SI
9215 (match_operand 1 "ext_register_operand" "0")
9216 (const_int 8)
9217 (const_int 8))
9218 (zero_extend:SI
9219 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 9220 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
9221 "!TARGET_64BIT
9222 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9223 "xor{b}\t{%2, %h0|%h0, %2}"
9224 [(set_attr "type" "alu")
9225 (set_attr "length_immediate" "0")
9226 (set_attr "mode" "QI")])
9227
9228(define_insn "*xorqi_ext_1_rex64"
9229 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9230 (const_int 8)
9231 (const_int 8))
9232 (xor:SI
9233 (zero_extract:SI
9234 (match_operand 1 "ext_register_operand" "0")
9235 (const_int 8)
9236 (const_int 8))
9237 (zero_extend:SI
9238 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 9239 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
9240 "TARGET_64BIT
9241 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9242 "xor{b}\t{%2, %h0|%h0, %2}"
9243 [(set_attr "type" "alu")
9244 (set_attr "length_immediate" "0")
9245 (set_attr "mode" "QI")])
9246
9247(define_insn "*xorqi_ext_2"
d2836273 9248 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6ef67412
JH
9249 (const_int 8)
9250 (const_int 8))
9251 (xor:SI
9252 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9253 (const_int 8)
9254 (const_int 8))
d2836273 9255 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6ef67412
JH
9256 (const_int 8)
9257 (const_int 8))))
8bc527af 9258 (clobber (reg:CC FLAGS_REG))]
2f41793e 9259 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
0f40f9f7 9260 "xor{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
9261 [(set_attr "type" "alu")
9262 (set_attr "length_immediate" "0")
9263 (set_attr "mode" "QI")])
e075ae69 9264
7abd4e00 9265(define_insn "*xorqi_cc_1"
42fabf21 9266 [(set (reg FLAGS_REG)
16189740 9267 (compare
e075ae69
RH
9268 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9269 (match_operand:QI 2 "general_operand" "qim,qi"))
9270 (const_int 0)))
9271 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9272 (xor:QI (match_dup 1) (match_dup 2)))]
16189740
RH
9273 "ix86_match_ccmode (insn, CCNOmode)
9274 && ix86_binary_operator_ok (XOR, QImode, operands)"
0f40f9f7 9275 "xor{b}\t{%2, %0|%0, %2}"
6ef67412
JH
9276 [(set_attr "type" "alu")
9277 (set_attr "mode" "QI")])
e075ae69 9278
b6bb1d56 9279(define_insn "*xorqi_2_slp"
42fabf21 9280 [(set (reg FLAGS_REG)
b6bb1d56
JH
9281 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9282 (match_operand:QI 1 "general_operand" "qim,qi"))
9283 (const_int 0)))
9284 (set (strict_low_part (match_dup 0))
9285 (xor:QI (match_dup 0) (match_dup 1)))]
9286 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade
JH
9287 && ix86_match_ccmode (insn, CCNOmode)
9288 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
b6bb1d56
JH
9289 "xor{b}\t{%1, %0|%0, %1}"
9290 [(set_attr "type" "alu1")
9291 (set_attr "mode" "QI")])
9292
d90ffc8d 9293(define_insn "*xorqi_cc_2"
42fabf21 9294 [(set (reg FLAGS_REG)
d90ffc8d
JH
9295 (compare
9296 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9297 (match_operand:QI 2 "general_operand" "qim"))
9298 (const_int 0)))
7e08e190 9299 (clobber (match_scratch:QI 0 "=q"))]
d90ffc8d
JH
9300 "ix86_match_ccmode (insn, CCNOmode)
9301 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 9302 "xor{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
9303 [(set_attr "type" "alu")
9304 (set_attr "mode" "QI")])
9305
9076b9c1 9306(define_insn "*xorqi_cc_ext_1"
42fabf21 9307 [(set (reg FLAGS_REG)
9076b9c1 9308 (compare
e075ae69
RH
9309 (xor:SI
9310 (zero_extract:SI
9311 (match_operand 1 "ext_register_operand" "0")
9312 (const_int 8)
9313 (const_int 8))
9314 (match_operand:QI 2 "general_operand" "qmn"))
9315 (const_int 0)))
9316 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9317 (const_int 8)
9318 (const_int 8))
9319 (xor:SI
9320 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9321 (match_dup 2)))]
d2836273 9322 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 9323 "xor{b}\t{%2, %h0|%h0, %2}"
d2836273
JH
9324 [(set_attr "type" "alu")
9325 (set_attr "mode" "QI")])
9326
9327(define_insn "*xorqi_cc_ext_1_rex64"
42fabf21 9328 [(set (reg FLAGS_REG)
d2836273
JH
9329 (compare
9330 (xor:SI
9331 (zero_extract:SI
9332 (match_operand 1 "ext_register_operand" "0")
9333 (const_int 8)
9334 (const_int 8))
9335 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9336 (const_int 0)))
9337 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9338 (const_int 8)
9339 (const_int 8))
9340 (xor:SI
9341 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9342 (match_dup 2)))]
9343 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 9344 "xor{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
9345 [(set_attr "type" "alu")
9346 (set_attr "mode" "QI")])
9076b9c1
JH
9347
9348(define_expand "xorqi_cc_ext_1"
9349 [(parallel [
8bc527af 9350 (set (reg:CCNO FLAGS_REG)
9076b9c1
JH
9351 (compare:CCNO
9352 (xor:SI
9353 (zero_extract:SI
9354 (match_operand 1 "ext_register_operand" "")
9355 (const_int 8)
9356 (const_int 8))
9357 (match_operand:QI 2 "general_operand" ""))
9358 (const_int 0)))
9359 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9360 (const_int 8)
9361 (const_int 8))
9362 (xor:SI
9363 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9364 (match_dup 2)))])]
9365 ""
9366 "")
2f41793e
JH
9367
9368(define_split
9369 [(set (match_operand 0 "register_operand" "")
9370 (xor (match_operand 1 "register_operand" "")
9371 (match_operand 2 "const_int_operand" "")))
8bc527af 9372 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
9373 "reload_completed
9374 && QI_REG_P (operands[0])
9375 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9376 && !(INTVAL (operands[2]) & ~(255 << 8))
9377 && GET_MODE (operands[0]) != QImode"
9378 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9379 (xor:SI (zero_extract:SI (match_dup 1)
9380 (const_int 8) (const_int 8))
9381 (match_dup 2)))
8bc527af 9382 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
9383 "operands[0] = gen_lowpart (SImode, operands[0]);
9384 operands[1] = gen_lowpart (SImode, operands[1]);
9385 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9386
9387;; Since XOR can be encoded with sign extended immediate, this is only
9388;; profitable when 7th bit is set.
9389(define_split
9390 [(set (match_operand 0 "register_operand" "")
9391 (xor (match_operand 1 "general_operand" "")
9392 (match_operand 2 "const_int_operand" "")))
8bc527af 9393 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
9394 "reload_completed
9395 && ANY_QI_REG_P (operands[0])
9396 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9397 && !(INTVAL (operands[2]) & ~255)
9398 && (INTVAL (operands[2]) & 128)
9399 && GET_MODE (operands[0]) != QImode"
9400 [(parallel [(set (strict_low_part (match_dup 0))
9401 (xor:QI (match_dup 1)
9402 (match_dup 2)))
8bc527af 9403 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
9404 "operands[0] = gen_lowpart (QImode, operands[0]);
9405 operands[1] = gen_lowpart (QImode, operands[1]);
9406 operands[2] = gen_lowpart (QImode, operands[2]);")
e075ae69
RH
9407\f
9408;; Negation instructions
57dbca5e 9409
06a964de
JH
9410(define_expand "negdi2"
9411 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2756c3d8 9412 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
8bc527af 9413 (clobber (reg:CC FLAGS_REG))])]
06a964de
JH
9414 ""
9415 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9416
9417(define_insn "*negdi2_1"
e075ae69
RH
9418 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9419 (neg:DI (match_operand:DI 1 "general_operand" "0")))
8bc527af 9420 (clobber (reg:CC FLAGS_REG))]
d2836273
JH
9421 "!TARGET_64BIT
9422 && ix86_unary_operator_ok (NEG, DImode, operands)"
e075ae69 9423 "#")
886c62d1 9424
e075ae69
RH
9425(define_split
9426 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9427 (neg:DI (match_operand:DI 1 "general_operand" "")))
8bc527af 9428 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 9429 "!TARGET_64BIT && reload_completed"
e075ae69 9430 [(parallel
8bc527af 9431 [(set (reg:CCZ FLAGS_REG)
16189740 9432 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
e075ae69
RH
9433 (set (match_dup 0) (neg:SI (match_dup 2)))])
9434 (parallel
9435 [(set (match_dup 1)
8bc527af 9436 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9dcbdc7e
JH
9437 (match_dup 3))
9438 (const_int 0)))
8bc527af 9439 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
9440 (parallel
9441 [(set (match_dup 1)
9442 (neg:SI (match_dup 1)))
8bc527af 9443 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
9444 "split_di (operands+1, 1, operands+2, operands+3);
9445 split_di (operands+0, 1, operands+0, operands+1);")
886c62d1 9446
9b70259d
JH
9447(define_insn "*negdi2_1_rex64"
9448 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9449 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
8bc527af 9450 (clobber (reg:CC FLAGS_REG))]
9b70259d 9451 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
0f40f9f7 9452 "neg{q}\t%0"
9b70259d
JH
9453 [(set_attr "type" "negnot")
9454 (set_attr "mode" "DI")])
9455
9456;; The problem with neg is that it does not perform (compare x 0),
9457;; it really performs (compare 0 x), which leaves us with the zero
9458;; flag being the only useful item.
9459
9460(define_insn "*negdi2_cmpz_rex64"
8bc527af 9461 [(set (reg:CCZ FLAGS_REG)
9b70259d
JH
9462 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9463 (const_int 0)))
9464 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9465 (neg:DI (match_dup 1)))]
9466 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
0f40f9f7 9467 "neg{q}\t%0"
9b70259d
JH
9468 [(set_attr "type" "negnot")
9469 (set_attr "mode" "DI")])
9470
9471
06a964de
JH
9472(define_expand "negsi2"
9473 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2756c3d8 9474 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
8bc527af 9475 (clobber (reg:CC FLAGS_REG))])]
06a964de
JH
9476 ""
9477 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9478
9479(define_insn "*negsi2_1"
2ae0f82c 9480 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 9481 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
8bc527af 9482 (clobber (reg:CC FLAGS_REG))]
06a964de 9483 "ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9484 "neg{l}\t%0"
6ef67412
JH
9485 [(set_attr "type" "negnot")
9486 (set_attr "mode" "SI")])
e075ae69 9487
9b70259d
JH
9488;; Combine is quite creative about this pattern.
9489(define_insn "*negsi2_1_zext"
9490 [(set (match_operand:DI 0 "register_operand" "=r")
9491 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9492 (const_int 32)))
9493 (const_int 32)))
8bc527af 9494 (clobber (reg:CC FLAGS_REG))]
9b70259d 9495 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9496 "neg{l}\t%k0"
9b70259d
JH
9497 [(set_attr "type" "negnot")
9498 (set_attr "mode" "SI")])
9499
16189740
RH
9500;; The problem with neg is that it does not perform (compare x 0),
9501;; it really performs (compare 0 x), which leaves us with the zero
9502;; flag being the only useful item.
e075ae69 9503
16189740 9504(define_insn "*negsi2_cmpz"
8bc527af 9505 [(set (reg:CCZ FLAGS_REG)
16189740
RH
9506 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9507 (const_int 0)))
e075ae69
RH
9508 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9509 (neg:SI (match_dup 1)))]
06a964de 9510 "ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9511 "neg{l}\t%0"
6ef67412
JH
9512 [(set_attr "type" "negnot")
9513 (set_attr "mode" "SI")])
886c62d1 9514
9b70259d 9515(define_insn "*negsi2_cmpz_zext"
8bc527af 9516 [(set (reg:CCZ FLAGS_REG)
9b70259d
JH
9517 (compare:CCZ (lshiftrt:DI
9518 (neg:DI (ashift:DI
9519 (match_operand:DI 1 "register_operand" "0")
9520 (const_int 32)))
9521 (const_int 32))
9522 (const_int 0)))
9523 (set (match_operand:DI 0 "register_operand" "=r")
9524 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9525 (const_int 32)))
9526 (const_int 32)))]
9527 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9528 "neg{l}\t%k0"
9b70259d
JH
9529 [(set_attr "type" "negnot")
9530 (set_attr "mode" "SI")])
9531
06a964de
JH
9532(define_expand "neghi2"
9533 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
2756c3d8 9534 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
8bc527af 9535 (clobber (reg:CC FLAGS_REG))])]
d9f32422 9536 "TARGET_HIMODE_MATH"
06a964de
JH
9537 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9538
9539(define_insn "*neghi2_1"
2ae0f82c 9540 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 9541 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
8bc527af 9542 (clobber (reg:CC FLAGS_REG))]
06a964de 9543 "ix86_unary_operator_ok (NEG, HImode, operands)"
0f40f9f7 9544 "neg{w}\t%0"
6ef67412
JH
9545 [(set_attr "type" "negnot")
9546 (set_attr "mode" "HI")])
e075ae69 9547
16189740 9548(define_insn "*neghi2_cmpz"
8bc527af 9549 [(set (reg:CCZ FLAGS_REG)
16189740
RH
9550 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9551 (const_int 0)))
e075ae69
RH
9552 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9553 (neg:HI (match_dup 1)))]
06a964de 9554 "ix86_unary_operator_ok (NEG, HImode, operands)"
0f40f9f7 9555 "neg{w}\t%0"
6ef67412
JH
9556 [(set_attr "type" "negnot")
9557 (set_attr "mode" "HI")])
886c62d1 9558
06a964de
JH
9559(define_expand "negqi2"
9560 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
2756c3d8 9561 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 9562 (clobber (reg:CC FLAGS_REG))])]
d9f32422 9563 "TARGET_QIMODE_MATH"
06a964de
JH
9564 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9565
9566(define_insn "*negqi2_1"
2ae0f82c 9567 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 9568 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
8bc527af 9569 (clobber (reg:CC FLAGS_REG))]
06a964de 9570 "ix86_unary_operator_ok (NEG, QImode, operands)"
0f40f9f7 9571 "neg{b}\t%0"
6ef67412
JH
9572 [(set_attr "type" "negnot")
9573 (set_attr "mode" "QI")])
e075ae69 9574
16189740 9575(define_insn "*negqi2_cmpz"
8bc527af 9576 [(set (reg:CCZ FLAGS_REG)
16189740
RH
9577 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9578 (const_int 0)))
e075ae69
RH
9579 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9580 (neg:QI (match_dup 1)))]
06a964de 9581 "ix86_unary_operator_ok (NEG, QImode, operands)"
0f40f9f7 9582 "neg{b}\t%0"
6ef67412
JH
9583 [(set_attr "type" "negnot")
9584 (set_attr "mode" "QI")])
886c62d1 9585
06a964de 9586;; Changing of sign for FP values is doable using integer unit too.
1ce485ec 9587
06a964de 9588(define_expand "negsf2"
7cacf53e
RH
9589 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9590 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9591 "TARGET_80387 || TARGET_SSE_MATH"
9592 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
b3298882 9593
7cacf53e
RH
9594(define_expand "abssf2"
9595 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9596 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9597 "TARGET_80387 || TARGET_SSE_MATH"
9598 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
b3298882 9599
7cacf53e
RH
9600(define_insn "*absnegsf2_mixed"
9601 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9602 (match_operator:SF 3 "absneg_operator"
9603 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#fr,0 ,0")]))
9604 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
8bc527af 9605 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9606 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9607 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
b3298882
JH
9608 "#")
9609
7cacf53e
RH
9610(define_insn "*absnegsf2_sse"
9611 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#r,x#r,rm#x")
9612 (match_operator:SF 3 "absneg_operator"
9613 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#r,0")]))
9614 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X"))
8bc527af 9615 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9616 "TARGET_SSE_MATH
9617 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9618 "#")
06a964de 9619
7cacf53e 9620(define_insn "*absnegsf2_i387"
e20440c1 9621 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
7cacf53e
RH
9622 (match_operator:SF 3 "absneg_operator"
9623 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9624 (use (match_operand 2 "" ""))
8bc527af 9625 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9626 "TARGET_80387 && !TARGET_SSE_MATH
9627 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
1ce485ec
JH
9628 "#")
9629
06a964de 9630(define_expand "negdf2"
7cacf53e
RH
9631 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9632 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9633 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9634 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
b3298882 9635
7cacf53e
RH
9636(define_expand "absdf2"
9637 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9638 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9639 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9640 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9641
9642(define_insn "*absnegdf2_mixed"
9643 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9644 (match_operator:DF 3 "absneg_operator"
9645 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#fr,0 ,0")]))
9646 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
8bc527af 9647 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9648 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9649 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
b3298882
JH
9650 "#")
9651
7cacf53e
RH
9652(define_insn "*absnegdf2_sse"
9653 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#r,Y#r,rm#Y")
9654 (match_operator:DF 3 "absneg_operator"
9655 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#r,0")]))
9656 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X"))
8bc527af 9657 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9658 "TARGET_SSE2 && TARGET_SSE_MATH
9659 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
141e454b
JH
9660 "#")
9661
7cacf53e
RH
9662(define_insn "*absnegdf2_i387"
9663 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9664 (match_operator:DF 3 "absneg_operator"
9665 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9666 (use (match_operand 2 "" ""))
8bc527af 9667 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9668 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9669 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
b3298882
JH
9670 "#")
9671
7cacf53e
RH
9672(define_expand "negxf2"
9673 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9674 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9675 "TARGET_80387"
9676 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
b3298882 9677
7cacf53e
RH
9678(define_expand "absxf2"
9679 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9680 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9681 "TARGET_80387"
9682 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9683
9684(define_insn "*absnegxf2_i387"
9685 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9686 (match_operator:XF 3 "absneg_operator"
9687 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9688 (use (match_operand 2 "" ""))
8bc527af 9689 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9690 "TARGET_80387
9691 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9692 "#")
9693
9694;; Splitters for fp abs and neg.
b3298882 9695
141e454b 9696(define_split
7cacf53e
RH
9697 [(set (match_operand 0 "fp_register_operand" "")
9698 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9699 (use (match_operand 2 "" ""))
8bc527af 9700 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9701 "reload_completed"
9702 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
141e454b 9703
b3298882 9704(define_split
7cacf53e
RH
9705 [(set (match_operand 0 "register_operand" "")
9706 (match_operator 3 "absneg_operator"
9707 [(match_operand 1 "register_operand" "")]))
9708 (use (match_operand 2 "nonimmediate_operand" ""))
8bc527af 9709 (clobber (reg:CC FLAGS_REG))]
b3298882 9710 "reload_completed && SSE_REG_P (operands[0])"
7cacf53e 9711 [(set (match_dup 0) (match_dup 3))]
b3298882 9712{
7cacf53e
RH
9713 enum machine_mode mode = GET_MODE (operands[0]);
9714 enum machine_mode vmode = GET_MODE (operands[2]);
9715 rtx tmp;
9716
9717 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9718 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
b3298882
JH
9719 if (operands_match_p (operands[0], operands[2]))
9720 {
b3298882
JH
9721 tmp = operands[1];
9722 operands[1] = operands[2];
9723 operands[2] = tmp;
9724 }
7cacf53e
RH
9725 if (GET_CODE (operands[3]) == ABS)
9726 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9727 else
9728 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9729 operands[3] = tmp;
0f40f9f7 9730})
06a964de 9731
1ce485ec 9732(define_split
7cacf53e
RH
9733 [(set (match_operand:SF 0 "register_operand" "")
9734 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9735 (use (match_operand:V4SF 2 "" ""))
8bc527af 9736 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9737 "reload_completed"
9738 [(parallel [(set (match_dup 0) (match_dup 1))
9739 (clobber (reg:CC FLAGS_REG))])]
9740{
9741 rtx tmp;
9742 operands[0] = gen_lowpart (SImode, operands[0]);
9743 if (GET_CODE (operands[1]) == ABS)
9744 {
9745 tmp = gen_int_mode (0x7fffffff, SImode);
9746 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9747 }
9748 else
9749 {
9750 tmp = gen_int_mode (0x80000000, SImode);
9751 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9752 }
9753 operands[1] = tmp;
9754})
1ce485ec
JH
9755
9756(define_split
7cacf53e
RH
9757 [(set (match_operand:DF 0 "register_operand" "")
9758 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9759 (use (match_operand 2 "" ""))
8bc527af 9760 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9761 "reload_completed"
9762 [(parallel [(set (match_dup 0) (match_dup 1))
8bc527af 9763 (clobber (reg:CC FLAGS_REG))])]
7cacf53e
RH
9764{
9765 rtx tmp;
9766 if (TARGET_64BIT)
9767 {
9768 tmp = gen_lowpart (DImode, operands[0]);
9769 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9770 operands[0] = tmp;
2b589241 9771
7cacf53e
RH
9772 if (GET_CODE (operands[1]) == ABS)
9773 tmp = const0_rtx;
9774 else
9775 tmp = gen_rtx_NOT (DImode, tmp);
9776 }
9777 else
9778 {
9779 operands[0] = gen_highpart (SImode, operands[0]);
9780 if (GET_CODE (operands[1]) == ABS)
9781 {
9782 tmp = gen_int_mode (0x7fffffff, SImode);
9783 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9784 }
9785 else
9786 {
9787 tmp = gen_int_mode (0x80000000, SImode);
9788 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9789 }
9790 }
9791 operands[1] = tmp;
9792})
1ce485ec
JH
9793
9794(define_split
7cacf53e
RH
9795 [(set (match_operand:XF 0 "register_operand" "")
9796 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9797 (use (match_operand 2 "" ""))
8bc527af 9798 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9799 "reload_completed"
9800 [(parallel [(set (match_dup 0) (match_dup 1))
9801 (clobber (reg:CC FLAGS_REG))])]
9802{
9803 rtx tmp;
9804 operands[0] = gen_rtx_REG (SImode,
9805 true_regnum (operands[0])
9806 + (TARGET_64BIT ? 1 : 2));
9807 if (GET_CODE (operands[1]) == ABS)
9808 {
9809 tmp = GEN_INT (0x7fff);
9810 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9811 }
9812 else
9813 {
9814 tmp = GEN_INT (0x8000);
9815 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9816 }
9817 operands[1] = tmp;
9818})
1ce485ec
JH
9819
9820(define_split
7cacf53e
RH
9821 [(set (match_operand 0 "memory_operand" "")
9822 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9823 (use (match_operand 2 "" ""))
8bc527af 9824 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9825 "reload_completed"
9826 [(parallel [(set (match_dup 0) (match_dup 1))
8bc527af 9827 (clobber (reg:CC FLAGS_REG))])]
7cacf53e
RH
9828{
9829 enum machine_mode mode = GET_MODE (operands[0]);
9830 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9831 rtx tmp;
9832
9833 operands[0] = adjust_address (operands[0], QImode, size - 1);
9834 if (GET_CODE (operands[1]) == ABS)
9835 {
9836 tmp = gen_int_mode (0x7f, QImode);
9837 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9838 }
9839 else
9840 {
9841 tmp = gen_int_mode (0x80, QImode);
9842 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9843 }
9844 operands[1] = tmp;
9845})
1ce485ec 9846
7cacf53e 9847;; Conditionalize these after reload. If they match before reload, we
1ce485ec
JH
9848;; lose the clobber and ability to use integer instructions.
9849
9850(define_insn "*negsf2_1"
886c62d1 9851 [(set (match_operand:SF 0 "register_operand" "=f")
2ae0f82c 9852 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1ce485ec 9853 "TARGET_80387 && reload_completed"
10195bd8 9854 "fchs"
e075ae69 9855 [(set_attr "type" "fsgn")
56bab446 9856 (set_attr "mode" "SF")])
886c62d1 9857
1ce485ec 9858(define_insn "*negdf2_1"
886c62d1 9859 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 9860 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
1ce485ec 9861 "TARGET_80387 && reload_completed"
10195bd8 9862 "fchs"
e075ae69 9863 [(set_attr "type" "fsgn")
56bab446 9864 (set_attr "mode" "DF")])
886c62d1 9865
7cacf53e
RH
9866(define_insn "*negxf2_1"
9867 [(set (match_operand:XF 0 "register_operand" "=f")
9868 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9869 "TARGET_80387 && reload_completed"
10195bd8 9870 "fchs"
7cacf53e
RH
9871 [(set_attr "type" "fsgn")
9872 (set_attr "mode" "XF")])
9873
9874(define_insn "*abssf2_1"
9875 [(set (match_operand:SF 0 "register_operand" "=f")
9876 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9877 "TARGET_80387 && reload_completed"
9878 "fabs"
9879 [(set_attr "type" "fsgn")
9880 (set_attr "mode" "SF")])
9881
9882(define_insn "*absdf2_1"
9883 [(set (match_operand:DF 0 "register_operand" "=f")
9884 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9885 "TARGET_80387 && reload_completed"
9886 "fabs"
e075ae69 9887 [(set_attr "type" "fsgn")
56bab446 9888 (set_attr "mode" "DF")])
4fb21e90 9889
7cacf53e 9890(define_insn "*absxf2_1"
4fb21e90 9891 [(set (match_operand:XF 0 "register_operand" "=f")
7cacf53e 9892 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
f8a1ebc6 9893 "TARGET_80387 && reload_completed"
7cacf53e
RH
9894 "fabs"
9895 [(set_attr "type" "fsgn")
9896 (set_attr "mode" "DF")])
9897
9898(define_insn "*negextendsfdf2"
9899 [(set (match_operand:DF 0 "register_operand" "=f")
9900 (neg:DF (float_extend:DF
9901 (match_operand:SF 1 "register_operand" "0"))))]
9902 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10195bd8 9903 "fchs"
e075ae69 9904 [(set_attr "type" "fsgn")
7cacf53e 9905 (set_attr "mode" "DF")])
e075ae69 9906
6343a50e 9907(define_insn "*negextenddfxf2"
e075ae69
RH
9908 [(set (match_operand:XF 0 "register_operand" "=f")
9909 (neg:XF (float_extend:XF
9910 (match_operand:DF 1 "register_operand" "0"))))]
f8a1ebc6 9911 "TARGET_80387"
e075ae69
RH
9912 "fchs"
9913 [(set_attr "type" "fsgn")
56bab446 9914 (set_attr "mode" "XF")])
4fb21e90 9915
6343a50e 9916(define_insn "*negextendsfxf2"
4fb21e90 9917 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
9918 (neg:XF (float_extend:XF
9919 (match_operand:SF 1 "register_operand" "0"))))]
2b589241
JH
9920 "TARGET_80387"
9921 "fchs"
9922 [(set_attr "type" "fsgn")
56bab446 9923 (set_attr "mode" "XF")])
886c62d1 9924
6343a50e 9925(define_insn "*absextendsfdf2"
886c62d1 9926 [(set (match_operand:DF 0 "register_operand" "=f")
e075ae69
RH
9927 (abs:DF (float_extend:DF
9928 (match_operand:SF 1 "register_operand" "0"))))]
7cacf53e 9929 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
2ae0f82c 9930 "fabs"
6ef67412
JH
9931 [(set_attr "type" "fsgn")
9932 (set_attr "mode" "DF")])
4fb21e90 9933
6343a50e 9934(define_insn "*absextenddfxf2"
4fb21e90 9935 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
9936 (abs:XF (float_extend:XF
9937 (match_operand:DF 1 "register_operand" "0"))))]
f8a1ebc6 9938 "TARGET_80387"
2ae0f82c 9939 "fabs"
6ef67412
JH
9940 [(set_attr "type" "fsgn")
9941 (set_attr "mode" "XF")])
a199fdd6 9942
6343a50e 9943(define_insn "*absextendsfxf2"
58733f96 9944 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
9945 (abs:XF (float_extend:XF
9946 (match_operand:SF 1 "register_operand" "0"))))]
2b589241
JH
9947 "TARGET_80387"
9948 "fabs"
9949 [(set_attr "type" "fsgn")
9950 (set_attr "mode" "XF")])
886c62d1 9951\f
e075ae69 9952;; One complement instructions
886c62d1 9953
9b70259d
JH
9954(define_expand "one_cmpldi2"
9955 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9956 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9957 "TARGET_64BIT"
9958 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9959
9960(define_insn "*one_cmpldi2_1_rex64"
9961 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9962 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9963 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
0f40f9f7 9964 "not{q}\t%0"
9b70259d
JH
9965 [(set_attr "type" "negnot")
9966 (set_attr "mode" "DI")])
9967
9968(define_insn "*one_cmpldi2_2_rex64"
42fabf21 9969 [(set (reg FLAGS_REG)
9b70259d
JH
9970 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9971 (const_int 0)))
9972 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9973 (not:DI (match_dup 1)))]
9974 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9975 && ix86_unary_operator_ok (NOT, DImode, operands)"
9976 "#"
9977 [(set_attr "type" "alu1")
9978 (set_attr "mode" "DI")])
9979
9980(define_split
25da5dc7
RH
9981 [(set (match_operand 0 "flags_reg_operand" "")
9982 (match_operator 2 "compare_operator"
9983 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9984 (const_int 0)]))
9985 (set (match_operand:DI 1 "nonimmediate_operand" "")
9986 (not:DI (match_dup 3)))]
9b70259d 9987 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
9988 [(parallel [(set (match_dup 0)
9989 (match_op_dup 2
9990 [(xor:DI (match_dup 3) (const_int -1))
9991 (const_int 0)]))
9992 (set (match_dup 1)
9993 (xor:DI (match_dup 3) (const_int -1)))])]
9b70259d
JH
9994 "")
9995
06a964de 9996(define_expand "one_cmplsi2"
a1cbdd7f
JH
9997 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9998 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
06a964de
JH
9999 ""
10000 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10001
10002(define_insn "*one_cmplsi2_1"
2ae0f82c
SC
10003 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10004 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
a1cbdd7f 10005 "ix86_unary_operator_ok (NOT, SImode, operands)"
0f40f9f7 10006 "not{l}\t%0"
6ef67412
JH
10007 [(set_attr "type" "negnot")
10008 (set_attr "mode" "SI")])
bb524860 10009
9b70259d
JH
10010;; ??? Currently never generated - xor is used instead.
10011(define_insn "*one_cmplsi2_1_zext"
10012 [(set (match_operand:DI 0 "register_operand" "=r")
10013 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10014 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
0f40f9f7 10015 "not{l}\t%k0"
9b70259d
JH
10016 [(set_attr "type" "negnot")
10017 (set_attr "mode" "SI")])
10018
06a964de 10019(define_insn "*one_cmplsi2_2"
42fabf21 10020 [(set (reg FLAGS_REG)
16189740
RH
10021 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10022 (const_int 0)))
e075ae69
RH
10023 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10024 (not:SI (match_dup 1)))]
16189740
RH
10025 "ix86_match_ccmode (insn, CCNOmode)
10026 && ix86_unary_operator_ok (NOT, SImode, operands)"
e075ae69 10027 "#"
6ef67412
JH
10028 [(set_attr "type" "alu1")
10029 (set_attr "mode" "SI")])
e075ae69
RH
10030
10031(define_split
25da5dc7
RH
10032 [(set (match_operand 0 "flags_reg_operand" "")
10033 (match_operator 2 "compare_operator"
10034 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10035 (const_int 0)]))
10036 (set (match_operand:SI 1 "nonimmediate_operand" "")
10037 (not:SI (match_dup 3)))]
16189740 10038 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
10039 [(parallel [(set (match_dup 0)
10040 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10041 (const_int 0)]))
10042 (set (match_dup 1)
10043 (xor:SI (match_dup 3) (const_int -1)))])]
e075ae69 10044 "")
886c62d1 10045
9b70259d
JH
10046;; ??? Currently never generated - xor is used instead.
10047(define_insn "*one_cmplsi2_2_zext"
42fabf21 10048 [(set (reg FLAGS_REG)
9b70259d
JH
10049 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10050 (const_int 0)))
10051 (set (match_operand:DI 0 "register_operand" "=r")
10052 (zero_extend:DI (not:SI (match_dup 1))))]
10053 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10054 && ix86_unary_operator_ok (NOT, SImode, operands)"
10055 "#"
10056 [(set_attr "type" "alu1")
10057 (set_attr "mode" "SI")])
10058
10059(define_split
25da5dc7
RH
10060 [(set (match_operand 0 "flags_reg_operand" "")
10061 (match_operator 2 "compare_operator"
10062 [(not:SI (match_operand:SI 3 "register_operand" ""))
10063 (const_int 0)]))
10064 (set (match_operand:DI 1 "register_operand" "")
10065 (zero_extend:DI (not:SI (match_dup 3))))]
9b70259d 10066 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
10067 [(parallel [(set (match_dup 0)
10068 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10069 (const_int 0)]))
10070 (set (match_dup 1)
10071 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9b70259d
JH
10072 "")
10073
06a964de 10074(define_expand "one_cmplhi2"
a1cbdd7f
JH
10075 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10076 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
d9f32422 10077 "TARGET_HIMODE_MATH"
06a964de
JH
10078 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10079
10080(define_insn "*one_cmplhi2_1"
2ae0f82c
SC
10081 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10082 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
a1cbdd7f 10083 "ix86_unary_operator_ok (NOT, HImode, operands)"
0f40f9f7 10084 "not{w}\t%0"
6ef67412
JH
10085 [(set_attr "type" "negnot")
10086 (set_attr "mode" "HI")])
bb524860 10087
06a964de 10088(define_insn "*one_cmplhi2_2"
42fabf21 10089 [(set (reg FLAGS_REG)
16189740
RH
10090 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10091 (const_int 0)))
e075ae69
RH
10092 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10093 (not:HI (match_dup 1)))]
16189740
RH
10094 "ix86_match_ccmode (insn, CCNOmode)
10095 && ix86_unary_operator_ok (NEG, HImode, operands)"
e075ae69 10096 "#"
6ef67412
JH
10097 [(set_attr "type" "alu1")
10098 (set_attr "mode" "HI")])
e075ae69
RH
10099
10100(define_split
25da5dc7
RH
10101 [(set (match_operand 0 "flags_reg_operand" "")
10102 (match_operator 2 "compare_operator"
10103 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10104 (const_int 0)]))
10105 (set (match_operand:HI 1 "nonimmediate_operand" "")
10106 (not:HI (match_dup 3)))]
16189740 10107 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
10108 [(parallel [(set (match_dup 0)
10109 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10110 (const_int 0)]))
10111 (set (match_dup 1)
10112 (xor:HI (match_dup 3) (const_int -1)))])]
e075ae69 10113 "")
886c62d1 10114
e075ae69 10115;; %%% Potential partial reg stall on alternative 1. What to do?
06a964de 10116(define_expand "one_cmplqi2"
a1cbdd7f
JH
10117 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10118 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
d9f32422 10119 "TARGET_QIMODE_MATH"
06a964de
JH
10120 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10121
10122(define_insn "*one_cmplqi2_1"
7c6b971d 10123 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
e075ae69 10124 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
a1cbdd7f 10125 "ix86_unary_operator_ok (NOT, QImode, operands)"
e075ae69 10126 "@
0f40f9f7
ZW
10127 not{b}\t%0
10128 not{l}\t%k0"
6ef67412
JH
10129 [(set_attr "type" "negnot")
10130 (set_attr "mode" "QI,SI")])
bb524860 10131
06a964de 10132(define_insn "*one_cmplqi2_2"
42fabf21 10133 [(set (reg FLAGS_REG)
16189740
RH
10134 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10135 (const_int 0)))
e075ae69
RH
10136 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10137 (not:QI (match_dup 1)))]
16189740
RH
10138 "ix86_match_ccmode (insn, CCNOmode)
10139 && ix86_unary_operator_ok (NOT, QImode, operands)"
e075ae69 10140 "#"
6ef67412
JH
10141 [(set_attr "type" "alu1")
10142 (set_attr "mode" "QI")])
e075ae69
RH
10143
10144(define_split
25da5dc7
RH
10145 [(set (match_operand 0 "flags_reg_operand" "")
10146 (match_operator 2 "compare_operator"
10147 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10148 (const_int 0)]))
10149 (set (match_operand:QI 1 "nonimmediate_operand" "")
10150 (not:QI (match_dup 3)))]
16189740 10151 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
10152 [(parallel [(set (match_dup 0)
10153 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10154 (const_int 0)]))
10155 (set (match_dup 1)
10156 (xor:QI (match_dup 3) (const_int -1)))])]
e075ae69 10157 "")
886c62d1 10158\f
e075ae69 10159;; Arithmetic shift instructions
886c62d1
JVA
10160
10161;; DImode shifts are implemented using the i386 "shift double" opcode,
10162;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10163;; is variable, then the count is in %cl and the "imm" operand is dropped
10164;; from the assembler input.
e075ae69 10165;;
886c62d1
JVA
10166;; This instruction shifts the target reg/mem as usual, but instead of
10167;; shifting in zeros, bits are shifted in from reg operand. If the insn
10168;; is a left shift double, bits are taken from the high order bits of
10169;; reg, else if the insn is a shift right double, bits are taken from the
10170;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10171;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
e075ae69 10172;;
886c62d1
JVA
10173;; Since sh[lr]d does not change the `reg' operand, that is done
10174;; separately, making all shifts emit pairs of shift double and normal
10175;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10176;; support a 63 bit shift, each shift where the count is in a reg expands
f58acb67 10177;; to a pair of shifts, a branch, a shift by 32 and a label.
e075ae69 10178;;
886c62d1
JVA
10179;; If the shift count is a constant, we need never emit more than one
10180;; shift pair, instead using moves and sign extension for counts greater
10181;; than 31.
10182
56c0e8fa 10183(define_expand "ashldi3"
93330ea1
RH
10184 [(set (match_operand:DI 0 "shiftdi_operand" "")
10185 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10186 (match_operand:QI 2 "nonmemory_operand" "")))]
56c0e8fa 10187 ""
93330ea1 10188 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
56c0e8fa 10189
371bc54b
JH
10190(define_insn "*ashldi3_1_rex64"
10191 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9a9286af 10192 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
7c17f553 10193 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
8bc527af 10194 (clobber (reg:CC FLAGS_REG))]
371bc54b 10195 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
371bc54b
JH
10196{
10197 switch (get_attr_type (insn))
10198 {
10199 case TYPE_ALU:
10200 if (operands[2] != const1_rtx)
10201 abort ();
10202 if (!rtx_equal_p (operands[0], operands[1]))
10203 abort ();
0f40f9f7 10204 return "add{q}\t{%0, %0|%0, %0}";
371bc54b
JH
10205
10206 case TYPE_LEA:
10207 if (GET_CODE (operands[2]) != CONST_INT
10208 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10209 abort ();
10210 operands[1] = gen_rtx_MULT (DImode, operands[1],
10211 GEN_INT (1 << INTVAL (operands[2])));
0f40f9f7 10212 return "lea{q}\t{%a1, %0|%0, %a1}";
371bc54b
JH
10213
10214 default:
10215 if (REG_P (operands[2]))
0f40f9f7 10216 return "sal{q}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10217 else if (operands[2] == const1_rtx
495333a6 10218 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10219 return "sal{q}\t%0";
371bc54b 10220 else
0f40f9f7 10221 return "sal{q}\t{%2, %0|%0, %2}";
371bc54b 10222 }
0f40f9f7 10223}
371bc54b
JH
10224 [(set (attr "type")
10225 (cond [(eq_attr "alternative" "1")
10226 (const_string "lea")
10227 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10228 (const_int 0))
10229 (match_operand 0 "register_operand" ""))
10230 (match_operand 2 "const1_operand" ""))
10231 (const_string "alu")
10232 ]
10233 (const_string "ishift")))
10234 (set_attr "mode" "DI")])
10235
10236;; Convert lea to the lea pattern to avoid flags dependency.
10237(define_split
10238 [(set (match_operand:DI 0 "register_operand" "")
9a9286af 10239 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
371bc54b 10240 (match_operand:QI 2 "immediate_operand" "")))
8bc527af 10241 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 10242 "TARGET_64BIT && reload_completed
371bc54b
JH
10243 && true_regnum (operands[0]) != true_regnum (operands[1])"
10244 [(set (match_dup 0)
10245 (mult:DI (match_dup 1)
10246 (match_dup 2)))]
d8bf17f9 10247 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
371bc54b
JH
10248
10249;; This pattern can't accept a variable shift count, since shifts by
10250;; zero don't affect the flags. We assume that shifts by constant
10251;; zero are optimized away.
10252(define_insn "*ashldi3_cmp_rex64"
42fabf21 10253 [(set (reg FLAGS_REG)
371bc54b
JH
10254 (compare
10255 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10256 (match_operand:QI 2 "immediate_operand" "e"))
10257 (const_int 0)))
10258 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10259 (ashift:DI (match_dup 1) (match_dup 2)))]
10260 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10261 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
371bc54b
JH
10262{
10263 switch (get_attr_type (insn))
10264 {
10265 case TYPE_ALU:
10266 if (operands[2] != const1_rtx)
10267 abort ();
0f40f9f7 10268 return "add{q}\t{%0, %0|%0, %0}";
371bc54b
JH
10269
10270 default:
10271 if (REG_P (operands[2]))
0f40f9f7 10272 return "sal{q}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10273 else if (operands[2] == const1_rtx
495333a6 10274 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10275 return "sal{q}\t%0";
371bc54b 10276 else
0f40f9f7 10277 return "sal{q}\t{%2, %0|%0, %2}";
371bc54b 10278 }
0f40f9f7 10279}
371bc54b
JH
10280 [(set (attr "type")
10281 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10282 (const_int 0))
10283 (match_operand 0 "register_operand" ""))
10284 (match_operand 2 "const1_operand" ""))
10285 (const_string "alu")
10286 ]
10287 (const_string "ishift")))
10288 (set_attr "mode" "DI")])
10289
93330ea1
RH
10290(define_insn "*ashldi3_1"
10291 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10292 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10293 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
8bc527af 10294 (clobber (reg:CC FLAGS_REG))]
371bc54b 10295 "!TARGET_64BIT"
e075ae69
RH
10296 "#"
10297 [(set_attr "type" "multi")])
886c62d1 10298
93330ea1
RH
10299;; By default we don't ask for a scratch register, because when DImode
10300;; values are manipulated, registers are already at a premium. But if
10301;; we have one handy, we won't turn it away.
10302(define_peephole2
10303 [(match_scratch:SI 3 "r")
10304 (parallel [(set (match_operand:DI 0 "register_operand" "")
10305 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10306 (match_operand:QI 2 "nonmemory_operand" "")))
10307 (clobber (reg:CC FLAGS_REG))])
10308 (match_dup 3)]
10309 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69
RH
10310 [(const_int 0)]
10311 "ix86_split_ashldi (operands, operands[3]); DONE;")
47f59fd4 10312
e075ae69
RH
10313(define_split
10314 [(set (match_operand:DI 0 "register_operand" "")
93330ea1 10315 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
e075ae69 10316 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 10317 (clobber (reg:CC FLAGS_REG))]
93330ea1 10318 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
e075ae69
RH
10319 [(const_int 0)]
10320 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
6ec6d558 10321
e075ae69
RH
10322(define_insn "x86_shld_1"
10323 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10324 (ior:SI (ashift:SI (match_dup 0)
10325 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10326 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10327 (minus:QI (const_int 32) (match_dup 2)))))
8bc527af 10328 (clobber (reg:CC FLAGS_REG))]
6ec6d558 10329 ""
e075ae69 10330 "@
0f40f9f7
ZW
10331 shld{l}\t{%2, %1, %0|%0, %1, %2}
10332 shld{l}\t{%s2%1, %0|%0, %1, %2}"
e075ae69 10333 [(set_attr "type" "ishift")
6ef67412
JH
10334 (set_attr "prefix_0f" "1")
10335 (set_attr "mode" "SI")
e075ae69 10336 (set_attr "pent_pair" "np")
56bab446 10337 (set_attr "athlon_decode" "vector")])
e075ae69
RH
10338
10339(define_expand "x86_shift_adj_1"
8bc527af 10340 [(set (reg:CCZ FLAGS_REG)
16189740
RH
10341 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10342 (const_int 32))
10343 (const_int 0)))
e075ae69 10344 (set (match_operand:SI 0 "register_operand" "")
8bc527af 10345 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
e075ae69
RH
10346 (match_operand:SI 1 "register_operand" "")
10347 (match_dup 0)))
10348 (set (match_dup 1)
8bc527af 10349 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
e075ae69
RH
10350 (match_operand:SI 3 "register_operand" "r")
10351 (match_dup 1)))]
10352 "TARGET_CMOVE"
6ec6d558
JH
10353 "")
10354
e075ae69
RH
10355(define_expand "x86_shift_adj_2"
10356 [(use (match_operand:SI 0 "register_operand" ""))
10357 (use (match_operand:SI 1 "register_operand" ""))
10358 (use (match_operand:QI 2 "register_operand" ""))]
886c62d1 10359 ""
e075ae69
RH
10360{
10361 rtx label = gen_label_rtx ();
10362 rtx tmp;
886c62d1 10363
16189740 10364 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
886c62d1 10365
16189740 10366 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
10367 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10368 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10369 gen_rtx_LABEL_REF (VOIDmode, label),
10370 pc_rtx);
10371 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10372 JUMP_LABEL (tmp) = label;
886c62d1 10373
e075ae69 10374 emit_move_insn (operands[0], operands[1]);
93330ea1 10375 ix86_expand_clear (operands[1]);
886c62d1 10376
e075ae69
RH
10377 emit_label (label);
10378 LABEL_NUSES (label) = 1;
56c0e8fa
JVA
10379
10380 DONE;
0f40f9f7 10381})
56c0e8fa 10382
d525dfdf
JH
10383(define_expand "ashlsi3"
10384 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10385 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10386 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 10387 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
10388 ""
10389 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10390
10391(define_insn "*ashlsi3_1"
e075ae69 10392 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9a9286af 10393 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
e075ae69 10394 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8bc527af 10395 (clobber (reg:CC FLAGS_REG))]
d525dfdf 10396 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
2ae0f82c 10397{
e075ae69
RH
10398 switch (get_attr_type (insn))
10399 {
10400 case TYPE_ALU:
10401 if (operands[2] != const1_rtx)
10402 abort ();
10403 if (!rtx_equal_p (operands[0], operands[1]))
10404 abort ();
0f40f9f7 10405 return "add{l}\t{%0, %0|%0, %0}";
2ae0f82c 10406
e075ae69 10407 case TYPE_LEA:
0f40f9f7 10408 return "#";
2ae0f82c 10409
e075ae69
RH
10410 default:
10411 if (REG_P (operands[2]))
0f40f9f7 10412 return "sal{l}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10413 else if (operands[2] == const1_rtx
495333a6 10414 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10415 return "sal{l}\t%0";
e075ae69 10416 else
0f40f9f7 10417 return "sal{l}\t{%2, %0|%0, %2}";
e075ae69 10418 }
0f40f9f7 10419}
e075ae69
RH
10420 [(set (attr "type")
10421 (cond [(eq_attr "alternative" "1")
10422 (const_string "lea")
10423 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10424 (const_int 0))
10425 (match_operand 0 "register_operand" ""))
10426 (match_operand 2 "const1_operand" ""))
10427 (const_string "alu")
10428 ]
6ef67412
JH
10429 (const_string "ishift")))
10430 (set_attr "mode" "SI")])
e075ae69 10431
1c27d4b2
JH
10432;; Convert lea to the lea pattern to avoid flags dependency.
10433(define_split
58787064 10434 [(set (match_operand 0 "register_operand" "")
7ec70495 10435 (ashift (match_operand 1 "index_register_operand" "")
ca4ae08d 10436 (match_operand:QI 2 "const_int_operand" "")))
8bc527af 10437 (clobber (reg:CC FLAGS_REG))]
abe24fb3 10438 "reload_completed
9a9286af
RH
10439 && true_regnum (operands[0]) != true_regnum (operands[1])
10440 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
58787064 10441 [(const_int 0)]
58787064
JH
10442{
10443 rtx pat;
9a9286af
RH
10444 enum machine_mode mode = GET_MODE (operands[0]);
10445
10446 if (GET_MODE_SIZE (mode) < 4)
10447 operands[0] = gen_lowpart (SImode, operands[0]);
10448 if (mode != Pmode)
10449 operands[1] = gen_lowpart (Pmode, operands[1]);
d8bf17f9 10450 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9a9286af 10451
58787064
JH
10452 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10453 if (Pmode != SImode)
10454 pat = gen_rtx_SUBREG (SImode, pat, 0);
10455 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10456 DONE;
0f40f9f7 10457})
1c27d4b2 10458
7ec70495
JH
10459;; Rare case of shifting RSP is handled by generating move and shift
10460(define_split
10461 [(set (match_operand 0 "register_operand" "")
10462 (ashift (match_operand 1 "register_operand" "")
10463 (match_operand:QI 2 "const_int_operand" "")))
8bc527af 10464 (clobber (reg:CC FLAGS_REG))]
7ec70495
JH
10465 "reload_completed
10466 && true_regnum (operands[0]) != true_regnum (operands[1])"
10467 [(const_int 0)]
10468{
10469 rtx pat, clob;
10470 emit_move_insn (operands[1], operands[0]);
10471 pat = gen_rtx_SET (VOIDmode, operands[0],
10472 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10473 operands[0], operands[2]));
10474 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10475 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10476 DONE;
10477})
10478
371bc54b
JH
10479(define_insn "*ashlsi3_1_zext"
10480 [(set (match_operand:DI 0 "register_operand" "=r,r")
9a9286af 10481 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
371bc54b 10482 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
8bc527af 10483 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 10484 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
371bc54b
JH
10485{
10486 switch (get_attr_type (insn))
10487 {
10488 case TYPE_ALU:
10489 if (operands[2] != const1_rtx)
10490 abort ();
0f40f9f7 10491 return "add{l}\t{%k0, %k0|%k0, %k0}";
371bc54b
JH
10492
10493 case TYPE_LEA:
0f40f9f7 10494 return "#";
371bc54b
JH
10495
10496 default:
10497 if (REG_P (operands[2]))
0f40f9f7 10498 return "sal{l}\t{%b2, %k0|%k0, %b2}";
b4e0dd8e 10499 else if (operands[2] == const1_rtx
495333a6 10500 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10501 return "sal{l}\t%k0";
371bc54b 10502 else
0f40f9f7 10503 return "sal{l}\t{%2, %k0|%k0, %2}";
371bc54b 10504 }
0f40f9f7 10505}
371bc54b
JH
10506 [(set (attr "type")
10507 (cond [(eq_attr "alternative" "1")
10508 (const_string "lea")
10509 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10510 (const_int 0))
10511 (match_operand 2 "const1_operand" ""))
10512 (const_string "alu")
10513 ]
10514 (const_string "ishift")))
10515 (set_attr "mode" "SI")])
10516
10517;; Convert lea to the lea pattern to avoid flags dependency.
10518(define_split
10519 [(set (match_operand:DI 0 "register_operand" "")
10520 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10521 (match_operand:QI 2 "const_int_operand" ""))))
8bc527af 10522 (clobber (reg:CC FLAGS_REG))]
bc8a6d63 10523 "TARGET_64BIT && reload_completed
371bc54b 10524 && true_regnum (operands[0]) != true_regnum (operands[1])"
bc8a6d63
RH
10525 [(set (match_dup 0) (zero_extend:DI
10526 (subreg:SI (mult:SI (match_dup 1)
10527 (match_dup 2)) 0)))]
371bc54b
JH
10528{
10529 operands[1] = gen_lowpart (Pmode, operands[1]);
d8bf17f9 10530 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
0f40f9f7 10531})
371bc54b 10532
28cefcd2
BS
10533;; This pattern can't accept a variable shift count, since shifts by
10534;; zero don't affect the flags. We assume that shifts by constant
10535;; zero are optimized away.
2c873473 10536(define_insn "*ashlsi3_cmp"
42fabf21 10537 [(set (reg FLAGS_REG)
16189740 10538 (compare
e075ae69 10539 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
794a292d 10540 (match_operand:QI 2 "const_int_1_31_operand" "I"))
e075ae69
RH
10541 (const_int 0)))
10542 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10543 (ashift:SI (match_dup 1) (match_dup 2)))]
9076b9c1 10544 "ix86_match_ccmode (insn, CCGOCmode)
16189740 10545 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
886c62d1 10546{
e075ae69 10547 switch (get_attr_type (insn))
886c62d1 10548 {
e075ae69
RH
10549 case TYPE_ALU:
10550 if (operands[2] != const1_rtx)
10551 abort ();
0f40f9f7 10552 return "add{l}\t{%0, %0|%0, %0}";
886c62d1 10553
e075ae69
RH
10554 default:
10555 if (REG_P (operands[2]))
0f40f9f7 10556 return "sal{l}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10557 else if (operands[2] == const1_rtx
495333a6 10558 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10559 return "sal{l}\t%0";
e075ae69 10560 else
0f40f9f7 10561 return "sal{l}\t{%2, %0|%0, %2}";
56c0e8fa 10562 }
0f40f9f7 10563}
e075ae69
RH
10564 [(set (attr "type")
10565 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10566 (const_int 0))
10567 (match_operand 0 "register_operand" ""))
10568 (match_operand 2 "const1_operand" ""))
10569 (const_string "alu")
10570 ]
6ef67412
JH
10571 (const_string "ishift")))
10572 (set_attr "mode" "SI")])
e075ae69 10573
371bc54b 10574(define_insn "*ashlsi3_cmp_zext"
42fabf21 10575 [(set (reg FLAGS_REG)
371bc54b
JH
10576 (compare
10577 (ashift:SI (match_operand:SI 1 "register_operand" "0")
794a292d 10578 (match_operand:QI 2 "const_int_1_31_operand" "I"))
371bc54b
JH
10579 (const_int 0)))
10580 (set (match_operand:DI 0 "register_operand" "=r")
10581 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10582 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10583 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
371bc54b
JH
10584{
10585 switch (get_attr_type (insn))
10586 {
10587 case TYPE_ALU:
10588 if (operands[2] != const1_rtx)
10589 abort ();
0f40f9f7 10590 return "add{l}\t{%k0, %k0|%k0, %k0}";
371bc54b
JH
10591
10592 default:
10593 if (REG_P (operands[2]))
0f40f9f7 10594 return "sal{l}\t{%b2, %k0|%k0, %b2}";
b4e0dd8e 10595 else if (operands[2] == const1_rtx
495333a6 10596 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10597 return "sal{l}\t%k0";
371bc54b 10598 else
0f40f9f7 10599 return "sal{l}\t{%2, %k0|%k0, %2}";
371bc54b 10600 }
0f40f9f7 10601}
371bc54b
JH
10602 [(set (attr "type")
10603 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10604 (const_int 0))
10605 (match_operand 2 "const1_operand" ""))
10606 (const_string "alu")
10607 ]
10608 (const_string "ishift")))
10609 (set_attr "mode" "SI")])
10610
d525dfdf
JH
10611(define_expand "ashlhi3"
10612 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10613 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10614 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 10615 (clobber (reg:CC FLAGS_REG))]
d9f32422 10616 "TARGET_HIMODE_MATH"
d525dfdf
JH
10617 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10618
58787064
JH
10619(define_insn "*ashlhi3_1_lea"
10620 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9a9286af 10621 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
58787064 10622 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8bc527af 10623 (clobber (reg:CC FLAGS_REG))]
58787064
JH
10624 "!TARGET_PARTIAL_REG_STALL
10625 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
58787064
JH
10626{
10627 switch (get_attr_type (insn))
10628 {
10629 case TYPE_LEA:
0f40f9f7 10630 return "#";
58787064
JH
10631 case TYPE_ALU:
10632 if (operands[2] != const1_rtx)
10633 abort ();
0f40f9f7 10634 return "add{w}\t{%0, %0|%0, %0}";
58787064
JH
10635
10636 default:
10637 if (REG_P (operands[2]))
0f40f9f7 10638 return "sal{w}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10639 else if (operands[2] == const1_rtx
495333a6 10640 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10641 return "sal{w}\t%0";
58787064 10642 else
0f40f9f7 10643 return "sal{w}\t{%2, %0|%0, %2}";
58787064 10644 }
0f40f9f7 10645}
58787064
JH
10646 [(set (attr "type")
10647 (cond [(eq_attr "alternative" "1")
10648 (const_string "lea")
10649 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10650 (const_int 0))
10651 (match_operand 0 "register_operand" ""))
10652 (match_operand 2 "const1_operand" ""))
10653 (const_string "alu")
10654 ]
10655 (const_string "ishift")))
10656 (set_attr "mode" "HI,SI")])
10657
d525dfdf 10658(define_insn "*ashlhi3_1"
e075ae69
RH
10659 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10660 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10661 (match_operand:QI 2 "nonmemory_operand" "cI")))
8bc527af 10662 (clobber (reg:CC FLAGS_REG))]
58787064
JH
10663 "TARGET_PARTIAL_REG_STALL
10664 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
56c0e8fa 10665{
e075ae69
RH
10666 switch (get_attr_type (insn))
10667 {
10668 case TYPE_ALU:
10669 if (operands[2] != const1_rtx)
10670 abort ();
0f40f9f7 10671 return "add{w}\t{%0, %0|%0, %0}";
886c62d1 10672
e075ae69
RH
10673 default:
10674 if (REG_P (operands[2]))
0f40f9f7 10675 return "sal{w}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10676 else if (operands[2] == const1_rtx
495333a6 10677 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10678 return "sal{w}\t%0";
e075ae69 10679 else
0f40f9f7 10680 return "sal{w}\t{%2, %0|%0, %2}";
e075ae69 10681 }
0f40f9f7 10682}
e075ae69
RH
10683 [(set (attr "type")
10684 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10685 (const_int 0))
10686 (match_operand 0 "register_operand" ""))
10687 (match_operand 2 "const1_operand" ""))
10688 (const_string "alu")
10689 ]
6ef67412
JH
10690 (const_string "ishift")))
10691 (set_attr "mode" "HI")])
bb62e19a 10692
28cefcd2
BS
10693;; This pattern can't accept a variable shift count, since shifts by
10694;; zero don't affect the flags. We assume that shifts by constant
10695;; zero are optimized away.
2c873473 10696(define_insn "*ashlhi3_cmp"
42fabf21 10697 [(set (reg FLAGS_REG)
16189740 10698 (compare
e075ae69 10699 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
794a292d 10700 (match_operand:QI 2 "const_int_1_31_operand" "I"))
e075ae69
RH
10701 (const_int 0)))
10702 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10703 (ashift:HI (match_dup 1) (match_dup 2)))]
9076b9c1 10704 "ix86_match_ccmode (insn, CCGOCmode)
16189740 10705 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
886c62d1 10706{
e075ae69
RH
10707 switch (get_attr_type (insn))
10708 {
10709 case TYPE_ALU:
10710 if (operands[2] != const1_rtx)
10711 abort ();
0f40f9f7 10712 return "add{w}\t{%0, %0|%0, %0}";
886c62d1 10713
e075ae69
RH
10714 default:
10715 if (REG_P (operands[2]))
0f40f9f7 10716 return "sal{w}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10717 else if (operands[2] == const1_rtx
495333a6 10718 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10719 return "sal{w}\t%0";
e075ae69 10720 else
0f40f9f7 10721 return "sal{w}\t{%2, %0|%0, %2}";
e075ae69 10722 }
0f40f9f7 10723}
e075ae69
RH
10724 [(set (attr "type")
10725 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10726 (const_int 0))
10727 (match_operand 0 "register_operand" ""))
10728 (match_operand 2 "const1_operand" ""))
10729 (const_string "alu")
10730 ]
6ef67412
JH
10731 (const_string "ishift")))
10732 (set_attr "mode" "HI")])
e075ae69 10733
d525dfdf
JH
10734(define_expand "ashlqi3"
10735 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10736 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10737 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 10738 (clobber (reg:CC FLAGS_REG))]
d9f32422 10739 "TARGET_QIMODE_MATH"
d525dfdf
JH
10740 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10741
e075ae69 10742;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
10743
10744(define_insn "*ashlqi3_1_lea"
10745 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9a9286af 10746 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
91f9a498 10747 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8bc527af 10748 (clobber (reg:CC FLAGS_REG))]
58787064
JH
10749 "!TARGET_PARTIAL_REG_STALL
10750 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
58787064
JH
10751{
10752 switch (get_attr_type (insn))
10753 {
10754 case TYPE_LEA:
0f40f9f7 10755 return "#";
58787064
JH
10756 case TYPE_ALU:
10757 if (operands[2] != const1_rtx)
10758 abort ();
1a06f5fe 10759 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
0f40f9f7 10760 return "add{l}\t{%k0, %k0|%k0, %k0}";
58787064 10761 else
0f40f9f7 10762 return "add{b}\t{%0, %0|%0, %0}";
58787064
JH
10763
10764 default:
10765 if (REG_P (operands[2]))
10766 {
10767 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10768 return "sal{l}\t{%b2, %k0|%k0, %b2}";
58787064 10769 else
0f40f9f7 10770 return "sal{b}\t{%b2, %0|%0, %b2}";
58787064 10771 }
b4e0dd8e 10772 else if (operands[2] == const1_rtx
495333a6 10773 && (TARGET_SHIFT1 || optimize_size))
58787064
JH
10774 {
10775 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10776 return "sal{l}\t%0";
58787064 10777 else
0f40f9f7 10778 return "sal{b}\t%0";
58787064
JH
10779 }
10780 else
10781 {
10782 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10783 return "sal{l}\t{%2, %k0|%k0, %2}";
58787064 10784 else
0f40f9f7 10785 return "sal{b}\t{%2, %0|%0, %2}";
58787064
JH
10786 }
10787 }
0f40f9f7 10788}
58787064
JH
10789 [(set (attr "type")
10790 (cond [(eq_attr "alternative" "2")
10791 (const_string "lea")
10792 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10793 (const_int 0))
10794 (match_operand 0 "register_operand" ""))
10795 (match_operand 2 "const1_operand" ""))
10796 (const_string "alu")
10797 ]
10798 (const_string "ishift")))
10799 (set_attr "mode" "QI,SI,SI")])
10800
d525dfdf
JH
10801(define_insn "*ashlqi3_1"
10802 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
e075ae69
RH
10803 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10804 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
8bc527af 10805 (clobber (reg:CC FLAGS_REG))]
58787064
JH
10806 "TARGET_PARTIAL_REG_STALL
10807 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
886c62d1 10808{
e075ae69
RH
10809 switch (get_attr_type (insn))
10810 {
10811 case TYPE_ALU:
10812 if (operands[2] != const1_rtx)
10813 abort ();
1a06f5fe 10814 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
0f40f9f7 10815 return "add{l}\t{%k0, %k0|%k0, %k0}";
e075ae69 10816 else
0f40f9f7 10817 return "add{b}\t{%0, %0|%0, %0}";
886c62d1 10818
e075ae69
RH
10819 default:
10820 if (REG_P (operands[2]))
10821 {
1a06f5fe 10822 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10823 return "sal{l}\t{%b2, %k0|%k0, %b2}";
e075ae69 10824 else
0f40f9f7 10825 return "sal{b}\t{%b2, %0|%0, %b2}";
e075ae69 10826 }
b4e0dd8e 10827 else if (operands[2] == const1_rtx
495333a6 10828 && (TARGET_SHIFT1 || optimize_size))
8bad7136 10829 {
1a06f5fe 10830 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10831 return "sal{l}\t%0";
8bad7136 10832 else
0f40f9f7 10833 return "sal{b}\t%0";
8bad7136 10834 }
e075ae69
RH
10835 else
10836 {
1a06f5fe 10837 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10838 return "sal{l}\t{%2, %k0|%k0, %2}";
e075ae69 10839 else
0f40f9f7 10840 return "sal{b}\t{%2, %0|%0, %2}";
e075ae69
RH
10841 }
10842 }
0f40f9f7 10843}
e075ae69
RH
10844 [(set (attr "type")
10845 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10846 (const_int 0))
10847 (match_operand 0 "register_operand" ""))
10848 (match_operand 2 "const1_operand" ""))
10849 (const_string "alu")
10850 ]
6ef67412
JH
10851 (const_string "ishift")))
10852 (set_attr "mode" "QI,SI")])
e075ae69 10853
28cefcd2
BS
10854;; This pattern can't accept a variable shift count, since shifts by
10855;; zero don't affect the flags. We assume that shifts by constant
10856;; zero are optimized away.
2c873473 10857(define_insn "*ashlqi3_cmp"
42fabf21 10858 [(set (reg FLAGS_REG)
16189740 10859 (compare
e075ae69 10860 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
794a292d 10861 (match_operand:QI 2 "const_int_1_31_operand" "I"))
e075ae69
RH
10862 (const_int 0)))
10863 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10864 (ashift:QI (match_dup 1) (match_dup 2)))]
9076b9c1 10865 "ix86_match_ccmode (insn, CCGOCmode)
16189740 10866 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
886c62d1 10867{
e075ae69
RH
10868 switch (get_attr_type (insn))
10869 {
10870 case TYPE_ALU:
10871 if (operands[2] != const1_rtx)
10872 abort ();
0f40f9f7 10873 return "add{b}\t{%0, %0|%0, %0}";
e075ae69
RH
10874
10875 default:
10876 if (REG_P (operands[2]))
0f40f9f7 10877 return "sal{b}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10878 else if (operands[2] == const1_rtx
495333a6 10879 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10880 return "sal{b}\t%0";
e075ae69 10881 else
0f40f9f7 10882 return "sal{b}\t{%2, %0|%0, %2}";
e075ae69 10883 }
0f40f9f7 10884}
e075ae69
RH
10885 [(set (attr "type")
10886 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10887 (const_int 0))
10888 (match_operand 0 "register_operand" ""))
10889 (match_operand 2 "const1_operand" ""))
10890 (const_string "alu")
10891 ]
6ef67412
JH
10892 (const_string "ishift")))
10893 (set_attr "mode" "QI")])
886c62d1
JVA
10894
10895;; See comment above `ashldi3' about how this works.
10896
e075ae69 10897(define_expand "ashrdi3"
93330ea1
RH
10898 [(set (match_operand:DI 0 "shiftdi_operand" "")
10899 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10900 (match_operand:QI 2 "nonmemory_operand" "")))]
56c0e8fa 10901 ""
93330ea1 10902 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
2ae0f82c 10903
93330ea1 10904(define_insn "*ashrdi3_63_rex64"
371bc54b
JH
10905 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10906 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10907 (match_operand:DI 2 "const_int_operand" "i,i")))
8bc527af 10908 (clobber (reg:CC FLAGS_REG))]
93330ea1
RH
10909 "TARGET_64BIT && INTVAL (operands[2]) == 63
10910 && (TARGET_USE_CLTD || optimize_size)
371bc54b
JH
10911 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10912 "@
10913 {cqto|cqo}
0f40f9f7 10914 sar{q}\t{%2, %0|%0, %2}"
371bc54b
JH
10915 [(set_attr "type" "imovx,ishift")
10916 (set_attr "prefix_0f" "0,*")
10917 (set_attr "length_immediate" "0,*")
10918 (set_attr "modrm" "0,1")
10919 (set_attr "mode" "DI")])
10920
10921(define_insn "*ashrdi3_1_one_bit_rex64"
10922 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10923 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 10924 (match_operand:QI 2 "const1_operand" "")))
8bc527af 10925 (clobber (reg:CC FLAGS_REG))]
371bc54b 10926 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
495333a6 10927 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 10928 "sar{q}\t%0"
371bc54b
JH
10929 [(set_attr "type" "ishift")
10930 (set (attr "length")
10931 (if_then_else (match_operand:DI 0 "register_operand" "")
10932 (const_string "2")
10933 (const_string "*")))])
10934
10935(define_insn "*ashrdi3_1_rex64"
10936 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10937 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7c17f553 10938 (match_operand:QI 2 "nonmemory_operand" "J,c")))
8bc527af 10939 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
10940 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10941 "@
0f40f9f7
ZW
10942 sar{q}\t{%2, %0|%0, %2}
10943 sar{q}\t{%b2, %0|%0, %b2}"
371bc54b
JH
10944 [(set_attr "type" "ishift")
10945 (set_attr "mode" "DI")])
10946
10947;; This pattern can't accept a variable shift count, since shifts by
10948;; zero don't affect the flags. We assume that shifts by constant
10949;; zero are optimized away.
10950(define_insn "*ashrdi3_one_bit_cmp_rex64"
42fabf21 10951 [(set (reg FLAGS_REG)
371bc54b
JH
10952 (compare
10953 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 10954 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
10955 (const_int 0)))
10956 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10957 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10958 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
495333a6 10959 && (TARGET_SHIFT1 || optimize_size)
371bc54b 10960 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
0f40f9f7 10961 "sar{q}\t%0"
371bc54b
JH
10962 [(set_attr "type" "ishift")
10963 (set (attr "length")
10964 (if_then_else (match_operand:DI 0 "register_operand" "")
10965 (const_string "2")
10966 (const_string "*")))])
10967
10968;; This pattern can't accept a variable shift count, since shifts by
10969;; zero don't affect the flags. We assume that shifts by constant
10970;; zero are optimized away.
10971(define_insn "*ashrdi3_cmp_rex64"
42fabf21 10972 [(set (reg FLAGS_REG)
371bc54b
JH
10973 (compare
10974 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10975 (match_operand:QI 2 "const_int_operand" "n"))
10976 (const_int 0)))
10977 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10978 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10979 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10980 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
0f40f9f7 10981 "sar{q}\t{%2, %0|%0, %2}"
371bc54b
JH
10982 [(set_attr "type" "ishift")
10983 (set_attr "mode" "DI")])
10984
93330ea1 10985(define_insn "*ashrdi3_1"
e075ae69
RH
10986 [(set (match_operand:DI 0 "register_operand" "=r")
10987 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10988 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8bc527af 10989 (clobber (reg:CC FLAGS_REG))]
371bc54b 10990 "!TARGET_64BIT"
e075ae69
RH
10991 "#"
10992 [(set_attr "type" "multi")])
886c62d1 10993
93330ea1
RH
10994;; By default we don't ask for a scratch register, because when DImode
10995;; values are manipulated, registers are already at a premium. But if
10996;; we have one handy, we won't turn it away.
10997(define_peephole2
10998 [(match_scratch:SI 3 "r")
10999 (parallel [(set (match_operand:DI 0 "register_operand" "")
11000 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11001 (match_operand:QI 2 "nonmemory_operand" "")))
11002 (clobber (reg:CC FLAGS_REG))])
11003 (match_dup 3)]
11004 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69
RH
11005 [(const_int 0)]
11006 "ix86_split_ashrdi (operands, operands[3]); DONE;")
886c62d1 11007
e075ae69
RH
11008(define_split
11009 [(set (match_operand:DI 0 "register_operand" "")
11010 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11011 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11012 (clobber (reg:CC FLAGS_REG))]
93330ea1 11013 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
e075ae69
RH
11014 [(const_int 0)]
11015 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
886c62d1 11016
e075ae69
RH
11017(define_insn "x86_shrd_1"
11018 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11019 (ior:SI (ashiftrt:SI (match_dup 0)
11020 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11021 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11022 (minus:QI (const_int 32) (match_dup 2)))))
8bc527af 11023 (clobber (reg:CC FLAGS_REG))]
886c62d1 11024 ""
e075ae69 11025 "@
0f40f9f7
ZW
11026 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11027 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
e075ae69 11028 [(set_attr "type" "ishift")
6ef67412 11029 (set_attr "prefix_0f" "1")
e075ae69 11030 (set_attr "pent_pair" "np")
6ef67412 11031 (set_attr "mode" "SI")])
e075ae69
RH
11032
11033(define_expand "x86_shift_adj_3"
11034 [(use (match_operand:SI 0 "register_operand" ""))
11035 (use (match_operand:SI 1 "register_operand" ""))
11036 (use (match_operand:QI 2 "register_operand" ""))]
11037 ""
886c62d1 11038{
e075ae69
RH
11039 rtx label = gen_label_rtx ();
11040 rtx tmp;
11041
16189740 11042 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
e075ae69 11043
16189740 11044 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
11045 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11046 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11047 gen_rtx_LABEL_REF (VOIDmode, label),
11048 pc_rtx);
11049 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11050 JUMP_LABEL (tmp) = label;
11051
11052 emit_move_insn (operands[0], operands[1]);
11053 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11054
11055 emit_label (label);
11056 LABEL_NUSES (label) = 1;
11057
11058 DONE;
0f40f9f7 11059})
886c62d1 11060
e075ae69
RH
11061(define_insn "ashrsi3_31"
11062 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11063 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11064 (match_operand:SI 2 "const_int_operand" "i,i")))
8bc527af 11065 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
11066 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11067 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
e075ae69
RH
11068 "@
11069 {cltd|cdq}
0f40f9f7 11070 sar{l}\t{%2, %0|%0, %2}"
6ef67412
JH
11071 [(set_attr "type" "imovx,ishift")
11072 (set_attr "prefix_0f" "0,*")
11073 (set_attr "length_immediate" "0,*")
11074 (set_attr "modrm" "0,1")
11075 (set_attr "mode" "SI")])
e075ae69 11076
371bc54b
JH
11077(define_insn "*ashrsi3_31_zext"
11078 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11079 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11080 (match_operand:SI 2 "const_int_operand" "i,i"))))
8bc527af 11081 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
11082 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11083 && INTVAL (operands[2]) == 31
11084 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
371bc54b
JH
11085 "@
11086 {cltd|cdq}
0f40f9f7 11087 sar{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
11088 [(set_attr "type" "imovx,ishift")
11089 (set_attr "prefix_0f" "0,*")
11090 (set_attr "length_immediate" "0,*")
11091 (set_attr "modrm" "0,1")
11092 (set_attr "mode" "SI")])
11093
d525dfdf
JH
11094(define_expand "ashrsi3"
11095 [(set (match_operand:SI 0 "nonimmediate_operand" "")
155d8a47 11096 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
d525dfdf 11097 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11098 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
11099 ""
11100 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11101
8bad7136
JL
11102(define_insn "*ashrsi3_1_one_bit"
11103 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11104 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 11105 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11106 (clobber (reg:CC FLAGS_REG))]
8bad7136 11107 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
495333a6 11108 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11109 "sar{l}\t%0"
8bad7136
JL
11110 [(set_attr "type" "ishift")
11111 (set (attr "length")
11112 (if_then_else (match_operand:SI 0 "register_operand" "")
11113 (const_string "2")
11114 (const_string "*")))])
11115
371bc54b
JH
11116(define_insn "*ashrsi3_1_one_bit_zext"
11117 [(set (match_operand:DI 0 "register_operand" "=r")
11118 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
630eef90 11119 (match_operand:QI 2 "const1_operand" ""))))
8bc527af 11120 (clobber (reg:CC FLAGS_REG))]
371bc54b 11121 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
495333a6 11122 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11123 "sar{l}\t%k0"
371bc54b
JH
11124 [(set_attr "type" "ishift")
11125 (set_attr "length" "2")])
11126
d525dfdf 11127(define_insn "*ashrsi3_1"
e075ae69
RH
11128 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11129 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11130 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11131 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11132 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
e075ae69 11133 "@
0f40f9f7
ZW
11134 sar{l}\t{%2, %0|%0, %2}
11135 sar{l}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11136 [(set_attr "type" "ishift")
11137 (set_attr "mode" "SI")])
886c62d1 11138
371bc54b
JH
11139(define_insn "*ashrsi3_1_zext"
11140 [(set (match_operand:DI 0 "register_operand" "=r,r")
11141 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11142 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 11143 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11144 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11145 "@
0f40f9f7
ZW
11146 sar{l}\t{%2, %k0|%k0, %2}
11147 sar{l}\t{%b2, %k0|%k0, %b2}"
371bc54b
JH
11148 [(set_attr "type" "ishift")
11149 (set_attr "mode" "SI")])
11150
8bad7136
JL
11151;; This pattern can't accept a variable shift count, since shifts by
11152;; zero don't affect the flags. We assume that shifts by constant
11153;; zero are optimized away.
2c873473 11154(define_insn "*ashrsi3_one_bit_cmp"
42fabf21 11155 [(set (reg FLAGS_REG)
8bad7136
JL
11156 (compare
11157 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 11158 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
11159 (const_int 0)))
11160 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11161 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2c873473 11162 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11163 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11164 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11165 "sar{l}\t%0"
8bad7136
JL
11166 [(set_attr "type" "ishift")
11167 (set (attr "length")
11168 (if_then_else (match_operand:SI 0 "register_operand" "")
11169 (const_string "2")
11170 (const_string "*")))])
11171
371bc54b 11172(define_insn "*ashrsi3_one_bit_cmp_zext"
42fabf21 11173 [(set (reg FLAGS_REG)
371bc54b
JH
11174 (compare
11175 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
630eef90 11176 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
11177 (const_int 0)))
11178 (set (match_operand:DI 0 "register_operand" "=r")
11179 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11180 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
495333a6 11181 && (TARGET_SHIFT1 || optimize_size)
371bc54b 11182 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11183 "sar{l}\t%k0"
371bc54b
JH
11184 [(set_attr "type" "ishift")
11185 (set_attr "length" "2")])
11186
28cefcd2
BS
11187;; This pattern can't accept a variable shift count, since shifts by
11188;; zero don't affect the flags. We assume that shifts by constant
11189;; zero are optimized away.
2c873473 11190(define_insn "*ashrsi3_cmp"
42fabf21 11191 [(set (reg FLAGS_REG)
16189740 11192 (compare
28cefcd2 11193 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
794a292d 11194 (match_operand:QI 2 "const_int_1_31_operand" "I"))
e075ae69 11195 (const_int 0)))
28cefcd2 11196 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 11197 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2c873473 11198 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11199 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11200 "sar{l}\t{%2, %0|%0, %2}"
6ef67412
JH
11201 [(set_attr "type" "ishift")
11202 (set_attr "mode" "SI")])
886c62d1 11203
371bc54b 11204(define_insn "*ashrsi3_cmp_zext"
42fabf21 11205 [(set (reg FLAGS_REG)
371bc54b
JH
11206 (compare
11207 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
794a292d 11208 (match_operand:QI 2 "const_int_1_31_operand" "I"))
371bc54b
JH
11209 (const_int 0)))
11210 (set (match_operand:DI 0 "register_operand" "=r")
11211 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11212 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11213 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11214 "sar{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
11215 [(set_attr "type" "ishift")
11216 (set_attr "mode" "SI")])
11217
d525dfdf
JH
11218(define_expand "ashrhi3"
11219 [(set (match_operand:HI 0 "nonimmediate_operand" "")
155d8a47 11220 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
d525dfdf 11221 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11222 (clobber (reg:CC FLAGS_REG))]
d9f32422 11223 "TARGET_HIMODE_MATH"
d525dfdf
JH
11224 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11225
8bad7136
JL
11226(define_insn "*ashrhi3_1_one_bit"
11227 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11228 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 11229 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11230 (clobber (reg:CC FLAGS_REG))]
8bad7136 11231 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
495333a6 11232 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11233 "sar{w}\t%0"
8bad7136
JL
11234 [(set_attr "type" "ishift")
11235 (set (attr "length")
3d117b30 11236 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11237 (const_string "2")
11238 (const_string "*")))])
11239
d525dfdf 11240(define_insn "*ashrhi3_1"
e075ae69
RH
11241 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11242 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11243 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11244 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11245 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
e075ae69 11246 "@
0f40f9f7
ZW
11247 sar{w}\t{%2, %0|%0, %2}
11248 sar{w}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11249 [(set_attr "type" "ishift")
11250 (set_attr "mode" "HI")])
886c62d1 11251
8bad7136
JL
11252;; This pattern can't accept a variable shift count, since shifts by
11253;; zero don't affect the flags. We assume that shifts by constant
11254;; zero are optimized away.
2c873473 11255(define_insn "*ashrhi3_one_bit_cmp"
42fabf21 11256 [(set (reg FLAGS_REG)
8bad7136
JL
11257 (compare
11258 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 11259 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
11260 (const_int 0)))
11261 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11262 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
2c873473 11263 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11264 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11265 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
0f40f9f7 11266 "sar{w}\t%0"
8bad7136
JL
11267 [(set_attr "type" "ishift")
11268 (set (attr "length")
3d117b30 11269 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11270 (const_string "2")
11271 (const_string "*")))])
11272
28cefcd2
BS
11273;; This pattern can't accept a variable shift count, since shifts by
11274;; zero don't affect the flags. We assume that shifts by constant
11275;; zero are optimized away.
2c873473 11276(define_insn "*ashrhi3_cmp"
42fabf21 11277 [(set (reg FLAGS_REG)
16189740 11278 (compare
28cefcd2 11279 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
794a292d 11280 (match_operand:QI 2 "const_int_1_31_operand" "I"))
e075ae69 11281 (const_int 0)))
28cefcd2 11282 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 11283 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
2c873473 11284 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11285 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
0f40f9f7 11286 "sar{w}\t{%2, %0|%0, %2}"
6ef67412
JH
11287 [(set_attr "type" "ishift")
11288 (set_attr "mode" "HI")])
886c62d1 11289
d525dfdf
JH
11290(define_expand "ashrqi3"
11291 [(set (match_operand:QI 0 "nonimmediate_operand" "")
155d8a47 11292 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
d525dfdf 11293 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11294 (clobber (reg:CC FLAGS_REG))]
d9f32422 11295 "TARGET_QIMODE_MATH"
d525dfdf
JH
11296 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11297
8bad7136
JL
11298(define_insn "*ashrqi3_1_one_bit"
11299 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11300 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 11301 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11302 (clobber (reg:CC FLAGS_REG))]
8bad7136 11303 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
495333a6 11304 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11305 "sar{b}\t%0"
8bad7136
JL
11306 [(set_attr "type" "ishift")
11307 (set (attr "length")
3d117b30 11308 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11309 (const_string "2")
11310 (const_string "*")))])
11311
2f41793e
JH
11312(define_insn "*ashrqi3_1_one_bit_slp"
11313 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 11314 (ashiftrt:QI (match_dup 0)
630eef90 11315 (match_operand:QI 1 "const1_operand" "")))
8bc527af 11316 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
11317 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11318 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
495333a6 11319 && (TARGET_SHIFT1 || optimize_size)"
2f41793e 11320 "sar{b}\t%0"
1b245ade 11321 [(set_attr "type" "ishift1")
2f41793e
JH
11322 (set (attr "length")
11323 (if_then_else (match_operand 0 "register_operand" "")
11324 (const_string "2")
11325 (const_string "*")))])
11326
d525dfdf 11327(define_insn "*ashrqi3_1"
e075ae69
RH
11328 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11329 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11330 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11331 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11332 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
e075ae69 11333 "@
0f40f9f7
ZW
11334 sar{b}\t{%2, %0|%0, %2}
11335 sar{b}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11336 [(set_attr "type" "ishift")
11337 (set_attr "mode" "QI")])
886c62d1 11338
2f41793e
JH
11339(define_insn "*ashrqi3_1_slp"
11340 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
11341 (ashiftrt:QI (match_dup 0)
11342 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 11343 (clobber (reg:CC FLAGS_REG))]
2f41793e 11344 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade 11345 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f41793e 11346 "@
1b245ade
JH
11347 sar{b}\t{%1, %0|%0, %1}
11348 sar{b}\t{%b1, %0|%0, %b1}"
11349 [(set_attr "type" "ishift1")
2f41793e
JH
11350 (set_attr "mode" "QI")])
11351
8bad7136
JL
11352;; This pattern can't accept a variable shift count, since shifts by
11353;; zero don't affect the flags. We assume that shifts by constant
11354;; zero are optimized away.
2c873473 11355(define_insn "*ashrqi3_one_bit_cmp"
42fabf21 11356 [(set (reg FLAGS_REG)
8bad7136
JL
11357 (compare
11358 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 11359 (match_operand:QI 2 "const1_operand" "I"))
8bad7136 11360 (const_int 0)))
5f90a099 11361 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8bad7136 11362 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
2c873473 11363 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11364 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11365 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
0f40f9f7 11366 "sar{b}\t%0"
8bad7136
JL
11367 [(set_attr "type" "ishift")
11368 (set (attr "length")
3d117b30 11369 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11370 (const_string "2")
11371 (const_string "*")))])
11372
28cefcd2
BS
11373;; This pattern can't accept a variable shift count, since shifts by
11374;; zero don't affect the flags. We assume that shifts by constant
11375;; zero are optimized away.
2c873473 11376(define_insn "*ashrqi3_cmp"
42fabf21 11377 [(set (reg FLAGS_REG)
16189740 11378 (compare
28cefcd2 11379 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
794a292d 11380 (match_operand:QI 2 "const_int_1_31_operand" "I"))
e075ae69 11381 (const_int 0)))
5f90a099 11382 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 11383 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
2c873473 11384 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11385 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
0f40f9f7 11386 "sar{b}\t{%2, %0|%0, %2}"
6ef67412
JH
11387 [(set_attr "type" "ishift")
11388 (set_attr "mode" "QI")])
886c62d1 11389\f
e075ae69
RH
11390;; Logical shift instructions
11391
11392;; See comment above `ashldi3' about how this works.
11393
11394(define_expand "lshrdi3"
93330ea1
RH
11395 [(set (match_operand:DI 0 "shiftdi_operand" "")
11396 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11397 (match_operand:QI 2 "nonmemory_operand" "")))]
886c62d1 11398 ""
93330ea1 11399 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
886c62d1 11400
371bc54b
JH
11401(define_insn "*lshrdi3_1_one_bit_rex64"
11402 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11403 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 11404 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11405 (clobber (reg:CC FLAGS_REG))]
371bc54b 11406 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
495333a6 11407 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11408 "shr{q}\t%0"
371bc54b
JH
11409 [(set_attr "type" "ishift")
11410 (set (attr "length")
11411 (if_then_else (match_operand:DI 0 "register_operand" "")
11412 (const_string "2")
11413 (const_string "*")))])
11414
11415(define_insn "*lshrdi3_1_rex64"
11416 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11417 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11418 (match_operand:QI 2 "nonmemory_operand" "J,c")))
8bc527af 11419 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11420 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11421 "@
0f40f9f7
ZW
11422 shr{q}\t{%2, %0|%0, %2}
11423 shr{q}\t{%b2, %0|%0, %b2}"
371bc54b
JH
11424 [(set_attr "type" "ishift")
11425 (set_attr "mode" "DI")])
11426
11427;; This pattern can't accept a variable shift count, since shifts by
11428;; zero don't affect the flags. We assume that shifts by constant
11429;; zero are optimized away.
11430(define_insn "*lshrdi3_cmp_one_bit_rex64"
42fabf21 11431 [(set (reg FLAGS_REG)
371bc54b
JH
11432 (compare
11433 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 11434 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
11435 (const_int 0)))
11436 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11438 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
495333a6 11439 && (TARGET_SHIFT1 || optimize_size)
371bc54b 11440 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11441 "shr{q}\t%0"
371bc54b
JH
11442 [(set_attr "type" "ishift")
11443 (set (attr "length")
11444 (if_then_else (match_operand:DI 0 "register_operand" "")
11445 (const_string "2")
11446 (const_string "*")))])
11447
11448;; This pattern can't accept a variable shift count, since shifts by
11449;; zero don't affect the flags. We assume that shifts by constant
11450;; zero are optimized away.
11451(define_insn "*lshrdi3_cmp_rex64"
42fabf21 11452 [(set (reg FLAGS_REG)
371bc54b
JH
11453 (compare
11454 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11455 (match_operand:QI 2 "const_int_operand" "e"))
11456 (const_int 0)))
11457 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11458 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11459 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11460 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11461 "shr{q}\t{%2, %0|%0, %2}"
371bc54b
JH
11462 [(set_attr "type" "ishift")
11463 (set_attr "mode" "DI")])
11464
93330ea1 11465(define_insn "*lshrdi3_1"
e075ae69
RH
11466 [(set (match_operand:DI 0 "register_operand" "=r")
11467 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11468 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8bc527af 11469 (clobber (reg:CC FLAGS_REG))]
1e07edd3 11470 "!TARGET_64BIT"
e075ae69
RH
11471 "#"
11472 [(set_attr "type" "multi")])
886c62d1 11473
93330ea1
RH
11474;; By default we don't ask for a scratch register, because when DImode
11475;; values are manipulated, registers are already at a premium. But if
11476;; we have one handy, we won't turn it away.
11477(define_peephole2
11478 [(match_scratch:SI 3 "r")
11479 (parallel [(set (match_operand:DI 0 "register_operand" "")
11480 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11481 (match_operand:QI 2 "nonmemory_operand" "")))
11482 (clobber (reg:CC FLAGS_REG))])
11483 (match_dup 3)]
11484 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69
RH
11485 [(const_int 0)]
11486 "ix86_split_lshrdi (operands, operands[3]); DONE;")
886c62d1 11487
e075ae69
RH
11488(define_split
11489 [(set (match_operand:DI 0 "register_operand" "")
11490 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11491 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11492 (clobber (reg:CC FLAGS_REG))]
93330ea1 11493 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
e075ae69
RH
11494 [(const_int 0)]
11495 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
886c62d1 11496
d525dfdf
JH
11497(define_expand "lshrsi3"
11498 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11499 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11500 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11501 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
11502 ""
11503 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11504
8bad7136
JL
11505(define_insn "*lshrsi3_1_one_bit"
11506 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11507 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 11508 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11509 (clobber (reg:CC FLAGS_REG))]
8bad7136 11510 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
495333a6 11511 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11512 "shr{l}\t%0"
8bad7136
JL
11513 [(set_attr "type" "ishift")
11514 (set (attr "length")
11515 (if_then_else (match_operand:SI 0 "register_operand" "")
11516 (const_string "2")
11517 (const_string "*")))])
11518
371bc54b
JH
11519(define_insn "*lshrsi3_1_one_bit_zext"
11520 [(set (match_operand:DI 0 "register_operand" "=r")
11521 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
630eef90 11522 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11523 (clobber (reg:CC FLAGS_REG))]
371bc54b 11524 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
495333a6 11525 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11526 "shr{l}\t%k0"
371bc54b
JH
11527 [(set_attr "type" "ishift")
11528 (set_attr "length" "2")])
11529
d525dfdf 11530(define_insn "*lshrsi3_1"
e075ae69
RH
11531 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11532 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11533 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11534 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11535 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
e075ae69 11536 "@
0f40f9f7
ZW
11537 shr{l}\t{%2, %0|%0, %2}
11538 shr{l}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11539 [(set_attr "type" "ishift")
11540 (set_attr "mode" "SI")])
886c62d1 11541
371bc54b
JH
11542(define_insn "*lshrsi3_1_zext"
11543 [(set (match_operand:DI 0 "register_operand" "=r,r")
11544 (zero_extend:DI
11545 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11546 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 11547 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11548 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11549 "@
0f40f9f7
ZW
11550 shr{l}\t{%2, %k0|%k0, %2}
11551 shr{l}\t{%b2, %k0|%k0, %b2}"
371bc54b
JH
11552 [(set_attr "type" "ishift")
11553 (set_attr "mode" "SI")])
11554
8bad7136
JL
11555;; This pattern can't accept a variable shift count, since shifts by
11556;; zero don't affect the flags. We assume that shifts by constant
11557;; zero are optimized away.
2c873473 11558(define_insn "*lshrsi3_one_bit_cmp"
42fabf21 11559 [(set (reg FLAGS_REG)
8bad7136
JL
11560 (compare
11561 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 11562 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
11563 (const_int 0)))
11564 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11565 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
9076b9c1 11566 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11567 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11568 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11569 "shr{l}\t%0"
8bad7136
JL
11570 [(set_attr "type" "ishift")
11571 (set (attr "length")
11572 (if_then_else (match_operand:SI 0 "register_operand" "")
11573 (const_string "2")
11574 (const_string "*")))])
11575
371bc54b 11576(define_insn "*lshrsi3_cmp_one_bit_zext"
42fabf21 11577 [(set (reg FLAGS_REG)
371bc54b
JH
11578 (compare
11579 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
630eef90 11580 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
11581 (const_int 0)))
11582 (set (match_operand:DI 0 "register_operand" "=r")
11583 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11584 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
495333a6 11585 && (TARGET_SHIFT1 || optimize_size)
371bc54b 11586 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11587 "shr{l}\t%k0"
371bc54b
JH
11588 [(set_attr "type" "ishift")
11589 (set_attr "length" "2")])
11590
28cefcd2
BS
11591;; This pattern can't accept a variable shift count, since shifts by
11592;; zero don't affect the flags. We assume that shifts by constant
11593;; zero are optimized away.
2c873473 11594(define_insn "*lshrsi3_cmp"
42fabf21 11595 [(set (reg FLAGS_REG)
16189740 11596 (compare
28cefcd2 11597 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
794a292d 11598 (match_operand:QI 2 "const_int_1_31_operand" "I"))
e075ae69 11599 (const_int 0)))
28cefcd2 11600 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 11601 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
9076b9c1 11602 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11603 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11604 "shr{l}\t{%2, %0|%0, %2}"
6ef67412
JH
11605 [(set_attr "type" "ishift")
11606 (set_attr "mode" "SI")])
886c62d1 11607
371bc54b 11608(define_insn "*lshrsi3_cmp_zext"
42fabf21 11609 [(set (reg FLAGS_REG)
371bc54b
JH
11610 (compare
11611 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
794a292d 11612 (match_operand:QI 2 "const_int_1_31_operand" "I"))
371bc54b
JH
11613 (const_int 0)))
11614 (set (match_operand:DI 0 "register_operand" "=r")
11615 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11616 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11617 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11618 "shr{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
11619 [(set_attr "type" "ishift")
11620 (set_attr "mode" "SI")])
11621
d525dfdf
JH
11622(define_expand "lshrhi3"
11623 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11624 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11625 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11626 (clobber (reg:CC FLAGS_REG))]
d9f32422 11627 "TARGET_HIMODE_MATH"
d525dfdf
JH
11628 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11629
8bad7136
JL
11630(define_insn "*lshrhi3_1_one_bit"
11631 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11632 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 11633 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11634 (clobber (reg:CC FLAGS_REG))]
8bad7136 11635 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
495333a6 11636 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11637 "shr{w}\t%0"
8bad7136
JL
11638 [(set_attr "type" "ishift")
11639 (set (attr "length")
3d117b30 11640 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11641 (const_string "2")
11642 (const_string "*")))])
11643
d525dfdf 11644(define_insn "*lshrhi3_1"
e075ae69
RH
11645 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11646 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11647 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11648 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11649 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
e075ae69 11650 "@
0f40f9f7
ZW
11651 shr{w}\t{%2, %0|%0, %2}
11652 shr{w}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11653 [(set_attr "type" "ishift")
11654 (set_attr "mode" "HI")])
886c62d1 11655
8bad7136
JL
11656;; This pattern can't accept a variable shift count, since shifts by
11657;; zero don't affect the flags. We assume that shifts by constant
11658;; zero are optimized away.
2c873473 11659(define_insn "*lshrhi3_one_bit_cmp"
42fabf21 11660 [(set (reg FLAGS_REG)
8bad7136
JL
11661 (compare
11662 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 11663 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
11664 (const_int 0)))
11665 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11666 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
9076b9c1 11667 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11668 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11669 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11670 "shr{w}\t%0"
8bad7136
JL
11671 [(set_attr "type" "ishift")
11672 (set (attr "length")
11673 (if_then_else (match_operand:SI 0 "register_operand" "")
11674 (const_string "2")
11675 (const_string "*")))])
11676
28cefcd2
BS
11677;; This pattern can't accept a variable shift count, since shifts by
11678;; zero don't affect the flags. We assume that shifts by constant
11679;; zero are optimized away.
2c873473 11680(define_insn "*lshrhi3_cmp"
42fabf21 11681 [(set (reg FLAGS_REG)
16189740 11682 (compare
28cefcd2 11683 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
794a292d 11684 (match_operand:QI 2 "const_int_1_31_operand" "I"))
e075ae69 11685 (const_int 0)))
28cefcd2 11686 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 11687 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
9076b9c1 11688 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11689 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11690 "shr{w}\t{%2, %0|%0, %2}"
6ef67412
JH
11691 [(set_attr "type" "ishift")
11692 (set_attr "mode" "HI")])
886c62d1 11693
d525dfdf
JH
11694(define_expand "lshrqi3"
11695 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11696 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11697 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11698 (clobber (reg:CC FLAGS_REG))]
d9f32422 11699 "TARGET_QIMODE_MATH"
d525dfdf
JH
11700 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11701
8bad7136
JL
11702(define_insn "*lshrqi3_1_one_bit"
11703 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11704 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 11705 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11706 (clobber (reg:CC FLAGS_REG))]
8bad7136 11707 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
495333a6 11708 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11709 "shr{b}\t%0"
8bad7136
JL
11710 [(set_attr "type" "ishift")
11711 (set (attr "length")
3d117b30 11712 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11713 (const_string "2")
11714 (const_string "*")))])
11715
2f41793e
JH
11716(define_insn "*lshrqi3_1_one_bit_slp"
11717 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 11718 (lshiftrt:QI (match_dup 0)
630eef90 11719 (match_operand:QI 1 "const1_operand" "")))
8bc527af 11720 (clobber (reg:CC FLAGS_REG))]
2f41793e 11721 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
495333a6 11722 && (TARGET_SHIFT1 || optimize_size)"
2f41793e 11723 "shr{b}\t%0"
1b245ade 11724 [(set_attr "type" "ishift1")
2f41793e
JH
11725 (set (attr "length")
11726 (if_then_else (match_operand 0 "register_operand" "")
11727 (const_string "2")
11728 (const_string "*")))])
11729
d525dfdf 11730(define_insn "*lshrqi3_1"
e075ae69
RH
11731 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11732 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11733 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11734 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11735 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
e075ae69 11736 "@
0f40f9f7
ZW
11737 shr{b}\t{%2, %0|%0, %2}
11738 shr{b}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11739 [(set_attr "type" "ishift")
11740 (set_attr "mode" "QI")])
886c62d1 11741
2f41793e
JH
11742(define_insn "*lshrqi3_1_slp"
11743 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
11744 (lshiftrt:QI (match_dup 0)
11745 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 11746 (clobber (reg:CC FLAGS_REG))]
2f41793e 11747 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade 11748 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f41793e 11749 "@
1b245ade
JH
11750 shr{b}\t{%1, %0|%0, %1}
11751 shr{b}\t{%b1, %0|%0, %b1}"
11752 [(set_attr "type" "ishift1")
2f41793e
JH
11753 (set_attr "mode" "QI")])
11754
8bad7136
JL
11755;; This pattern can't accept a variable shift count, since shifts by
11756;; zero don't affect the flags. We assume that shifts by constant
11757;; zero are optimized away.
2c873473 11758(define_insn "*lshrqi2_one_bit_cmp"
42fabf21 11759 [(set (reg FLAGS_REG)
8bad7136
JL
11760 (compare
11761 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 11762 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
11763 (const_int 0)))
11764 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11765 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
9076b9c1 11766 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11767 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11768 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
0f40f9f7 11769 "shr{b}\t%0"
8bad7136
JL
11770 [(set_attr "type" "ishift")
11771 (set (attr "length")
11772 (if_then_else (match_operand:SI 0 "register_operand" "")
11773 (const_string "2")
11774 (const_string "*")))])
11775
28cefcd2
BS
11776;; This pattern can't accept a variable shift count, since shifts by
11777;; zero don't affect the flags. We assume that shifts by constant
11778;; zero are optimized away.
2c873473 11779(define_insn "*lshrqi2_cmp"
42fabf21 11780 [(set (reg FLAGS_REG)
16189740 11781 (compare
28cefcd2 11782 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
794a292d 11783 (match_operand:QI 2 "const_int_1_31_operand" "I"))
e075ae69 11784 (const_int 0)))
122ddbf9 11785 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 11786 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
9076b9c1 11787 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11788 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
0f40f9f7 11789 "shr{b}\t{%2, %0|%0, %2}"
6ef67412
JH
11790 [(set_attr "type" "ishift")
11791 (set_attr "mode" "QI")])
886c62d1 11792\f
e075ae69 11793;; Rotate instructions
886c62d1 11794
371bc54b
JH
11795(define_expand "rotldi3"
11796 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11797 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11798 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11799 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11800 "TARGET_64BIT"
11801 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11802
11803(define_insn "*rotlsi3_1_one_bit_rex64"
11804 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11805 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 11806 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11807 (clobber (reg:CC FLAGS_REG))]
371bc54b 11808 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
495333a6 11809 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11810 "rol{q}\t%0"
890d52e8 11811 [(set_attr "type" "rotate")
371bc54b
JH
11812 (set (attr "length")
11813 (if_then_else (match_operand:DI 0 "register_operand" "")
11814 (const_string "2")
11815 (const_string "*")))])
11816
11817(define_insn "*rotldi3_1_rex64"
11818 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11819 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11820 (match_operand:QI 2 "nonmemory_operand" "e,c")))
8bc527af 11821 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11822 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11823 "@
0f40f9f7
ZW
11824 rol{q}\t{%2, %0|%0, %2}
11825 rol{q}\t{%b2, %0|%0, %b2}"
890d52e8 11826 [(set_attr "type" "rotate")
371bc54b
JH
11827 (set_attr "mode" "DI")])
11828
d525dfdf
JH
11829(define_expand "rotlsi3"
11830 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11831 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11832 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11833 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
11834 ""
11835 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11836
8bad7136
JL
11837(define_insn "*rotlsi3_1_one_bit"
11838 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11839 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 11840 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11841 (clobber (reg:CC FLAGS_REG))]
8bad7136 11842 "ix86_binary_operator_ok (ROTATE, SImode, operands)
495333a6 11843 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11844 "rol{l}\t%0"
890d52e8 11845 [(set_attr "type" "rotate")
8bad7136
JL
11846 (set (attr "length")
11847 (if_then_else (match_operand:SI 0 "register_operand" "")
11848 (const_string "2")
11849 (const_string "*")))])
11850
371bc54b
JH
11851(define_insn "*rotlsi3_1_one_bit_zext"
11852 [(set (match_operand:DI 0 "register_operand" "=r")
11853 (zero_extend:DI
11854 (rotate:SI (match_operand:SI 1 "register_operand" "0")
630eef90 11855 (match_operand:QI 2 "const1_operand" ""))))
8bc527af 11856 (clobber (reg:CC FLAGS_REG))]
371bc54b 11857 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
495333a6 11858 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11859 "rol{l}\t%k0"
890d52e8 11860 [(set_attr "type" "rotate")
371bc54b
JH
11861 (set_attr "length" "2")])
11862
d525dfdf 11863(define_insn "*rotlsi3_1"
e075ae69
RH
11864 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11865 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11866 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11867 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11868 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
e075ae69 11869 "@
0f40f9f7
ZW
11870 rol{l}\t{%2, %0|%0, %2}
11871 rol{l}\t{%b2, %0|%0, %b2}"
890d52e8 11872 [(set_attr "type" "rotate")
6ef67412 11873 (set_attr "mode" "SI")])
b4ac57ab 11874
371bc54b
JH
11875(define_insn "*rotlsi3_1_zext"
11876 [(set (match_operand:DI 0 "register_operand" "=r,r")
11877 (zero_extend:DI
11878 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11879 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 11880 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11881 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11882 "@
0f40f9f7
ZW
11883 rol{l}\t{%2, %k0|%k0, %2}
11884 rol{l}\t{%b2, %k0|%k0, %b2}"
890d52e8 11885 [(set_attr "type" "rotate")
371bc54b
JH
11886 (set_attr "mode" "SI")])
11887
d525dfdf
JH
11888(define_expand "rotlhi3"
11889 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11890 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11891 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11892 (clobber (reg:CC FLAGS_REG))]
d9f32422 11893 "TARGET_HIMODE_MATH"
d525dfdf
JH
11894 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11895
8bad7136
JL
11896(define_insn "*rotlhi3_1_one_bit"
11897 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11898 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 11899 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11900 (clobber (reg:CC FLAGS_REG))]
8bad7136 11901 "ix86_binary_operator_ok (ROTATE, HImode, operands)
495333a6 11902 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11903 "rol{w}\t%0"
890d52e8 11904 [(set_attr "type" "rotate")
8bad7136 11905 (set (attr "length")
3d117b30 11906 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11907 (const_string "2")
11908 (const_string "*")))])
11909
d525dfdf 11910(define_insn "*rotlhi3_1"
e075ae69
RH
11911 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11912 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11913 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11914 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11915 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
e075ae69 11916 "@
0f40f9f7
ZW
11917 rol{w}\t{%2, %0|%0, %2}
11918 rol{w}\t{%b2, %0|%0, %b2}"
890d52e8 11919 [(set_attr "type" "rotate")
6ef67412 11920 (set_attr "mode" "HI")])
47af5d50 11921
d525dfdf
JH
11922(define_expand "rotlqi3"
11923 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11924 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11925 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11926 (clobber (reg:CC FLAGS_REG))]
d9f32422 11927 "TARGET_QIMODE_MATH"
d525dfdf
JH
11928 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11929
2f41793e
JH
11930(define_insn "*rotlqi3_1_one_bit_slp"
11931 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 11932 (rotate:QI (match_dup 0)
630eef90 11933 (match_operand:QI 1 "const1_operand" "")))
8bc527af 11934 (clobber (reg:CC FLAGS_REG))]
2f41793e 11935 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
495333a6 11936 && (TARGET_SHIFT1 || optimize_size)"
2f41793e 11937 "rol{b}\t%0"
1b245ade 11938 [(set_attr "type" "rotate1")
2f41793e
JH
11939 (set (attr "length")
11940 (if_then_else (match_operand 0 "register_operand" "")
11941 (const_string "2")
11942 (const_string "*")))])
11943
8bad7136
JL
11944(define_insn "*rotlqi3_1_one_bit"
11945 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 11947 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11948 (clobber (reg:CC FLAGS_REG))]
8bad7136 11949 "ix86_binary_operator_ok (ROTATE, QImode, operands)
495333a6 11950 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11951 "rol{b}\t%0"
890d52e8 11952 [(set_attr "type" "rotate")
8bad7136 11953 (set (attr "length")
3d117b30 11954 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11955 (const_string "2")
11956 (const_string "*")))])
11957
2f41793e
JH
11958(define_insn "*rotlqi3_1_slp"
11959 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
11960 (rotate:QI (match_dup 0)
11961 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 11962 (clobber (reg:CC FLAGS_REG))]
2f41793e 11963 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade 11964 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f41793e 11965 "@
1b245ade
JH
11966 rol{b}\t{%1, %0|%0, %1}
11967 rol{b}\t{%b1, %0|%0, %b1}"
11968 [(set_attr "type" "rotate1")
2f41793e
JH
11969 (set_attr "mode" "QI")])
11970
d525dfdf 11971(define_insn "*rotlqi3_1"
e075ae69
RH
11972 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11973 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11974 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11975 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11976 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
e075ae69 11977 "@
0f40f9f7
ZW
11978 rol{b}\t{%2, %0|%0, %2}
11979 rol{b}\t{%b2, %0|%0, %b2}"
890d52e8 11980 [(set_attr "type" "rotate")
6ef67412 11981 (set_attr "mode" "QI")])
47af5d50 11982
371bc54b
JH
11983(define_expand "rotrdi3"
11984 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11985 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11986 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11987 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11988 "TARGET_64BIT"
11989 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11990
11991(define_insn "*rotrdi3_1_one_bit_rex64"
11992 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11993 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 11994 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11995 (clobber (reg:CC FLAGS_REG))]
371bc54b 11996 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
495333a6 11997 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11998 "ror{q}\t%0"
890d52e8 11999 [(set_attr "type" "rotate")
371bc54b
JH
12000 (set (attr "length")
12001 (if_then_else (match_operand:DI 0 "register_operand" "")
12002 (const_string "2")
12003 (const_string "*")))])
12004
12005(define_insn "*rotrdi3_1_rex64"
12006 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12007 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12008 (match_operand:QI 2 "nonmemory_operand" "J,c")))
8bc527af 12009 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
12010 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12011 "@
0f40f9f7
ZW
12012 ror{q}\t{%2, %0|%0, %2}
12013 ror{q}\t{%b2, %0|%0, %b2}"
890d52e8 12014 [(set_attr "type" "rotate")
371bc54b
JH
12015 (set_attr "mode" "DI")])
12016
d525dfdf
JH
12017(define_expand "rotrsi3"
12018 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12019 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12020 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 12021 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
12022 ""
12023 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12024
8bad7136
JL
12025(define_insn "*rotrsi3_1_one_bit"
12026 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12027 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 12028 (match_operand:QI 2 "const1_operand" "")))
8bc527af 12029 (clobber (reg:CC FLAGS_REG))]
8bad7136 12030 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
495333a6 12031 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 12032 "ror{l}\t%0"
890d52e8 12033 [(set_attr "type" "rotate")
8bad7136
JL
12034 (set (attr "length")
12035 (if_then_else (match_operand:SI 0 "register_operand" "")
12036 (const_string "2")
12037 (const_string "*")))])
12038
371bc54b
JH
12039(define_insn "*rotrsi3_1_one_bit_zext"
12040 [(set (match_operand:DI 0 "register_operand" "=r")
12041 (zero_extend:DI
12042 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
630eef90 12043 (match_operand:QI 2 "const1_operand" ""))))
8bc527af 12044 (clobber (reg:CC FLAGS_REG))]
371bc54b 12045 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
495333a6 12046 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 12047 "ror{l}\t%k0"
890d52e8 12048 [(set_attr "type" "rotate")
371bc54b
JH
12049 (set (attr "length")
12050 (if_then_else (match_operand:SI 0 "register_operand" "")
12051 (const_string "2")
12052 (const_string "*")))])
12053
d525dfdf 12054(define_insn "*rotrsi3_1"
e075ae69
RH
12055 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12056 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12057 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 12058 (clobber (reg:CC FLAGS_REG))]
d525dfdf 12059 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
e075ae69 12060 "@
0f40f9f7
ZW
12061 ror{l}\t{%2, %0|%0, %2}
12062 ror{l}\t{%b2, %0|%0, %b2}"
890d52e8 12063 [(set_attr "type" "rotate")
6ef67412 12064 (set_attr "mode" "SI")])
47af5d50 12065
371bc54b
JH
12066(define_insn "*rotrsi3_1_zext"
12067 [(set (match_operand:DI 0 "register_operand" "=r,r")
12068 (zero_extend:DI
12069 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12070 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 12071 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
12072 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12073 "@
0f40f9f7
ZW
12074 ror{l}\t{%2, %k0|%k0, %2}
12075 ror{l}\t{%b2, %k0|%k0, %b2}"
890d52e8 12076 [(set_attr "type" "rotate")
371bc54b
JH
12077 (set_attr "mode" "SI")])
12078
d525dfdf
JH
12079(define_expand "rotrhi3"
12080 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12081 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12082 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 12083 (clobber (reg:CC FLAGS_REG))]
d9f32422 12084 "TARGET_HIMODE_MATH"
d525dfdf
JH
12085 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12086
8bad7136
JL
12087(define_insn "*rotrhi3_one_bit"
12088 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12089 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 12090 (match_operand:QI 2 "const1_operand" "")))
8bc527af 12091 (clobber (reg:CC FLAGS_REG))]
8bad7136 12092 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
495333a6 12093 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 12094 "ror{w}\t%0"
890d52e8 12095 [(set_attr "type" "rotate")
8bad7136 12096 (set (attr "length")
3d117b30 12097 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
12098 (const_string "2")
12099 (const_string "*")))])
12100
d525dfdf 12101(define_insn "*rotrhi3"
e075ae69
RH
12102 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12103 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12104 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 12105 (clobber (reg:CC FLAGS_REG))]
d525dfdf 12106 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
e075ae69 12107 "@
0f40f9f7
ZW
12108 ror{w}\t{%2, %0|%0, %2}
12109 ror{w}\t{%b2, %0|%0, %b2}"
890d52e8 12110 [(set_attr "type" "rotate")
6ef67412 12111 (set_attr "mode" "HI")])
a199fdd6 12112
d525dfdf
JH
12113(define_expand "rotrqi3"
12114 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12115 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12116 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 12117 (clobber (reg:CC FLAGS_REG))]
d9f32422 12118 "TARGET_QIMODE_MATH"
d525dfdf
JH
12119 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12120
8bad7136
JL
12121(define_insn "*rotrqi3_1_one_bit"
12122 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12123 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 12124 (match_operand:QI 2 "const1_operand" "")))
8bc527af 12125 (clobber (reg:CC FLAGS_REG))]
8bad7136 12126 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
495333a6 12127 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 12128 "ror{b}\t%0"
890d52e8 12129 [(set_attr "type" "rotate")
8bad7136 12130 (set (attr "length")
3d117b30 12131 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
12132 (const_string "2")
12133 (const_string "*")))])
12134
2f41793e
JH
12135(define_insn "*rotrqi3_1_one_bit_slp"
12136 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 12137 (rotatert:QI (match_dup 0)
630eef90 12138 (match_operand:QI 1 "const1_operand" "")))
8bc527af 12139 (clobber (reg:CC FLAGS_REG))]
2f41793e 12140 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
495333a6 12141 && (TARGET_SHIFT1 || optimize_size)"
2f41793e 12142 "ror{b}\t%0"
1b245ade 12143 [(set_attr "type" "rotate1")
2f41793e
JH
12144 (set (attr "length")
12145 (if_then_else (match_operand 0 "register_operand" "")
12146 (const_string "2")
12147 (const_string "*")))])
12148
d525dfdf 12149(define_insn "*rotrqi3_1"
e075ae69
RH
12150 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12151 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12152 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 12153 (clobber (reg:CC FLAGS_REG))]
d525dfdf 12154 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
e075ae69 12155 "@
0f40f9f7
ZW
12156 ror{b}\t{%2, %0|%0, %2}
12157 ror{b}\t{%b2, %0|%0, %b2}"
890d52e8 12158 [(set_attr "type" "rotate")
6ef67412 12159 (set_attr "mode" "QI")])
2f41793e
JH
12160
12161(define_insn "*rotrqi3_1_slp"
12162 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
12163 (rotatert:QI (match_dup 0)
12164 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 12165 (clobber (reg:CC FLAGS_REG))]
2f41793e 12166 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade 12167 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f41793e 12168 "@
1b245ade
JH
12169 ror{b}\t{%1, %0|%0, %1}
12170 ror{b}\t{%b1, %0|%0, %b1}"
12171 [(set_attr "type" "rotate1")
2f41793e 12172 (set_attr "mode" "QI")])
e075ae69
RH
12173\f
12174;; Bit set / bit test instructions
a199fdd6 12175
e075ae69
RH
12176(define_expand "extv"
12177 [(set (match_operand:SI 0 "register_operand" "")
12178 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12179 (match_operand:SI 2 "immediate_operand" "")
12180 (match_operand:SI 3 "immediate_operand" "")))]
12181 ""
e075ae69
RH
12182{
12183 /* Handle extractions from %ah et al. */
12184 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12185 FAIL;
a199fdd6 12186
e075ae69
RH
12187 /* From mips.md: extract_bit_field doesn't verify that our source
12188 matches the predicate, so check it again here. */
12189 if (! register_operand (operands[1], VOIDmode))
12190 FAIL;
0f40f9f7 12191})
a199fdd6 12192
e075ae69
RH
12193(define_expand "extzv"
12194 [(set (match_operand:SI 0 "register_operand" "")
12195 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12196 (match_operand:SI 2 "immediate_operand" "")
12197 (match_operand:SI 3 "immediate_operand" "")))]
12198 ""
e075ae69
RH
12199{
12200 /* Handle extractions from %ah et al. */
12201 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12202 FAIL;
a199fdd6 12203
e075ae69
RH
12204 /* From mips.md: extract_bit_field doesn't verify that our source
12205 matches the predicate, so check it again here. */
12206 if (! register_operand (operands[1], VOIDmode))
12207 FAIL;
0f40f9f7 12208})
a199fdd6 12209
e075ae69 12210(define_expand "insv"
044b3892
L
12211 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12212 (match_operand 1 "immediate_operand" "")
12213 (match_operand 2 "immediate_operand" ""))
12214 (match_operand 3 "register_operand" ""))]
e075ae69 12215 ""
e075ae69
RH
12216{
12217 /* Handle extractions from %ah et al. */
12218 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12219 FAIL;
a199fdd6 12220
e075ae69
RH
12221 /* From mips.md: insert_bit_field doesn't verify that our source
12222 matches the predicate, so check it again here. */
12223 if (! register_operand (operands[0], VOIDmode))
12224 FAIL;
044b3892
L
12225
12226 if (TARGET_64BIT)
12227 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12228 else
12229 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12230
12231 DONE;
0f40f9f7 12232})
e075ae69
RH
12233
12234;; %%% bts, btr, btc, bt.
7cacf53e
RH
12235;; In general these instructions are *slow* when applied to memory,
12236;; since they enforce atomic operation. When applied to registers,
12237;; it depends on the cpu implementation. They're never faster than
12238;; the corresponding and/ior/xor operations, so with 32-bit there's
12239;; no point. But in 64-bit, we can't hold the relevant immediates
12240;; within the instruction itself, so operating on bits in the high
12241;; 32-bits of a register becomes easier.
12242;;
12243;; These are slow on Nocona, but fast on Athlon64. We do require the use
12244;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12245;; negdf respectively, so they can never be disabled entirely.
12246
12247(define_insn "*btsq"
12248 [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12249 (const_int 1)
12250 (match_operand 1 "const_0_to_63_operand" ""))
12251 (const_int 1))
12252 (clobber (reg:CC FLAGS_REG))]
12253 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12254 "bts{q} %1,%0"
12255 [(set_attr "type" "alu1")])
12256
12257(define_insn "*btrq"
12258 [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12259 (const_int 1)
12260 (match_operand 1 "const_0_to_63_operand" ""))
12261 (const_int 0))
12262 (clobber (reg:CC FLAGS_REG))]
12263 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12264 "btr{q} %1,%0"
12265 [(set_attr "type" "alu1")])
12266
12267(define_insn "*btcq"
12268 [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12269 (const_int 1)
12270 (match_operand 1 "const_0_to_63_operand" ""))
12271 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12272 (clobber (reg:CC FLAGS_REG))]
12273 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12274 "btc{q} %1,%0"
12275 [(set_attr "type" "alu1")])
12276
12277;; Allow Nocona to avoid these instructions if a register is available.
12278
12279(define_peephole2
12280 [(match_scratch:DI 2 "r")
12281 (parallel [(set (zero_extract:DI
12282 (match_operand 0 "register_operand" "")
12283 (const_int 1)
12284 (match_operand 1 "const_0_to_63_operand" ""))
12285 (const_int 1))
12286 (clobber (reg:CC FLAGS_REG))])]
12287 "TARGET_64BIT && !TARGET_USE_BT"
12288 [(const_int 0)]
12289{
12290 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12291 rtx op1;
12292
12293 if (HOST_BITS_PER_WIDE_INT >= 64)
12294 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12295 else if (i < HOST_BITS_PER_WIDE_INT)
12296 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12297 else
12298 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12299
12300 op1 = immed_double_const (lo, hi, DImode);
12301 if (i >= 31)
12302 {
12303 emit_move_insn (operands[2], op1);
12304 op1 = operands[2];
12305 }
12306
12307 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12308 DONE;
12309})
12310
12311(define_peephole2
12312 [(match_scratch:DI 2 "r")
12313 (parallel [(set (zero_extract:DI
12314 (match_operand 0 "register_operand" "")
12315 (const_int 1)
12316 (match_operand 1 "const_0_to_63_operand" ""))
12317 (const_int 0))
12318 (clobber (reg:CC FLAGS_REG))])]
12319 "TARGET_64BIT && !TARGET_USE_BT"
12320 [(const_int 0)]
12321{
12322 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12323 rtx op1;
12324
12325 if (HOST_BITS_PER_WIDE_INT >= 64)
12326 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12327 else if (i < HOST_BITS_PER_WIDE_INT)
12328 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12329 else
12330 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12331
12332 op1 = immed_double_const (~lo, ~hi, DImode);
12333 if (i >= 32)
12334 {
12335 emit_move_insn (operands[2], op1);
12336 op1 = operands[2];
12337 }
12338
12339 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12340 DONE;
12341})
12342
12343(define_peephole2
12344 [(match_scratch:DI 2 "r")
12345 (parallel [(set (zero_extract:DI
12346 (match_operand 0 "register_operand" "")
12347 (const_int 1)
12348 (match_operand 1 "const_0_to_63_operand" ""))
12349 (not:DI (zero_extract:DI
12350 (match_dup 0) (const_int 1) (match_dup 1))))
12351 (clobber (reg:CC FLAGS_REG))])]
12352 "TARGET_64BIT && !TARGET_USE_BT"
12353 [(const_int 0)]
12354{
12355 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12356 rtx op1;
12357
12358 if (HOST_BITS_PER_WIDE_INT >= 64)
12359 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12360 else if (i < HOST_BITS_PER_WIDE_INT)
12361 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12362 else
12363 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12364
12365 op1 = immed_double_const (lo, hi, DImode);
12366 if (i >= 31)
12367 {
12368 emit_move_insn (operands[2], op1);
12369 op1 = operands[2];
12370 }
12371
12372 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12373 DONE;
12374})
886c62d1
JVA
12375\f
12376;; Store-flag instructions.
12377
c572e5ba
JVA
12378;; For all sCOND expanders, also expand the compare or test insn that
12379;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12380
e075ae69
RH
12381;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12382;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12383;; way, which can later delete the movzx if only QImode is needed.
12384
c572e5ba 12385(define_expand "seq"
b932f770 12386 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12387 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12388 ""
3a3677ff 12389 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
c572e5ba 12390
c572e5ba 12391(define_expand "sne"
b932f770 12392 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12393 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12394 ""
3a3677ff 12395 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
c572e5ba 12396
c572e5ba 12397(define_expand "sgt"
b932f770 12398 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12399 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12400 ""
3a3677ff 12401 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
c572e5ba 12402
c572e5ba 12403(define_expand "sgtu"
b932f770 12404 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12405 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12406 ""
3a3677ff 12407 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
c572e5ba 12408
c572e5ba 12409(define_expand "slt"
b932f770 12410 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12411 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12412 ""
3a3677ff 12413 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
c572e5ba 12414
c572e5ba 12415(define_expand "sltu"
b932f770 12416 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12417 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12418 ""
3a3677ff 12419 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
c572e5ba 12420
c572e5ba 12421(define_expand "sge"
b932f770 12422 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12423 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12424 ""
3a3677ff 12425 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
c572e5ba 12426
c572e5ba 12427(define_expand "sgeu"
b932f770 12428 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12429 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12430 ""
3a3677ff 12431 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
c572e5ba 12432
c572e5ba 12433(define_expand "sle"
b932f770 12434 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12435 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12436 ""
3a3677ff 12437 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
c572e5ba 12438
c785c660 12439(define_expand "sleu"
b932f770 12440 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12441 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
c785c660 12442 ""
3a3677ff
RH
12443 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12444
12445(define_expand "sunordered"
b932f770 12446 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12447 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12448 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12449 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12450
12451(define_expand "sordered"
b932f770 12452 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12453 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
3a3677ff
RH
12454 "TARGET_80387"
12455 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12456
12457(define_expand "suneq"
b932f770 12458 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12459 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12460 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12461 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12462
12463(define_expand "sunge"
b932f770 12464 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12465 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12466 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12467 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12468
12469(define_expand "sungt"
b932f770 12470 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12471 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12472 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12473 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12474
12475(define_expand "sunle"
b932f770 12476 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12477 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12478 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12479 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12480
12481(define_expand "sunlt"
b932f770 12482 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12483 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12484 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12485 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12486
12487(define_expand "sltgt"
b932f770 12488 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12489 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12490 "TARGET_80387 || TARGET_SSE"
3a3677ff 12491 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
c785c660 12492
e075ae69 12493(define_insn "*setcc_1"
a269a03c 12494 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9076b9c1 12495 (match_operator:QI 1 "ix86_comparison_operator"
42fabf21 12496 [(reg FLAGS_REG) (const_int 0)]))]
e075ae69 12497 ""
0f40f9f7 12498 "set%C1\t%0"
6ef67412
JH
12499 [(set_attr "type" "setcc")
12500 (set_attr "mode" "QI")])
a269a03c 12501
93330ea1 12502(define_insn "*setcc_2"
e075ae69 12503 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9076b9c1 12504 (match_operator:QI 1 "ix86_comparison_operator"
42fabf21 12505 [(reg FLAGS_REG) (const_int 0)]))]
e075ae69 12506 ""
0f40f9f7 12507 "set%C1\t%0"
6ef67412
JH
12508 [(set_attr "type" "setcc")
12509 (set_attr "mode" "QI")])
e075ae69 12510
10978207
RH
12511;; In general it is not safe to assume too much about CCmode registers,
12512;; so simplify-rtx stops when it sees a second one. Under certain
12513;; conditions this is safe on x86, so help combine not create
12514;;
12515;; seta %al
12516;; testb %al, %al
12517;; sete %al
12518
12519(define_split
12520 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12521 (ne:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 12522 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
12523 (const_int 0)))]
12524 ""
12525 [(set (match_dup 0) (match_dup 1))]
12526{
12527 PUT_MODE (operands[1], QImode);
12528})
12529
12530(define_split
12531 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12532 (ne:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 12533 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
12534 (const_int 0)))]
12535 ""
12536 [(set (match_dup 0) (match_dup 1))]
12537{
12538 PUT_MODE (operands[1], QImode);
12539})
12540
12541(define_split
12542 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12543 (eq:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 12544 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
12545 (const_int 0)))]
12546 ""
12547 [(set (match_dup 0) (match_dup 1))]
12548{
12549 rtx new_op1 = copy_rtx (operands[1]);
12550 operands[1] = new_op1;
12551 PUT_MODE (new_op1, QImode);
3c5cb3e4
KH
12552 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12553 GET_MODE (XEXP (new_op1, 0))));
10978207
RH
12554
12555 /* Make sure that (a) the CCmode we have for the flags is strong
12556 enough for the reversed compare or (b) we have a valid FP compare. */
12557 if (! ix86_comparison_operator (new_op1, VOIDmode))
12558 FAIL;
12559})
12560
12561(define_split
12562 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12563 (eq:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 12564 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
12565 (const_int 0)))]
12566 ""
12567 [(set (match_dup 0) (match_dup 1))]
12568{
12569 rtx new_op1 = copy_rtx (operands[1]);
12570 operands[1] = new_op1;
12571 PUT_MODE (new_op1, QImode);
3c5cb3e4
KH
12572 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12573 GET_MODE (XEXP (new_op1, 0))));
10978207
RH
12574
12575 /* Make sure that (a) the CCmode we have for the flags is strong
12576 enough for the reversed compare or (b) we have a valid FP compare. */
12577 if (! ix86_comparison_operator (new_op1, VOIDmode))
12578 FAIL;
12579})
12580
a46d1d38
JH
12581;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12582;; subsequent logical operations are used to imitate conditional moves.
12583;; 0xffffffff is NaN, but not in normalized form, so we can't represent
d1f87653 12584;; it directly. Further holding this value in pseudo register might bring
a46d1d38
JH
12585;; problem in implicit normalization in spill code.
12586;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12587;; instructions after reload by splitting the conditional move patterns.
12588
12589(define_insn "*sse_setccsf"
12590 [(set (match_operand:SF 0 "register_operand" "=x")
12591 (match_operator:SF 1 "sse_comparison_operator"
12592 [(match_operand:SF 2 "register_operand" "0")
12593 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12594 "TARGET_SSE && reload_completed"
0f40f9f7 12595 "cmp%D1ss\t{%3, %0|%0, %3}"
3d34cd91 12596 [(set_attr "type" "ssecmp")
a46d1d38
JH
12597 (set_attr "mode" "SF")])
12598
12599(define_insn "*sse_setccdf"
12600 [(set (match_operand:DF 0 "register_operand" "=Y")
12601 (match_operator:DF 1 "sse_comparison_operator"
12602 [(match_operand:DF 2 "register_operand" "0")
12603 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12604 "TARGET_SSE2 && reload_completed"
0f40f9f7 12605 "cmp%D1sd\t{%3, %0|%0, %3}"
3d34cd91 12606 [(set_attr "type" "ssecmp")
a46d1d38 12607 (set_attr "mode" "DF")])
886c62d1
JVA
12608\f
12609;; Basic conditional jump instructions.
12610;; We ignore the overflow flag for signed branch instructions.
12611
c572e5ba 12612;; For all bCOND expanders, also expand the compare or test insn that
42fabf21 12613;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
c572e5ba
JVA
12614
12615(define_expand "beq"
e075ae69
RH
12616 [(set (pc)
12617 (if_then_else (match_dup 1)
c572e5ba
JVA
12618 (label_ref (match_operand 0 "" ""))
12619 (pc)))]
12620 ""
3a3677ff 12621 "ix86_expand_branch (EQ, operands[0]); DONE;")
c572e5ba 12622
c572e5ba 12623(define_expand "bne"
e075ae69
RH
12624 [(set (pc)
12625 (if_then_else (match_dup 1)
c572e5ba
JVA
12626 (label_ref (match_operand 0 "" ""))
12627 (pc)))]
12628 ""
3a3677ff 12629 "ix86_expand_branch (NE, operands[0]); DONE;")
886c62d1 12630
c572e5ba 12631(define_expand "bgt"
e075ae69
RH
12632 [(set (pc)
12633 (if_then_else (match_dup 1)
c572e5ba
JVA
12634 (label_ref (match_operand 0 "" ""))
12635 (pc)))]
12636 ""
3a3677ff 12637 "ix86_expand_branch (GT, operands[0]); DONE;")
c572e5ba 12638
c572e5ba 12639(define_expand "bgtu"
e075ae69
RH
12640 [(set (pc)
12641 (if_then_else (match_dup 1)
c572e5ba
JVA
12642 (label_ref (match_operand 0 "" ""))
12643 (pc)))]
12644 ""
3a3677ff 12645 "ix86_expand_branch (GTU, operands[0]); DONE;")
886c62d1 12646
886c62d1 12647(define_expand "blt"
e075ae69
RH
12648 [(set (pc)
12649 (if_then_else (match_dup 1)
886c62d1
JVA
12650 (label_ref (match_operand 0 "" ""))
12651 (pc)))]
12652 ""
3a3677ff 12653 "ix86_expand_branch (LT, operands[0]); DONE;")
886c62d1 12654
c572e5ba 12655(define_expand "bltu"
e075ae69
RH
12656 [(set (pc)
12657 (if_then_else (match_dup 1)
c572e5ba
JVA
12658 (label_ref (match_operand 0 "" ""))
12659 (pc)))]
12660 ""
3a3677ff 12661 "ix86_expand_branch (LTU, operands[0]); DONE;")
c572e5ba 12662
c572e5ba 12663(define_expand "bge"
e075ae69
RH
12664 [(set (pc)
12665 (if_then_else (match_dup 1)
c572e5ba
JVA
12666 (label_ref (match_operand 0 "" ""))
12667 (pc)))]
12668 ""
3a3677ff 12669 "ix86_expand_branch (GE, operands[0]); DONE;")
c572e5ba 12670
c572e5ba 12671(define_expand "bgeu"
e075ae69
RH
12672 [(set (pc)
12673 (if_then_else (match_dup 1)
c572e5ba
JVA
12674 (label_ref (match_operand 0 "" ""))
12675 (pc)))]
12676 ""
3a3677ff 12677 "ix86_expand_branch (GEU, operands[0]); DONE;")
886c62d1 12678
886c62d1 12679(define_expand "ble"
e075ae69
RH
12680 [(set (pc)
12681 (if_then_else (match_dup 1)
886c62d1
JVA
12682 (label_ref (match_operand 0 "" ""))
12683 (pc)))]
12684 ""
3a3677ff 12685 "ix86_expand_branch (LE, operands[0]); DONE;")
886c62d1 12686
c572e5ba 12687(define_expand "bleu"
e075ae69
RH
12688 [(set (pc)
12689 (if_then_else (match_dup 1)
c572e5ba
JVA
12690 (label_ref (match_operand 0 "" ""))
12691 (pc)))]
12692 ""
3a3677ff
RH
12693 "ix86_expand_branch (LEU, operands[0]); DONE;")
12694
12695(define_expand "bunordered"
12696 [(set (pc)
12697 (if_then_else (match_dup 1)
12698 (label_ref (match_operand 0 "" ""))
12699 (pc)))]
0644b628 12700 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12701 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12702
12703(define_expand "bordered"
12704 [(set (pc)
12705 (if_then_else (match_dup 1)
12706 (label_ref (match_operand 0 "" ""))
12707 (pc)))]
0644b628 12708 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12709 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12710
12711(define_expand "buneq"
12712 [(set (pc)
12713 (if_then_else (match_dup 1)
12714 (label_ref (match_operand 0 "" ""))
12715 (pc)))]
0644b628 12716 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12717 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12718
12719(define_expand "bunge"
12720 [(set (pc)
12721 (if_then_else (match_dup 1)
12722 (label_ref (match_operand 0 "" ""))
12723 (pc)))]
0644b628 12724 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12725 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12726
12727(define_expand "bungt"
12728 [(set (pc)
12729 (if_then_else (match_dup 1)
12730 (label_ref (match_operand 0 "" ""))
12731 (pc)))]
0644b628 12732 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12733 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12734
12735(define_expand "bunle"
12736 [(set (pc)
12737 (if_then_else (match_dup 1)
12738 (label_ref (match_operand 0 "" ""))
12739 (pc)))]
0644b628 12740 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12741 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12742
12743(define_expand "bunlt"
12744 [(set (pc)
12745 (if_then_else (match_dup 1)
12746 (label_ref (match_operand 0 "" ""))
12747 (pc)))]
0644b628 12748 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12749 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12750
12751(define_expand "bltgt"
12752 [(set (pc)
12753 (if_then_else (match_dup 1)
12754 (label_ref (match_operand 0 "" ""))
12755 (pc)))]
0644b628 12756 "TARGET_80387 || TARGET_SSE"
3a3677ff 12757 "ix86_expand_branch (LTGT, operands[0]); DONE;")
886c62d1 12758
e075ae69
RH
12759(define_insn "*jcc_1"
12760 [(set (pc)
9076b9c1 12761 (if_then_else (match_operator 1 "ix86_comparison_operator"
42fabf21 12762 [(reg FLAGS_REG) (const_int 0)])
6ef67412 12763 (label_ref (match_operand 0 "" ""))
e075ae69
RH
12764 (pc)))]
12765 ""
0f40f9f7 12766 "%+j%C1\t%l0"
e075ae69 12767 [(set_attr "type" "ibr")
c7375e61 12768 (set_attr "modrm" "0")
efcc7037 12769 (set (attr "length")
6ef67412 12770 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 12771 (const_int -126))
6ef67412 12772 (lt (minus (match_dup 0) (pc))
db1077d3 12773 (const_int 128)))
efcc7037
JH
12774 (const_int 2)
12775 (const_int 6)))])
e075ae69
RH
12776
12777(define_insn "*jcc_2"
12778 [(set (pc)
9076b9c1 12779 (if_then_else (match_operator 1 "ix86_comparison_operator"
42fabf21 12780 [(reg FLAGS_REG) (const_int 0)])
e075ae69 12781 (pc)
6ef67412 12782 (label_ref (match_operand 0 "" ""))))]
e075ae69 12783 ""
0f40f9f7 12784 "%+j%c1\t%l0"
e075ae69 12785 [(set_attr "type" "ibr")
c7375e61 12786 (set_attr "modrm" "0")
efcc7037 12787 (set (attr "length")
6ef67412 12788 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 12789 (const_int -126))
6ef67412 12790 (lt (minus (match_dup 0) (pc))
db1077d3 12791 (const_int 128)))
efcc7037
JH
12792 (const_int 2)
12793 (const_int 6)))])
e075ae69 12794
592188a5
RH
12795;; In general it is not safe to assume too much about CCmode registers,
12796;; so simplify-rtx stops when it sees a second one. Under certain
12797;; conditions this is safe on x86, so help combine not create
12798;;
12799;; seta %al
12800;; testb %al, %al
12801;; je Lfoo
12802
12803(define_split
12804 [(set (pc)
12805 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
42fabf21 12806 [(reg FLAGS_REG) (const_int 0)])
592188a5
RH
12807 (const_int 0))
12808 (label_ref (match_operand 1 "" ""))
12809 (pc)))]
12810 ""
12811 [(set (pc)
12812 (if_then_else (match_dup 0)
12813 (label_ref (match_dup 1))
12814 (pc)))]
12815{
12816 PUT_MODE (operands[0], VOIDmode);
12817})
12818
12819(define_split
12820 [(set (pc)
12821 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
42fabf21 12822 [(reg FLAGS_REG) (const_int 0)])
592188a5
RH
12823 (const_int 0))
12824 (label_ref (match_operand 1 "" ""))
12825 (pc)))]
12826 ""
12827 [(set (pc)
12828 (if_then_else (match_dup 0)
12829 (label_ref (match_dup 1))
12830 (pc)))]
12831{
12832 rtx new_op0 = copy_rtx (operands[0]);
12833 operands[0] = new_op0;
12834 PUT_MODE (new_op0, VOIDmode);
3c5cb3e4
KH
12835 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12836 GET_MODE (XEXP (new_op0, 0))));
592188a5
RH
12837
12838 /* Make sure that (a) the CCmode we have for the flags is strong
12839 enough for the reversed compare or (b) we have a valid FP compare. */
12840 if (! ix86_comparison_operator (new_op0, VOIDmode))
12841 FAIL;
12842})
12843
3a3677ff
RH
12844;; Define combination compare-and-branch fp compare instructions to use
12845;; during early optimization. Splitting the operation apart early makes
12846;; for bad code when we want to reverse the operation.
12847
12848(define_insn "*fp_jcc_1"
12849 [(set (pc)
12850 (if_then_else (match_operator 0 "comparison_operator"
12851 [(match_operand 1 "register_operand" "f")
12852 (match_operand 2 "register_operand" "f")])
12853 (label_ref (match_operand 3 "" ""))
12854 (pc)))
8bc527af
SB
12855 (clobber (reg:CCFP FPSR_REG))
12856 (clobber (reg:CCFP FLAGS_REG))]
3a3677ff 12857 "TARGET_CMOVE && TARGET_80387
0644b628 12858 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
3a3677ff 12859 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12860 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12861 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12862 "#")
12863
0644b628
JH
12864(define_insn "*fp_jcc_1_sse"
12865 [(set (pc)
12866 (if_then_else (match_operator 0 "comparison_operator"
12867 [(match_operand 1 "register_operand" "f#x,x#f")
12868 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12869 (label_ref (match_operand 3 "" ""))
12870 (pc)))
8bc527af
SB
12871 (clobber (reg:CCFP FPSR_REG))
12872 (clobber (reg:CCFP FLAGS_REG))]
0644b628
JH
12873 "TARGET_80387
12874 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12875 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12876 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12877 "#")
12878
12879(define_insn "*fp_jcc_1_sse_only"
12880 [(set (pc)
12881 (if_then_else (match_operator 0 "comparison_operator"
12882 [(match_operand 1 "register_operand" "x")
12883 (match_operand 2 "nonimmediate_operand" "xm")])
12884 (label_ref (match_operand 3 "" ""))
12885 (pc)))
8bc527af
SB
12886 (clobber (reg:CCFP FPSR_REG))
12887 (clobber (reg:CCFP FLAGS_REG))]
0644b628 12888 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12889 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12890 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12891 "#")
12892
3a3677ff
RH
12893(define_insn "*fp_jcc_2"
12894 [(set (pc)
12895 (if_then_else (match_operator 0 "comparison_operator"
12896 [(match_operand 1 "register_operand" "f")
12897 (match_operand 2 "register_operand" "f")])
12898 (pc)
12899 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
12900 (clobber (reg:CCFP FPSR_REG))
12901 (clobber (reg:CCFP FLAGS_REG))]
3a3677ff 12902 "TARGET_CMOVE && TARGET_80387
0644b628 12903 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
3a3677ff 12904 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12905 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12906 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12907 "#")
12908
0644b628
JH
12909(define_insn "*fp_jcc_2_sse"
12910 [(set (pc)
12911 (if_then_else (match_operator 0 "comparison_operator"
12912 [(match_operand 1 "register_operand" "f#x,x#f")
12913 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12914 (pc)
12915 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
12916 (clobber (reg:CCFP FPSR_REG))
12917 (clobber (reg:CCFP FLAGS_REG))]
0644b628
JH
12918 "TARGET_80387
12919 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12920 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12921 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12922 "#")
12923
12924(define_insn "*fp_jcc_2_sse_only"
12925 [(set (pc)
12926 (if_then_else (match_operator 0 "comparison_operator"
12927 [(match_operand 1 "register_operand" "x")
12928 (match_operand 2 "nonimmediate_operand" "xm")])
12929 (pc)
12930 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
12931 (clobber (reg:CCFP FPSR_REG))
12932 (clobber (reg:CCFP FLAGS_REG))]
0644b628 12933 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12934 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12935 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12936 "#")
12937
3a3677ff
RH
12938(define_insn "*fp_jcc_3"
12939 [(set (pc)
b1cdafbb 12940 (if_then_else (match_operator 0 "comparison_operator"
3a3677ff
RH
12941 [(match_operand 1 "register_operand" "f")
12942 (match_operand 2 "nonimmediate_operand" "fm")])
12943 (label_ref (match_operand 3 "" ""))
12944 (pc)))
8bc527af
SB
12945 (clobber (reg:CCFP FPSR_REG))
12946 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
12947 (clobber (match_scratch:HI 4 "=a"))]
12948 "TARGET_80387
12949 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 12950 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb
JH
12951 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12952 && SELECT_CC_MODE (GET_CODE (operands[0]),
03598dea
JH
12953 operands[1], operands[2]) == CCFPmode
12954 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12955 "#")
12956
12957(define_insn "*fp_jcc_4"
12958 [(set (pc)
b1cdafbb 12959 (if_then_else (match_operator 0 "comparison_operator"
3a3677ff
RH
12960 [(match_operand 1 "register_operand" "f")
12961 (match_operand 2 "nonimmediate_operand" "fm")])
12962 (pc)
12963 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
12964 (clobber (reg:CCFP FPSR_REG))
12965 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
12966 (clobber (match_scratch:HI 4 "=a"))]
12967 "TARGET_80387
12968 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 12969 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb
JH
12970 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12971 && SELECT_CC_MODE (GET_CODE (operands[0]),
03598dea
JH
12972 operands[1], operands[2]) == CCFPmode
12973 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12974 "#")
12975
12976(define_insn "*fp_jcc_5"
12977 [(set (pc)
12978 (if_then_else (match_operator 0 "comparison_operator"
12979 [(match_operand 1 "register_operand" "f")
12980 (match_operand 2 "register_operand" "f")])
12981 (label_ref (match_operand 3 "" ""))
12982 (pc)))
8bc527af
SB
12983 (clobber (reg:CCFP FPSR_REG))
12984 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
12985 (clobber (match_scratch:HI 4 "=a"))]
12986 "TARGET_80387
12987 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12988 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12989 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12990 "#")
12991
12992(define_insn "*fp_jcc_6"
12993 [(set (pc)
12994 (if_then_else (match_operator 0 "comparison_operator"
12995 [(match_operand 1 "register_operand" "f")
12996 (match_operand 2 "register_operand" "f")])
12997 (pc)
12998 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
12999 (clobber (reg:CCFP FPSR_REG))
13000 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
13001 (clobber (match_scratch:HI 4 "=a"))]
13002 "TARGET_80387
13003 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
13004 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13005 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
13006 "#")
13007
45c8c47f
UB
13008(define_insn "*fp_jcc_7"
13009 [(set (pc)
13010 (if_then_else (match_operator 0 "comparison_operator"
13011 [(match_operand 1 "register_operand" "f")
13012 (match_operand 2 "const_double_operand" "C")])
13013 (label_ref (match_operand 3 "" ""))
13014 (pc)))
13015 (clobber (reg:CCFP FPSR_REG))
13016 (clobber (reg:CCFP FLAGS_REG))
13017 (clobber (match_scratch:HI 4 "=a"))]
13018 "TARGET_80387
13019 && FLOAT_MODE_P (GET_MODE (operands[1]))
13020 && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13021 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13022 && SELECT_CC_MODE (GET_CODE (operands[0]),
13023 operands[1], operands[2]) == CCFPmode
13024 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13025 "#")
13026
7c82106f
UB
13027;; The order of operands in *fp_jcc_8 is forced by combine in
13028;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13029;; with a precedence over other operators and is always put in the first
13030;; place. Swap condition and operands to match ficom instruction.
13031
13032(define_insn "*fp_jcc_8"
13033 [(set (pc)
13034 (if_then_else (match_operator 0 "comparison_operator"
13035 [(match_operator 1 "float_operator"
13036 [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13037 (match_operand 3 "register_operand" "f,f")])
13038 (label_ref (match_operand 4 "" ""))
13039 (pc)))
13040 (clobber (reg:CCFP FPSR_REG))
13041 (clobber (reg:CCFP FLAGS_REG))
13042 (clobber (match_scratch:HI 5 "=a,a"))]
13043 "TARGET_80387 && TARGET_USE_FIOP
13044 && FLOAT_MODE_P (GET_MODE (operands[3]))
13045 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13046 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13047 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13048 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13049 "#")
13050
3a3677ff
RH
13051(define_split
13052 [(set (pc)
13053 (if_then_else (match_operator 0 "comparison_operator"
13054 [(match_operand 1 "register_operand" "")
13055 (match_operand 2 "nonimmediate_operand" "")])
13056 (match_operand 3 "" "")
13057 (match_operand 4 "" "")))
8bc527af
SB
13058 (clobber (reg:CCFP FPSR_REG))
13059 (clobber (reg:CCFP FLAGS_REG))]
3a3677ff 13060 "reload_completed"
9e7adcb3 13061 [(const_int 0)]
3a3677ff 13062{
03598dea 13063 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
7c82106f 13064 operands[3], operands[4], NULL_RTX, NULL_RTX);
9e7adcb3 13065 DONE;
0f40f9f7 13066})
3a3677ff
RH
13067
13068(define_split
13069 [(set (pc)
13070 (if_then_else (match_operator 0 "comparison_operator"
13071 [(match_operand 1 "register_operand" "")
45c8c47f 13072 (match_operand 2 "general_operand" "")])
3a3677ff
RH
13073 (match_operand 3 "" "")
13074 (match_operand 4 "" "")))
8bc527af
SB
13075 (clobber (reg:CCFP FPSR_REG))
13076 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
13077 (clobber (match_scratch:HI 5 "=a"))]
13078 "reload_completed"
45c8c47f 13079 [(const_int 0)]
3a3677ff 13080{
03598dea 13081 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
7c82106f
UB
13082 operands[3], operands[4], operands[5], NULL_RTX);
13083 DONE;
13084})
13085
13086(define_split
13087 [(set (pc)
13088 (if_then_else (match_operator 0 "comparison_operator"
13089 [(match_operator 1 "float_operator"
13090 [(match_operand:SI 2 "memory_operand" "")])
13091 (match_operand 3 "register_operand" "")])
13092 (match_operand 4 "" "")
13093 (match_operand 5 "" "")))
13094 (clobber (reg:CCFP FPSR_REG))
13095 (clobber (reg:CCFP FLAGS_REG))
13096 (clobber (match_scratch:HI 6 "=a"))]
13097 "reload_completed"
13098 [(const_int 0)]
13099{
13100 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13101 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13102 operands[3], operands[7],
13103 operands[4], operands[5], operands[6], NULL_RTX);
13104 DONE;
13105})
13106
13107;; %%% Kill this when reload knows how to do it.
13108(define_split
13109 [(set (pc)
13110 (if_then_else (match_operator 0 "comparison_operator"
13111 [(match_operator 1 "float_operator"
13112 [(match_operand:SI 2 "register_operand" "")])
13113 (match_operand 3 "register_operand" "")])
13114 (match_operand 4 "" "")
13115 (match_operand 5 "" "")))
13116 (clobber (reg:CCFP FPSR_REG))
13117 (clobber (reg:CCFP FLAGS_REG))
13118 (clobber (match_scratch:HI 6 "=a"))]
13119 "reload_completed"
13120 [(const_int 0)]
13121{
13122 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13123 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13124 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13125 operands[3], operands[7],
13126 operands[4], operands[5], operands[6], operands[2]);
9e7adcb3 13127 DONE;
0f40f9f7 13128})
886c62d1
JVA
13129\f
13130;; Unconditional and other jump instructions
13131
13132(define_insn "jump"
13133 [(set (pc)
13134 (label_ref (match_operand 0 "" "")))]
13135 ""
0f40f9f7 13136 "jmp\t%l0"
c7375e61 13137 [(set_attr "type" "ibr")
efcc7037
JH
13138 (set (attr "length")
13139 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 13140 (const_int -126))
efcc7037 13141 (lt (minus (match_dup 0) (pc))
db1077d3 13142 (const_int 128)))
efcc7037
JH
13143 (const_int 2)
13144 (const_int 5)))
c7375e61 13145 (set_attr "modrm" "0")])
886c62d1 13146
14f73b5a
JH
13147(define_expand "indirect_jump"
13148 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
886c62d1 13149 ""
14f73b5a
JH
13150 "")
13151
13152(define_insn "*indirect_jump"
13153 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13154 "!TARGET_64BIT"
13155 "jmp\t%A0"
13156 [(set_attr "type" "ibr")
13157 (set_attr "length_immediate" "0")])
13158
13159(define_insn "*indirect_jump_rtx64"
13160 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13161 "TARGET_64BIT"
0f40f9f7 13162 "jmp\t%A0"
6ef67412
JH
13163 [(set_attr "type" "ibr")
13164 (set_attr "length_immediate" "0")])
4801403e 13165
90675921 13166(define_expand "tablejump"
6eb791fc 13167 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
90675921
RH
13168 (use (label_ref (match_operand 1 "" "")))])]
13169 ""
13170{
66edd3b4
RH
13171 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13172 relative. Convert the relative address to an absolute address. */
90675921
RH
13173 if (flag_pic)
13174 {
66edd3b4
RH
13175 rtx op0, op1;
13176 enum rtx_code code;
13177
6eb791fc 13178 if (TARGET_64BIT)
66edd3b4
RH
13179 {
13180 code = PLUS;
13181 op0 = operands[0];
13182 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13183 }
b069de3b 13184 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
f88c65f7 13185 {
66edd3b4
RH
13186 code = PLUS;
13187 op0 = operands[0];
13188 op1 = pic_offset_table_rtx;
f88c65f7 13189 }
6eb791fc
JH
13190 else
13191 {
66edd3b4
RH
13192 code = MINUS;
13193 op0 = pic_offset_table_rtx;
13194 op1 = operands[0];
6eb791fc 13195 }
66edd3b4 13196
c16576e6 13197 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
66edd3b4 13198 OPTAB_DIRECT);
90675921 13199 }
0f40f9f7 13200})
2bb7a0f5 13201
90675921 13202(define_insn "*tablejump_1"
2ae0f82c 13203 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
886c62d1 13204 (use (label_ref (match_operand 1 "" "")))]
14f73b5a
JH
13205 "!TARGET_64BIT"
13206 "jmp\t%A0"
13207 [(set_attr "type" "ibr")
13208 (set_attr "length_immediate" "0")])
13209
13210(define_insn "*tablejump_1_rtx64"
13211 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13212 (use (label_ref (match_operand 1 "" "")))]
13213 "TARGET_64BIT"
0f40f9f7 13214 "jmp\t%A0"
6ef67412
JH
13215 [(set_attr "type" "ibr")
13216 (set_attr "length_immediate" "0")])
e075ae69
RH
13217\f
13218;; Loop instruction
13219;;
13220;; This is all complicated by the fact that since this is a jump insn
13221;; we must handle our own reloads.
13222
5527bf14
RH
13223(define_expand "doloop_end"
13224 [(use (match_operand 0 "" "")) ; loop pseudo
13225 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13226 (use (match_operand 2 "" "")) ; max iterations
13227 (use (match_operand 3 "" "")) ; loop level
13228 (use (match_operand 4 "" ""))] ; label
1b0c37d7 13229 "!TARGET_64BIT && TARGET_USE_LOOP"
5527bf14
RH
13230 "
13231{
13232 /* Only use cloop on innermost loops. */
13233 if (INTVAL (operands[3]) > 1)
13234 FAIL;
13235 if (GET_MODE (operands[0]) != SImode)
13236 FAIL;
13237 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13238 operands[0]));
13239 DONE;
13240}")
e075ae69 13241
5527bf14 13242(define_insn "doloop_end_internal"
e075ae69 13243 [(set (pc)
5527bf14 13244 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
e075ae69
RH
13245 (const_int 1))
13246 (label_ref (match_operand 0 "" ""))
13247 (pc)))
e0c34369 13248 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
e075ae69
RH
13249 (plus:SI (match_dup 1)
13250 (const_int -1)))
13251 (clobber (match_scratch:SI 3 "=X,X,r"))
8bc527af 13252 (clobber (reg:CC FLAGS_REG))]
e0c34369
JW
13253 "!TARGET_64BIT && TARGET_USE_LOOP
13254 && (reload_in_progress || reload_completed
13255 || register_operand (operands[2], VOIDmode))"
e075ae69
RH
13256{
13257 if (which_alternative != 0)
0f40f9f7 13258 return "#";
e075ae69 13259 if (get_attr_length (insn) == 2)
0f40f9f7 13260 return "%+loop\t%l0";
e075ae69 13261 else
0f40f9f7
ZW
13262 return "dec{l}\t%1\;%+jne\t%l0";
13263}
56bab446 13264 [(set (attr "length")
c7375e61
EB
13265 (if_then_else (and (eq_attr "alternative" "0")
13266 (and (ge (minus (match_dup 0) (pc))
db1077d3 13267 (const_int -126))
c7375e61 13268 (lt (minus (match_dup 0) (pc))
db1077d3 13269 (const_int 128))))
c7375e61
EB
13270 (const_int 2)
13271 (const_int 16)))
efcc7037
JH
13272 ;; We don't know the type before shorten branches. Optimistically expect
13273 ;; the loop instruction to match.
13274 (set (attr "type") (const_string "ibr"))])
e075ae69 13275
e075ae69
RH
13276(define_split
13277 [(set (pc)
13278 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13279 (const_int 1))
13280 (match_operand 0 "" "")
13281 (pc)))
5527bf14 13282 (set (match_dup 1)
e075ae69
RH
13283 (plus:SI (match_dup 1)
13284 (const_int -1)))
5527bf14 13285 (clobber (match_scratch:SI 2 ""))
8bc527af 13286 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 13287 "!TARGET_64BIT && TARGET_USE_LOOP
5527bf14
RH
13288 && reload_completed
13289 && REGNO (operands[1]) != 2"
8bc527af 13290 [(parallel [(set (reg:CCZ FLAGS_REG)
5527bf14 13291 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
e075ae69 13292 (const_int 0)))
5527bf14 13293 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
8bc527af 13294 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
e075ae69
RH
13295 (match_dup 0)
13296 (pc)))]
13297 "")
13298
13299(define_split
13300 [(set (pc)
13301 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13302 (const_int 1))
13303 (match_operand 0 "" "")
13304 (pc)))
5527bf14 13305 (set (match_operand:SI 2 "nonimmediate_operand" "")
e075ae69
RH
13306 (plus:SI (match_dup 1)
13307 (const_int -1)))
13308 (clobber (match_scratch:SI 3 ""))
8bc527af 13309 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 13310 "!TARGET_64BIT && TARGET_USE_LOOP
5527bf14
RH
13311 && reload_completed
13312 && (! REG_P (operands[2])
13313 || ! rtx_equal_p (operands[1], operands[2]))"
e075ae69 13314 [(set (match_dup 3) (match_dup 1))
8bc527af 13315 (parallel [(set (reg:CCZ FLAGS_REG)
16189740
RH
13316 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13317 (const_int 0)))
e075ae69
RH
13318 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13319 (set (match_dup 2) (match_dup 3))
8bc527af 13320 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
e075ae69
RH
13321 (match_dup 0)
13322 (pc)))]
13323 "")
c50e5bc0
RH
13324
13325;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13326
13327(define_peephole2
42fabf21 13328 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
c50e5bc0
RH
13329 (set (match_operand:QI 1 "register_operand" "")
13330 (match_operator:QI 2 "ix86_comparison_operator"
42fabf21 13331 [(reg FLAGS_REG) (const_int 0)]))
c50e5bc0
RH
13332 (set (match_operand 3 "q_regs_operand" "")
13333 (zero_extend (match_dup 1)))]
646ded90
RH
13334 "(peep2_reg_dead_p (3, operands[1])
13335 || operands_match_p (operands[1], operands[3]))
c50e5bc0 13336 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
646ded90
RH
13337 [(set (match_dup 4) (match_dup 0))
13338 (set (strict_low_part (match_dup 5))
13339 (match_dup 2))]
13340{
13341 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1e2115dc 13342 operands[5] = gen_lowpart (QImode, operands[3]);
a8bac9ab 13343 ix86_expand_clear (operands[3]);
646ded90
RH
13344})
13345
13346;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13347
13348(define_peephole2
42fabf21 13349 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
646ded90
RH
13350 (set (match_operand:QI 1 "register_operand" "")
13351 (match_operator:QI 2 "ix86_comparison_operator"
42fabf21 13352 [(reg FLAGS_REG) (const_int 0)]))
646ded90
RH
13353 (parallel [(set (match_operand 3 "q_regs_operand" "")
13354 (zero_extend (match_dup 1)))
8bc527af 13355 (clobber (reg:CC FLAGS_REG))])]
646ded90
RH
13356 "(peep2_reg_dead_p (3, operands[1])
13357 || operands_match_p (operands[1], operands[3]))
13358 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13359 [(set (match_dup 4) (match_dup 0))
c50e5bc0
RH
13360 (set (strict_low_part (match_dup 5))
13361 (match_dup 2))]
646ded90
RH
13362{
13363 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1e2115dc 13364 operands[5] = gen_lowpart (QImode, operands[3]);
a8bac9ab 13365 ix86_expand_clear (operands[3]);
646ded90 13366})
e075ae69
RH
13367\f
13368;; Call instructions.
2bb7a0f5 13369
cbbf65e0
RH
13370;; The predicates normally associated with named expanders are not properly
13371;; checked for calls. This is a bug in the generic code, but it isn't that
13372;; easy to fix. Ignore it for now and be prepared to fix things up.
2bb7a0f5 13373
886c62d1
JVA
13374;; Call subroutine returning no value.
13375
2bb7a0f5 13376(define_expand "call_pop"
cbbf65e0
RH
13377 [(parallel [(call (match_operand:QI 0 "" "")
13378 (match_operand:SI 1 "" ""))
8bc527af
SB
13379 (set (reg:SI SP_REG)
13380 (plus:SI (reg:SI SP_REG)
cbbf65e0 13381 (match_operand:SI 3 "" "")))])]
1e07edd3 13382 "!TARGET_64BIT"
2bb7a0f5 13383{
4977bab6 13384 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
0e07aff3 13385 DONE;
0f40f9f7 13386})
2bb7a0f5 13387
94bb5d0c 13388(define_insn "*call_pop_0"
e1ff012c 13389 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
94bb5d0c 13390 (match_operand:SI 1 "" ""))
8bc527af 13391 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 13392 (match_operand:SI 2 "immediate_operand" "")))]
1e07edd3 13393 "!TARGET_64BIT"
94bb5d0c
RH
13394{
13395 if (SIBLING_CALL_P (insn))
0f40f9f7 13396 return "jmp\t%P0";
94bb5d0c 13397 else
0f40f9f7
ZW
13398 return "call\t%P0";
13399}
94bb5d0c
RH
13400 [(set_attr "type" "call")])
13401
cbbf65e0 13402(define_insn "*call_pop_1"
e1ff012c 13403 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
94bb5d0c 13404 (match_operand:SI 1 "" ""))
8bc527af 13405 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 13406 (match_operand:SI 2 "immediate_operand" "i")))]
1e07edd3 13407 "!TARGET_64BIT"
886c62d1 13408{
e1ff012c 13409 if (constant_call_address_operand (operands[0], Pmode))
94bb5d0c
RH
13410 {
13411 if (SIBLING_CALL_P (insn))
0f40f9f7 13412 return "jmp\t%P0";
94bb5d0c 13413 else
0f40f9f7 13414 return "call\t%P0";
94bb5d0c 13415 }
94bb5d0c 13416 if (SIBLING_CALL_P (insn))
0f40f9f7 13417 return "jmp\t%A0";
94bb5d0c 13418 else
0f40f9f7
ZW
13419 return "call\t%A0";
13420}
e075ae69 13421 [(set_attr "type" "call")])
886c62d1 13422
2bb7a0f5 13423(define_expand "call"
cbbf65e0 13424 [(call (match_operand:QI 0 "" "")
39d04363
JH
13425 (match_operand 1 "" ""))
13426 (use (match_operand 2 "" ""))]
2bb7a0f5 13427 ""
2bb7a0f5 13428{
4977bab6
ZW
13429 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13430 DONE;
13431})
13432
13433(define_expand "sibcall"
13434 [(call (match_operand:QI 0 "" "")
13435 (match_operand 1 "" ""))
13436 (use (match_operand 2 "" ""))]
13437 ""
13438{
13439 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
0e07aff3 13440 DONE;
0f40f9f7 13441})
2bb7a0f5 13442
94bb5d0c 13443(define_insn "*call_0"
32ee7d1d
JH
13444 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13445 (match_operand 1 "" ""))]
94bb5d0c 13446 ""
94bb5d0c
RH
13447{
13448 if (SIBLING_CALL_P (insn))
0f40f9f7 13449 return "jmp\t%P0";
94bb5d0c 13450 else
0f40f9f7
ZW
13451 return "call\t%P0";
13452}
94bb5d0c
RH
13453 [(set_attr "type" "call")])
13454
cbbf65e0 13455(define_insn "*call_1"
e1ff012c 13456 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
32ee7d1d 13457 (match_operand 1 "" ""))]
4977bab6 13458 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
32ee7d1d 13459{
e427abbf 13460 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
13461 return "call\t%P0";
13462 return "call\t%A0";
13463}
13464 [(set_attr "type" "call")])
13465
13466(define_insn "*sibcall_1"
13467 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13468 (match_operand 1 "" ""))]
13469 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13470{
e427abbf 13471 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
13472 return "jmp\t%P0";
13473 return "jmp\t%A0";
0f40f9f7 13474}
32ee7d1d
JH
13475 [(set_attr "type" "call")])
13476
13477(define_insn "*call_1_rex64"
13478 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13479 (match_operand 1 "" ""))]
4977bab6 13480 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
886c62d1 13481{
e427abbf 13482 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
13483 return "call\t%P0";
13484 return "call\t%A0";
0f40f9f7 13485}
e075ae69 13486 [(set_attr "type" "call")])
886c62d1 13487
4977bab6
ZW
13488(define_insn "*sibcall_1_rex64"
13489 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13490 (match_operand 1 "" ""))]
13491 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13492 "jmp\t%P0"
13493 [(set_attr "type" "call")])
13494
13495(define_insn "*sibcall_1_rex64_v"
13496 [(call (mem:QI (reg:DI 40))
13497 (match_operand 0 "" ""))]
13498 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13499 "jmp\t*%%r11"
13500 [(set_attr "type" "call")])
13501
13502
886c62d1 13503;; Call subroutine, returning value in operand 0
886c62d1 13504
2bb7a0f5
RS
13505(define_expand "call_value_pop"
13506 [(parallel [(set (match_operand 0 "" "")
cbbf65e0
RH
13507 (call (match_operand:QI 1 "" "")
13508 (match_operand:SI 2 "" "")))
8bc527af
SB
13509 (set (reg:SI SP_REG)
13510 (plus:SI (reg:SI SP_REG)
cbbf65e0 13511 (match_operand:SI 4 "" "")))])]
1e07edd3 13512 "!TARGET_64BIT"
2bb7a0f5 13513{
0e07aff3 13514 ix86_expand_call (operands[0], operands[1], operands[2],
4977bab6 13515 operands[3], operands[4], 0);
0e07aff3 13516 DONE;
0f40f9f7 13517})
2bb7a0f5 13518
2bb7a0f5
RS
13519(define_expand "call_value"
13520 [(set (match_operand 0 "" "")
cbbf65e0 13521 (call (match_operand:QI 1 "" "")
39d04363
JH
13522 (match_operand:SI 2 "" "")))
13523 (use (match_operand:SI 3 "" ""))]
2bb7a0f5
RS
13524 ;; Operand 2 not used on the i386.
13525 ""
2bb7a0f5 13526{
4977bab6
ZW
13527 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13528 DONE;
13529})
13530
13531(define_expand "sibcall_value"
13532 [(set (match_operand 0 "" "")
13533 (call (match_operand:QI 1 "" "")
13534 (match_operand:SI 2 "" "")))
13535 (use (match_operand:SI 3 "" ""))]
13536 ;; Operand 2 not used on the i386.
13537 ""
13538{
13539 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
39d04363 13540 DONE;
0f40f9f7 13541})
2bb7a0f5 13542
b840bfb0
MM
13543;; Call subroutine returning any type.
13544
576182a3 13545(define_expand "untyped_call"
b840bfb0 13546 [(parallel [(call (match_operand 0 "" "")
576182a3 13547 (const_int 0))
b840bfb0 13548 (match_operand 1 "" "")
576182a3
TW
13549 (match_operand 2 "" "")])]
13550 ""
576182a3 13551{
b840bfb0 13552 int i;
576182a3 13553
d8b679b9
RK
13554 /* In order to give reg-stack an easier job in validating two
13555 coprocessor registers as containing a possible return value,
13556 simply pretend the untyped call returns a complex long double
13557 value. */
74775c7a 13558
0e07aff3
RH
13559 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13560 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13561 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
4977bab6 13562 NULL, 0);
576182a3 13563
b840bfb0 13564 for (i = 0; i < XVECLEN (operands[2], 0); i++)
576182a3 13565 {
b840bfb0
MM
13566 rtx set = XVECEXP (operands[2], 0, i);
13567 emit_move_insn (SET_DEST (set), SET_SRC (set));
576182a3 13568 }
576182a3 13569
b840bfb0
MM
13570 /* The optimizer does not know that the call sets the function value
13571 registers we stored in the result block. We avoid problems by
13572 claiming that all hard registers are used and clobbered at this
13573 point. */
66edd3b4 13574 emit_insn (gen_blockage (const0_rtx));
576182a3
TW
13575
13576 DONE;
0f40f9f7 13577})
e075ae69
RH
13578\f
13579;; Prologue and epilogue instructions
576182a3 13580
b840bfb0
MM
13581;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13582;; all of memory. This blocks insns from being moved across this point.
13583
13584(define_insn "blockage"
66edd3b4 13585 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
576182a3 13586 ""
90aec2cf 13587 ""
e075ae69 13588 [(set_attr "length" "0")])
576182a3 13589
886c62d1
JVA
13590;; Insn emitted into the body of a function to return from a function.
13591;; This is only done if the function's epilogue is known to be simple.
182a4620 13592;; See comments for ix86_can_use_return_insn_p in i386.c.
886c62d1 13593
5f3d14e3 13594(define_expand "return"
886c62d1 13595 [(return)]
5f3d14e3 13596 "ix86_can_use_return_insn_p ()"
9a7372d6
RH
13597{
13598 if (current_function_pops_args)
13599 {
13600 rtx popc = GEN_INT (current_function_pops_args);
13601 emit_jump_insn (gen_return_pop_internal (popc));
13602 DONE;
13603 }
0f40f9f7 13604})
5f3d14e3
SC
13605
13606(define_insn "return_internal"
13607 [(return)]
13608 "reload_completed"
90aec2cf 13609 "ret"
6ef67412
JH
13610 [(set_attr "length" "1")
13611 (set_attr "length_immediate" "0")
13612 (set_attr "modrm" "0")])
5f3d14e3 13613
253c7a00
JH
13614;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13615;; instruction Athlon and K8 have.
13616
13617(define_insn "return_internal_long"
13618 [(return)
13619 (unspec [(const_int 0)] UNSPEC_REP)]
13620 "reload_completed"
13621 "rep {;} ret"
13622 [(set_attr "length" "1")
13623 (set_attr "length_immediate" "0")
13624 (set_attr "prefix_rep" "1")
13625 (set_attr "modrm" "0")])
13626
6cd96118
SC
13627(define_insn "return_pop_internal"
13628 [(return)
13629 (use (match_operand:SI 0 "const_int_operand" ""))]
13630 "reload_completed"
0f40f9f7 13631 "ret\t%0"
6ef67412
JH
13632 [(set_attr "length" "3")
13633 (set_attr "length_immediate" "2")
13634 (set_attr "modrm" "0")])
6cd96118 13635
11837777
RH
13636(define_insn "return_indirect_internal"
13637 [(return)
13638 (use (match_operand:SI 0 "register_operand" "r"))]
13639 "reload_completed"
0f40f9f7 13640 "jmp\t%A0"
11837777
RH
13641 [(set_attr "type" "ibr")
13642 (set_attr "length_immediate" "0")])
13643
5f3d14e3
SC
13644(define_insn "nop"
13645 [(const_int 0)]
13646 ""
90aec2cf 13647 "nop"
e075ae69 13648 [(set_attr "length" "1")
6ef67412 13649 (set_attr "length_immediate" "0")
56bab446 13650 (set_attr "modrm" "0")])
5f3d14e3 13651
9ccf9681
RH
13652;; Align to 16-byte boundary, max skip in op0. Used to avoid
13653;; branch prediction penalty for the third jump in a 16-byte
13654;; block on K8.
d2c49530
JH
13655
13656(define_insn "align"
13657 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13658 ""
13659{
9ccf9681 13660#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
6262f66a 13661 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
9ccf9681 13662#else
6262f66a
JH
13663 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13664 The align insn is used to avoid 3 jump instructions in the row to improve
13665 branch prediction and the benefits hardly outweight the cost of extra 8
13666 nops on the average inserted by full alignment pseudo operation. */
d2c49530 13667#endif
9ccf9681 13668 return "";
d2c49530
JH
13669}
13670 [(set_attr "length" "16")])
13671
5f3d14e3
SC
13672(define_expand "prologue"
13673 [(const_int 1)]
13674 ""
e075ae69 13675 "ix86_expand_prologue (); DONE;")
5f3d14e3 13676
bd09bdeb 13677(define_insn "set_got"
69404d6f 13678 [(set (match_operand:SI 0 "register_operand" "=r")
c8c03509 13679 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
8bc527af 13680 (clobber (reg:CC FLAGS_REG))]
1e07edd3 13681 "!TARGET_64BIT"
c8c03509
RH
13682 { return output_set_got (operands[0]); }
13683 [(set_attr "type" "multi")
13684 (set_attr "length" "12")])
5f3d14e3 13685
e075ae69
RH
13686(define_expand "epilogue"
13687 [(const_int 1)]
13688 ""
cbbf65e0
RH
13689 "ix86_expand_epilogue (1); DONE;")
13690
13691(define_expand "sibcall_epilogue"
13692 [(const_int 1)]
13693 ""
13694 "ix86_expand_epilogue (0); DONE;")
e075ae69 13695
1020a5ab 13696(define_expand "eh_return"
34dc173c 13697 [(use (match_operand 0 "register_operand" ""))]
1020a5ab 13698 ""
1020a5ab 13699{
34dc173c 13700 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
1020a5ab
RH
13701
13702 /* Tricky bit: we write the address of the handler to which we will
13703 be returning into someone else's stack frame, one word below the
13704 stack address we wish to restore. */
13705 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13706 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13707 tmp = gen_rtx_MEM (Pmode, tmp);
13708 emit_move_insn (tmp, ra);
13709
d5d6a58b 13710 if (Pmode == SImode)
2e2052b1 13711 emit_jump_insn (gen_eh_return_si (sa));
d5d6a58b 13712 else
2e2052b1 13713 emit_jump_insn (gen_eh_return_di (sa));
1020a5ab
RH
13714 emit_barrier ();
13715 DONE;
0f40f9f7 13716})
1020a5ab 13717
d5d6a58b 13718(define_insn_and_split "eh_return_si"
2e2052b1
JH
13719 [(set (pc)
13720 (unspec [(match_operand:SI 0 "register_operand" "c")]
13721 UNSPEC_EH_RETURN))]
1b0c37d7 13722 "!TARGET_64BIT"
d5d6a58b
RH
13723 "#"
13724 "reload_completed"
13725 [(const_int 1)]
13726 "ix86_expand_epilogue (2); DONE;")
13727
13728(define_insn_and_split "eh_return_di"
2e2052b1
JH
13729 [(set (pc)
13730 (unspec [(match_operand:DI 0 "register_operand" "c")]
13731 UNSPEC_EH_RETURN))]
1b0c37d7 13732 "TARGET_64BIT"
1020a5ab
RH
13733 "#"
13734 "reload_completed"
13735 [(const_int 1)]
13736 "ix86_expand_epilogue (2); DONE;")
13737
e075ae69 13738(define_insn "leave"
8bc527af
SB
13739 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13740 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
f2042df3 13741 (clobber (mem:BLK (scratch)))]
1e07edd3 13742 "!TARGET_64BIT"
e075ae69 13743 "leave"
4977bab6 13744 [(set_attr "type" "leave")])
8362f420
JH
13745
13746(define_insn "leave_rex64"
8bc527af
SB
13747 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13748 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
f2042df3 13749 (clobber (mem:BLK (scratch)))]
8362f420
JH
13750 "TARGET_64BIT"
13751 "leave"
4977bab6 13752 [(set_attr "type" "leave")])
e075ae69
RH
13753\f
13754(define_expand "ffssi2"
8acfdd43
RH
13755 [(parallel
13756 [(set (match_operand:SI 0 "register_operand" "")
13757 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13758 (clobber (match_scratch:SI 2 ""))
8bc527af 13759 (clobber (reg:CC FLAGS_REG))])]
e075ae69 13760 ""
8acfdd43 13761 "")
e075ae69 13762
8acfdd43
RH
13763(define_insn_and_split "*ffs_cmove"
13764 [(set (match_operand:SI 0 "register_operand" "=r")
13765 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13766 (clobber (match_scratch:SI 2 "=&r"))
8bc527af 13767 (clobber (reg:CC FLAGS_REG))]
8acfdd43
RH
13768 "TARGET_CMOVE"
13769 "#"
13770 "&& reload_completed"
13771 [(set (match_dup 2) (const_int -1))
8bc527af 13772 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
8acfdd43
RH
13773 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13774 (set (match_dup 0) (if_then_else:SI
8bc527af 13775 (eq (reg:CCZ FLAGS_REG) (const_int 0))
8acfdd43
RH
13776 (match_dup 2)
13777 (match_dup 0)))
13778 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8bc527af 13779 (clobber (reg:CC FLAGS_REG))])]
8acfdd43 13780 "")
e0dc26ff 13781
8acfdd43
RH
13782(define_insn_and_split "*ffs_no_cmove"
13783 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13784 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
fa543fdd 13785 (clobber (match_scratch:SI 2 "=&q"))
8bc527af 13786 (clobber (reg:CC FLAGS_REG))]
8acfdd43
RH
13787 ""
13788 "#"
13789 "reload_completed"
8bc527af 13790 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
8acfdd43
RH
13791 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13792 (set (strict_low_part (match_dup 3))
8bc527af 13793 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
8acfdd43 13794 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
8bc527af 13795 (clobber (reg:CC FLAGS_REG))])
8acfdd43 13796 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
8bc527af 13797 (clobber (reg:CC FLAGS_REG))])
8acfdd43 13798 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8bc527af 13799 (clobber (reg:CC FLAGS_REG))])]
8acfdd43
RH
13800{
13801 operands[3] = gen_lowpart (QImode, operands[2]);
707e58b1 13802 ix86_expand_clear (operands[2]);
0f40f9f7 13803})
886c62d1 13804
8acfdd43 13805(define_insn "*ffssi_1"
8bc527af 13806 [(set (reg:CCZ FLAGS_REG)
8acfdd43 13807 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
16189740 13808 (const_int 0)))
e075ae69 13809 (set (match_operand:SI 0 "register_operand" "=r")
8acfdd43
RH
13810 (ctz:SI (match_dup 1)))]
13811 ""
13812 "bsf{l}\t{%1, %0|%0, %1}"
56bab446 13813 [(set_attr "prefix_0f" "1")])
8acfdd43 13814
d413e3cc
JJ
13815(define_expand "ffsdi2"
13816 [(parallel
13817 [(set (match_operand:DI 0 "register_operand" "")
13818 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13819 (clobber (match_scratch:DI 2 ""))
42fabf21 13820 (clobber (reg:CC FLAGS_REG))])]
d413e3cc
JJ
13821 "TARGET_64BIT && TARGET_CMOVE"
13822 "")
13823
13824(define_insn_and_split "*ffs_rex64"
13825 [(set (match_operand:DI 0 "register_operand" "=r")
13826 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13827 (clobber (match_scratch:DI 2 "=&r"))
42fabf21 13828 (clobber (reg:CC FLAGS_REG))]
d413e3cc
JJ
13829 "TARGET_64BIT && TARGET_CMOVE"
13830 "#"
13831 "&& reload_completed"
13832 [(set (match_dup 2) (const_int -1))
42fabf21
RH
13833 (parallel [(set (reg:CCZ FLAGS_REG)
13834 (compare:CCZ (match_dup 1) (const_int 0)))
d413e3cc
JJ
13835 (set (match_dup 0) (ctz:DI (match_dup 1)))])
13836 (set (match_dup 0) (if_then_else:DI
42fabf21 13837 (eq (reg:CCZ FLAGS_REG) (const_int 0))
d413e3cc
JJ
13838 (match_dup 2)
13839 (match_dup 0)))
13840 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
42fabf21 13841 (clobber (reg:CC FLAGS_REG))])]
d413e3cc
JJ
13842 "")
13843
13844(define_insn "*ffsdi_1"
42fabf21 13845 [(set (reg:CCZ FLAGS_REG)
d413e3cc
JJ
13846 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13847 (const_int 0)))
13848 (set (match_operand:DI 0 "register_operand" "=r")
13849 (ctz:DI (match_dup 1)))]
13850 "TARGET_64BIT"
13851 "bsf{q}\t{%1, %0|%0, %1}"
13852 [(set_attr "prefix_0f" "1")])
13853
8acfdd43
RH
13854(define_insn "ctzsi2"
13855 [(set (match_operand:SI 0 "register_operand" "=r")
13856 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
8bc527af 13857 (clobber (reg:CC FLAGS_REG))]
e075ae69 13858 ""
0f40f9f7 13859 "bsf{l}\t{%1, %0|%0, %1}"
56bab446 13860 [(set_attr "prefix_0f" "1")])
e075ae69 13861
d413e3cc
JJ
13862(define_insn "ctzdi2"
13863 [(set (match_operand:DI 0 "register_operand" "=r")
13864 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
42fabf21 13865 (clobber (reg:CC FLAGS_REG))]
d413e3cc
JJ
13866 "TARGET_64BIT"
13867 "bsf{q}\t{%1, %0|%0, %1}"
13868 [(set_attr "prefix_0f" "1")])
13869
8acfdd43
RH
13870(define_expand "clzsi2"
13871 [(parallel
13872 [(set (match_operand:SI 0 "register_operand" "")
13873 (minus:SI (const_int 31)
13874 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
8bc527af 13875 (clobber (reg:CC FLAGS_REG))])
8acfdd43
RH
13876 (parallel
13877 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
8bc527af 13878 (clobber (reg:CC FLAGS_REG))])]
8acfdd43
RH
13879 ""
13880 "")
13881
13882(define_insn "*bsr"
13883 [(set (match_operand:SI 0 "register_operand" "=r")
13884 (minus:SI (const_int 31)
13885 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
8bc527af 13886 (clobber (reg:CC FLAGS_REG))]
8acfdd43
RH
13887 ""
13888 "bsr{l}\t{%1, %0|%0, %1}"
56bab446 13889 [(set_attr "prefix_0f" "1")])
d413e3cc
JJ
13890
13891(define_expand "clzdi2"
13892 [(parallel
13893 [(set (match_operand:DI 0 "register_operand" "")
13894 (minus:DI (const_int 63)
13895 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
42fabf21 13896 (clobber (reg:CC FLAGS_REG))])
d413e3cc
JJ
13897 (parallel
13898 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
42fabf21 13899 (clobber (reg:CC FLAGS_REG))])]
d413e3cc
JJ
13900 "TARGET_64BIT"
13901 "")
13902
13903(define_insn "*bsr_rex64"
13904 [(set (match_operand:DI 0 "register_operand" "=r")
13905 (minus:DI (const_int 63)
13906 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
42fabf21 13907 (clobber (reg:CC FLAGS_REG))]
d413e3cc
JJ
13908 "TARGET_64BIT"
13909 "bsr{q}\t{%1, %0|%0, %1}"
13910 [(set_attr "prefix_0f" "1")])
e075ae69 13911\f
f996902d
RH
13912;; Thread-local storage patterns for ELF.
13913;;
13914;; Note that these code sequences must appear exactly as shown
13915;; in order to allow linker relaxation.
13916
75d38379 13917(define_insn "*tls_global_dynamic_32_gnu"
f996902d
RH
13918 [(set (match_operand:SI 0 "register_operand" "=a")
13919 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13920 (match_operand:SI 2 "tls_symbolic_operand" "")
13921 (match_operand:SI 3 "call_insn_operand" "")]
13922 UNSPEC_TLS_GD))
13923 (clobber (match_scratch:SI 4 "=d"))
13924 (clobber (match_scratch:SI 5 "=c"))
8bc527af 13925 (clobber (reg:CC FLAGS_REG))]
75d38379 13926 "!TARGET_64BIT && TARGET_GNU_TLS"
f996902d
RH
13927 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13928 [(set_attr "type" "multi")
13929 (set_attr "length" "12")])
13930
75d38379 13931(define_insn "*tls_global_dynamic_32_sun"
f996902d
RH
13932 [(set (match_operand:SI 0 "register_operand" "=a")
13933 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13934 (match_operand:SI 2 "tls_symbolic_operand" "")
13935 (match_operand:SI 3 "call_insn_operand" "")]
13936 UNSPEC_TLS_GD))
13937 (clobber (match_scratch:SI 4 "=d"))
13938 (clobber (match_scratch:SI 5 "=c"))
8bc527af 13939 (clobber (reg:CC FLAGS_REG))]
75d38379 13940 "!TARGET_64BIT && TARGET_SUN_TLS"
f996902d
RH
13941 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13942 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13943 [(set_attr "type" "multi")
13944 (set_attr "length" "14")])
13945
75d38379 13946(define_expand "tls_global_dynamic_32"
f996902d
RH
13947 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13948 (unspec:SI
13949 [(match_dup 2)
13950 (match_operand:SI 1 "tls_symbolic_operand" "")
13951 (match_dup 3)]
13952 UNSPEC_TLS_GD))
13953 (clobber (match_scratch:SI 4 ""))
13954 (clobber (match_scratch:SI 5 ""))
8bc527af 13955 (clobber (reg:CC FLAGS_REG))])]
f996902d
RH
13956 ""
13957{
dce81a1a
JJ
13958 if (flag_pic)
13959 operands[2] = pic_offset_table_rtx;
13960 else
13961 {
13962 operands[2] = gen_reg_rtx (Pmode);
13963 emit_insn (gen_set_got (operands[2]));
13964 }
f996902d
RH
13965 operands[3] = ix86_tls_get_addr ();
13966})
13967
75d38379
JJ
13968(define_insn "*tls_global_dynamic_64"
13969 [(set (match_operand:DI 0 "register_operand" "=a")
13970 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13971 (match_operand:DI 3 "" "")))
13972 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13973 UNSPEC_TLS_GD)]
13974 "TARGET_64BIT"
13975 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13976 [(set_attr "type" "multi")
13977 (set_attr "length" "16")])
13978
13979(define_expand "tls_global_dynamic_64"
13980 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13981 (call (mem:QI (match_dup 2)) (const_int 0)))
13982 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13983 UNSPEC_TLS_GD)])]
13984 ""
13985{
13986 operands[2] = ix86_tls_get_addr ();
13987})
13988
13989(define_insn "*tls_local_dynamic_base_32_gnu"
f996902d
RH
13990 [(set (match_operand:SI 0 "register_operand" "=a")
13991 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13992 (match_operand:SI 2 "call_insn_operand" "")]
13993 UNSPEC_TLS_LD_BASE))
13994 (clobber (match_scratch:SI 3 "=d"))
13995 (clobber (match_scratch:SI 4 "=c"))
8bc527af 13996 (clobber (reg:CC FLAGS_REG))]
75d38379 13997 "!TARGET_64BIT && TARGET_GNU_TLS"
f996902d
RH
13998 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13999 [(set_attr "type" "multi")
14000 (set_attr "length" "11")])
14001
75d38379 14002(define_insn "*tls_local_dynamic_base_32_sun"
f996902d
RH
14003 [(set (match_operand:SI 0 "register_operand" "=a")
14004 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14005 (match_operand:SI 2 "call_insn_operand" "")]
14006 UNSPEC_TLS_LD_BASE))
14007 (clobber (match_scratch:SI 3 "=d"))
14008 (clobber (match_scratch:SI 4 "=c"))
8bc527af 14009 (clobber (reg:CC FLAGS_REG))]
75d38379 14010 "!TARGET_64BIT && TARGET_SUN_TLS"
f996902d
RH
14011 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14012 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14013 [(set_attr "type" "multi")
14014 (set_attr "length" "13")])
14015
75d38379 14016(define_expand "tls_local_dynamic_base_32"
f996902d
RH
14017 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14018 (unspec:SI [(match_dup 1) (match_dup 2)]
14019 UNSPEC_TLS_LD_BASE))
14020 (clobber (match_scratch:SI 3 ""))
14021 (clobber (match_scratch:SI 4 ""))
8bc527af 14022 (clobber (reg:CC FLAGS_REG))])]
f996902d
RH
14023 ""
14024{
dce81a1a 14025 if (flag_pic)
9785f1d9 14026 operands[1] = pic_offset_table_rtx;
dce81a1a
JJ
14027 else
14028 {
9785f1d9
JJ
14029 operands[1] = gen_reg_rtx (Pmode);
14030 emit_insn (gen_set_got (operands[1]));
dce81a1a 14031 }
f996902d
RH
14032 operands[2] = ix86_tls_get_addr ();
14033})
14034
75d38379
JJ
14035(define_insn "*tls_local_dynamic_base_64"
14036 [(set (match_operand:DI 0 "register_operand" "=a")
14037 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14038 (match_operand:DI 2 "" "")))
14039 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14040 "TARGET_64BIT"
14041 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14042 [(set_attr "type" "multi")
14043 (set_attr "length" "12")])
14044
14045(define_expand "tls_local_dynamic_base_64"
14046 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14047 (call (mem:QI (match_dup 1)) (const_int 0)))
14048 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14049 ""
14050{
14051 operands[1] = ix86_tls_get_addr ();
14052})
14053
f996902d
RH
14054;; Local dynamic of a single variable is a lose. Show combine how
14055;; to convert that back to global dynamic.
14056
75d38379 14057(define_insn_and_split "*tls_local_dynamic_32_once"
f996902d
RH
14058 [(set (match_operand:SI 0 "register_operand" "=a")
14059 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14060 (match_operand:SI 2 "call_insn_operand" "")]
14061 UNSPEC_TLS_LD_BASE)
14062 (const:SI (unspec:SI
14063 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14064 UNSPEC_DTPOFF))))
14065 (clobber (match_scratch:SI 4 "=d"))
14066 (clobber (match_scratch:SI 5 "=c"))
8bc527af 14067 (clobber (reg:CC FLAGS_REG))]
f996902d
RH
14068 ""
14069 "#"
14070 ""
14071 [(parallel [(set (match_dup 0)
14072 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14073 UNSPEC_TLS_GD))
14074 (clobber (match_dup 4))
14075 (clobber (match_dup 5))
8bc527af 14076 (clobber (reg:CC FLAGS_REG))])]
f996902d 14077 "")
74dc3e94
RH
14078
14079;; Load and add the thread base pointer from %gs:0.
14080
14081(define_insn "*load_tp_si"
14082 [(set (match_operand:SI 0 "register_operand" "=r")
14083 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14084 "!TARGET_64BIT"
14085 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14086 [(set_attr "type" "imov")
14087 (set_attr "modrm" "0")
14088 (set_attr "length" "7")
14089 (set_attr "memory" "load")
14090 (set_attr "imm_disp" "false")])
14091
14092(define_insn "*add_tp_si"
14093 [(set (match_operand:SI 0 "register_operand" "=r")
14094 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14095 (match_operand:SI 1 "register_operand" "0")))
8bc527af 14096 (clobber (reg:CC FLAGS_REG))]
74dc3e94
RH
14097 "!TARGET_64BIT"
14098 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14099 [(set_attr "type" "alu")
14100 (set_attr "modrm" "0")
14101 (set_attr "length" "7")
14102 (set_attr "memory" "load")
14103 (set_attr "imm_disp" "false")])
14104
14105(define_insn "*load_tp_di"
14106 [(set (match_operand:DI 0 "register_operand" "=r")
14107 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14108 "TARGET_64BIT"
965514bd 14109 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
74dc3e94
RH
14110 [(set_attr "type" "imov")
14111 (set_attr "modrm" "0")
14112 (set_attr "length" "7")
14113 (set_attr "memory" "load")
14114 (set_attr "imm_disp" "false")])
14115
14116(define_insn "*add_tp_di"
14117 [(set (match_operand:DI 0 "register_operand" "=r")
14118 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14119 (match_operand:DI 1 "register_operand" "0")))
8bc527af 14120 (clobber (reg:CC FLAGS_REG))]
74dc3e94
RH
14121 "TARGET_64BIT"
14122 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14123 [(set_attr "type" "alu")
14124 (set_attr "modrm" "0")
14125 (set_attr "length" "7")
14126 (set_attr "memory" "load")
14127 (set_attr "imm_disp" "false")])
f996902d 14128\f
e075ae69
RH
14129;; These patterns match the binary 387 instructions for addM3, subM3,
14130;; mulM3 and divM3. There are three patterns for each of DFmode and
14131;; SFmode. The first is the normal insn, the second the same insn but
14132;; with one operand a conversion, and the third the same insn but with
14133;; the other operand a conversion. The conversion may be SFmode or
14134;; SImode if the target mode DFmode, but only SImode if the target mode
14135;; is SFmode.
14136
caa6ec8d
JH
14137;; Gcc is slightly more smart about handling normal two address instructions
14138;; so use special patterns for add and mull.
965f5423
JH
14139(define_insn "*fop_sf_comm_nosse"
14140 [(set (match_operand:SF 0 "register_operand" "=f")
14141 (match_operator:SF 3 "binary_fp_operator"
aebfea10 14142 [(match_operand:SF 1 "nonimmediate_operand" "%0")
965f5423
JH
14143 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14144 "TARGET_80387 && !TARGET_SSE_MATH
ec8e098d 14145 && COMMUTATIVE_ARITH_P (operands[3])
aebfea10 14146 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
965f5423
JH
14147 "* return output_387_binary_op (insn, operands);"
14148 [(set (attr "type")
14149 (if_then_else (match_operand:SF 3 "mult_operator" "")
14150 (const_string "fmul")
14151 (const_string "fop")))
14152 (set_attr "mode" "SF")])
14153
caa6ec8d 14154(define_insn "*fop_sf_comm"
1deaa899 14155 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
caa6ec8d 14156 (match_operator:SF 3 "binary_fp_operator"
aebfea10 14157 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
1deaa899 14158 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
965f5423 14159 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
ec8e098d 14160 && COMMUTATIVE_ARITH_P (operands[3])
aebfea10 14161 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
caa6ec8d
JH
14162 "* return output_387_binary_op (insn, operands);"
14163 [(set (attr "type")
1deaa899 14164 (if_then_else (eq_attr "alternative" "1")
3d34cd91
JH
14165 (if_then_else (match_operand:SF 3 "mult_operator" "")
14166 (const_string "ssemul")
14167 (const_string "sseadd"))
1deaa899
JH
14168 (if_then_else (match_operand:SF 3 "mult_operator" "")
14169 (const_string "fmul")
14170 (const_string "fop"))))
14171 (set_attr "mode" "SF")])
14172
14173(define_insn "*fop_sf_comm_sse"
14174 [(set (match_operand:SF 0 "register_operand" "=x")
14175 (match_operator:SF 3 "binary_fp_operator"
aebfea10 14176 [(match_operand:SF 1 "nonimmediate_operand" "%0")
1deaa899 14177 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
ec8e098d 14178 "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
aebfea10 14179 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1deaa899 14180 "* return output_387_binary_op (insn, operands);"
3d34cd91
JH
14181 [(set (attr "type")
14182 (if_then_else (match_operand:SF 3 "mult_operator" "")
14183 (const_string "ssemul")
14184 (const_string "sseadd")))
6ef67412 14185 (set_attr "mode" "SF")])
caa6ec8d 14186
965f5423
JH
14187(define_insn "*fop_df_comm_nosse"
14188 [(set (match_operand:DF 0 "register_operand" "=f")
14189 (match_operator:DF 3 "binary_fp_operator"
aebfea10 14190 [(match_operand:DF 1 "nonimmediate_operand" "%0")
965f5423
JH
14191 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14192 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
ec8e098d 14193 && COMMUTATIVE_ARITH_P (operands[3])
aebfea10 14194 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
965f5423
JH
14195 "* return output_387_binary_op (insn, operands);"
14196 [(set (attr "type")
14197 (if_then_else (match_operand:SF 3 "mult_operator" "")
14198 (const_string "fmul")
14199 (const_string "fop")))
14200 (set_attr "mode" "DF")])
14201
caa6ec8d 14202(define_insn "*fop_df_comm"
1deaa899 14203 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
caa6ec8d 14204 (match_operator:DF 3 "binary_fp_operator"
aebfea10 14205 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
1deaa899 14206 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
965f5423 14207 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
ec8e098d 14208 && COMMUTATIVE_ARITH_P (operands[3])
aebfea10 14209 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
caa6ec8d
JH
14210 "* return output_387_binary_op (insn, operands);"
14211 [(set (attr "type")
1deaa899 14212 (if_then_else (eq_attr "alternative" "1")
3d34cd91
JH
14213 (if_then_else (match_operand:SF 3 "mult_operator" "")
14214 (const_string "ssemul")
14215 (const_string "sseadd"))
1deaa899
JH
14216 (if_then_else (match_operand:SF 3 "mult_operator" "")
14217 (const_string "fmul")
14218 (const_string "fop"))))
14219 (set_attr "mode" "DF")])
14220
14221(define_insn "*fop_df_comm_sse"
14222 [(set (match_operand:DF 0 "register_operand" "=Y")
14223 (match_operator:DF 3 "binary_fp_operator"
aebfea10 14224 [(match_operand:DF 1 "nonimmediate_operand" "%0")
1deaa899 14225 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
965f5423 14226 "TARGET_SSE2 && TARGET_SSE_MATH
ec8e098d 14227 && COMMUTATIVE_ARITH_P (operands[3])
aebfea10 14228 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1deaa899 14229 "* return output_387_binary_op (insn, operands);"
3d34cd91
JH
14230 [(set (attr "type")
14231 (if_then_else (match_operand:SF 3 "mult_operator" "")
14232 (const_string "ssemul")
14233 (const_string "sseadd")))
6ef67412 14234 (set_attr "mode" "DF")])
caa6ec8d
JH
14235
14236(define_insn "*fop_xf_comm"
14237 [(set (match_operand:XF 0 "register_operand" "=f")
14238 (match_operator:XF 3 "binary_fp_operator"
14239 [(match_operand:XF 1 "register_operand" "%0")
14240 (match_operand:XF 2 "register_operand" "f")]))]
f8a1ebc6 14241 "TARGET_80387
ec8e098d 14242 && COMMUTATIVE_ARITH_P (operands[3])"
caa6ec8d
JH
14243 "* return output_387_binary_op (insn, operands);"
14244 [(set (attr "type")
14245 (if_then_else (match_operand:XF 3 "mult_operator" "")
14246 (const_string "fmul")
6ef67412
JH
14247 (const_string "fop")))
14248 (set_attr "mode" "XF")])
caa6ec8d 14249
965f5423
JH
14250(define_insn "*fop_sf_1_nosse"
14251 [(set (match_operand:SF 0 "register_operand" "=f,f")
14252 (match_operator:SF 3 "binary_fp_operator"
14253 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14254 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14255 "TARGET_80387 && !TARGET_SSE_MATH
ec8e098d 14256 && !COMMUTATIVE_ARITH_P (operands[3])
965f5423
JH
14257 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14258 "* return output_387_binary_op (insn, operands);"
14259 [(set (attr "type")
14260 (cond [(match_operand:SF 3 "mult_operator" "")
14261 (const_string "fmul")
14262 (match_operand:SF 3 "div_operator" "")
14263 (const_string "fdiv")
14264 ]
14265 (const_string "fop")))
14266 (set_attr "mode" "SF")])
14267
e075ae69 14268(define_insn "*fop_sf_1"
1deaa899 14269 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
e075ae69 14270 (match_operator:SF 3 "binary_fp_operator"
1deaa899
JH
14271 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14272 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
965f5423 14273 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
ec8e098d 14274 && !COMMUTATIVE_ARITH_P (operands[3])
f97d9ec3 14275 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
14276 "* return output_387_binary_op (insn, operands);"
14277 [(set (attr "type")
3d34cd91
JH
14278 (cond [(and (eq_attr "alternative" "2")
14279 (match_operand:SF 3 "mult_operator" ""))
14280 (const_string "ssemul")
14281 (and (eq_attr "alternative" "2")
14282 (match_operand:SF 3 "div_operator" ""))
14283 (const_string "ssediv")
14284 (eq_attr "alternative" "2")
14285 (const_string "sseadd")
1deaa899 14286 (match_operand:SF 3 "mult_operator" "")
e075ae69
RH
14287 (const_string "fmul")
14288 (match_operand:SF 3 "div_operator" "")
14289 (const_string "fdiv")
14290 ]
6ef67412
JH
14291 (const_string "fop")))
14292 (set_attr "mode" "SF")])
e075ae69 14293
1deaa899
JH
14294(define_insn "*fop_sf_1_sse"
14295 [(set (match_operand:SF 0 "register_operand" "=x")
14296 (match_operator:SF 3 "binary_fp_operator"
14297 [(match_operand:SF 1 "register_operand" "0")
14298 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
965f5423 14299 "TARGET_SSE_MATH
ec8e098d 14300 && !COMMUTATIVE_ARITH_P (operands[3])"
1deaa899 14301 "* return output_387_binary_op (insn, operands);"
3d34cd91
JH
14302 [(set (attr "type")
14303 (cond [(match_operand:SF 3 "mult_operator" "")
14304 (const_string "ssemul")
14305 (match_operand:SF 3 "div_operator" "")
14306 (const_string "ssediv")
14307 ]
14308 (const_string "sseadd")))
1deaa899
JH
14309 (set_attr "mode" "SF")])
14310
14311;; ??? Add SSE splitters for these!
e075ae69
RH
14312(define_insn "*fop_sf_2"
14313 [(set (match_operand:SF 0 "register_operand" "=f,f")
14314 (match_operator:SF 3 "binary_fp_operator"
14315 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14316 (match_operand:SF 2 "register_operand" "0,0")]))]
965f5423 14317 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
e075ae69
RH
14318 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14319 [(set (attr "type")
14320 (cond [(match_operand:SF 3 "mult_operator" "")
14321 (const_string "fmul")
14322 (match_operand:SF 3 "div_operator" "")
14323 (const_string "fdiv")
14324 ]
14325 (const_string "fop")))
14326 (set_attr "fp_int_src" "true")
6ef67412 14327 (set_attr "mode" "SI")])
e075ae69
RH
14328
14329(define_insn "*fop_sf_3"
14330 [(set (match_operand:SF 0 "register_operand" "=f,f")
14331 (match_operator:SF 3 "binary_fp_operator"
14332 [(match_operand:SF 1 "register_operand" "0,0")
14333 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
965f5423 14334 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
e075ae69
RH
14335 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14336 [(set (attr "type")
14337 (cond [(match_operand:SF 3 "mult_operator" "")
14338 (const_string "fmul")
14339 (match_operand:SF 3 "div_operator" "")
14340 (const_string "fdiv")
14341 ]
14342 (const_string "fop")))
14343 (set_attr "fp_int_src" "true")
6ef67412 14344 (set_attr "mode" "SI")])
e075ae69 14345
965f5423
JH
14346(define_insn "*fop_df_1_nosse"
14347 [(set (match_operand:DF 0 "register_operand" "=f,f")
14348 (match_operator:DF 3 "binary_fp_operator"
14349 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14350 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14351 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
ec8e098d 14352 && !COMMUTATIVE_ARITH_P (operands[3])
965f5423
JH
14353 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14354 "* return output_387_binary_op (insn, operands);"
14355 [(set (attr "type")
14356 (cond [(match_operand:DF 3 "mult_operator" "")
14357 (const_string "fmul")
3d34cd91 14358 (match_operand:DF 3 "div_operator" "")
965f5423
JH
14359 (const_string "fdiv")
14360 ]
14361 (const_string "fop")))
14362 (set_attr "mode" "DF")])
14363
14364
e075ae69 14365(define_insn "*fop_df_1"
1deaa899 14366 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
e075ae69 14367 (match_operator:DF 3 "binary_fp_operator"
1deaa899
JH
14368 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14369 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
965f5423 14370 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
ec8e098d 14371 && !COMMUTATIVE_ARITH_P (operands[3])
f97d9ec3 14372 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
14373 "* return output_387_binary_op (insn, operands);"
14374 [(set (attr "type")
3d34cd91
JH
14375 (cond [(and (eq_attr "alternative" "2")
14376 (match_operand:SF 3 "mult_operator" ""))
14377 (const_string "ssemul")
14378 (and (eq_attr "alternative" "2")
14379 (match_operand:SF 3 "div_operator" ""))
14380 (const_string "ssediv")
14381 (eq_attr "alternative" "2")
14382 (const_string "sseadd")
1deaa899 14383 (match_operand:DF 3 "mult_operator" "")
e075ae69
RH
14384 (const_string "fmul")
14385 (match_operand:DF 3 "div_operator" "")
14386 (const_string "fdiv")
14387 ]
6ef67412
JH
14388 (const_string "fop")))
14389 (set_attr "mode" "DF")])
e075ae69 14390
1deaa899
JH
14391(define_insn "*fop_df_1_sse"
14392 [(set (match_operand:DF 0 "register_operand" "=Y")
14393 (match_operator:DF 3 "binary_fp_operator"
14394 [(match_operand:DF 1 "register_operand" "0")
14395 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
965f5423 14396 "TARGET_SSE2 && TARGET_SSE_MATH
ec8e098d 14397 && !COMMUTATIVE_ARITH_P (operands[3])"
1deaa899 14398 "* return output_387_binary_op (insn, operands);"
3d34cd91
JH
14399 [(set_attr "mode" "DF")
14400 (set (attr "type")
14401 (cond [(match_operand:SF 3 "mult_operator" "")
14402 (const_string "ssemul")
14403 (match_operand:SF 3 "div_operator" "")
14404 (const_string "ssediv")
14405 ]
14406 (const_string "sseadd")))])
1deaa899
JH
14407
14408;; ??? Add SSE splitters for these!
e075ae69
RH
14409(define_insn "*fop_df_2"
14410 [(set (match_operand:DF 0 "register_operand" "=f,f")
14411 (match_operator:DF 3 "binary_fp_operator"
14412 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14413 (match_operand:DF 2 "register_operand" "0,0")]))]
965f5423 14414 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
e075ae69
RH
14415 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14416 [(set (attr "type")
14417 (cond [(match_operand:DF 3 "mult_operator" "")
14418 (const_string "fmul")
14419 (match_operand:DF 3 "div_operator" "")
14420 (const_string "fdiv")
14421 ]
14422 (const_string "fop")))
14423 (set_attr "fp_int_src" "true")
6ef67412 14424 (set_attr "mode" "SI")])
e075ae69
RH
14425
14426(define_insn "*fop_df_3"
14427 [(set (match_operand:DF 0 "register_operand" "=f,f")
14428 (match_operator:DF 3 "binary_fp_operator"
14429 [(match_operand:DF 1 "register_operand" "0,0")
14430 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
965f5423 14431 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
e075ae69
RH
14432 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14433 [(set (attr "type")
14434 (cond [(match_operand:DF 3 "mult_operator" "")
14435 (const_string "fmul")
14436 (match_operand:DF 3 "div_operator" "")
14437 (const_string "fdiv")
14438 ]
14439 (const_string "fop")))
14440 (set_attr "fp_int_src" "true")
6ef67412 14441 (set_attr "mode" "SI")])
e075ae69
RH
14442
14443(define_insn "*fop_df_4"
14444 [(set (match_operand:DF 0 "register_operand" "=f,f")
14445 (match_operator:DF 3 "binary_fp_operator"
14446 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14447 (match_operand:DF 2 "register_operand" "0,f")]))]
3987b9db 14448 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
f97d9ec3 14449 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
14450 "* return output_387_binary_op (insn, operands);"
14451 [(set (attr "type")
14452 (cond [(match_operand:DF 3 "mult_operator" "")
14453 (const_string "fmul")
14454 (match_operand:DF 3 "div_operator" "")
14455 (const_string "fdiv")
14456 ]
6ef67412
JH
14457 (const_string "fop")))
14458 (set_attr "mode" "SF")])
e075ae69
RH
14459
14460(define_insn "*fop_df_5"
14461 [(set (match_operand:DF 0 "register_operand" "=f,f")
14462 (match_operator:DF 3 "binary_fp_operator"
14463 [(match_operand:DF 1 "register_operand" "0,f")
14464 (float_extend:DF
14465 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
965f5423 14466 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
e075ae69
RH
14467 "* return output_387_binary_op (insn, operands);"
14468 [(set (attr "type")
14469 (cond [(match_operand:DF 3 "mult_operator" "")
14470 (const_string "fmul")
14471 (match_operand:DF 3 "div_operator" "")
14472 (const_string "fdiv")
14473 ]
6ef67412
JH
14474 (const_string "fop")))
14475 (set_attr "mode" "SF")])
e075ae69 14476
4977bab6
ZW
14477(define_insn "*fop_df_6"
14478 [(set (match_operand:DF 0 "register_operand" "=f,f")
14479 (match_operator:DF 3 "binary_fp_operator"
14480 [(float_extend:DF
14481 (match_operand:SF 1 "register_operand" "0,f"))
14482 (float_extend:DF
14483 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14484 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14485 "* return output_387_binary_op (insn, operands);"
14486 [(set (attr "type")
14487 (cond [(match_operand:DF 3 "mult_operator" "")
14488 (const_string "fmul")
14489 (match_operand:DF 3 "div_operator" "")
14490 (const_string "fdiv")
14491 ]
14492 (const_string "fop")))
14493 (set_attr "mode" "SF")])
14494
e075ae69
RH
14495(define_insn "*fop_xf_1"
14496 [(set (match_operand:XF 0 "register_operand" "=f,f")
14497 (match_operator:XF 3 "binary_fp_operator"
14498 [(match_operand:XF 1 "register_operand" "0,f")
14499 (match_operand:XF 2 "register_operand" "f,0")]))]
f8a1ebc6 14500 "TARGET_80387
ec8e098d 14501 && !COMMUTATIVE_ARITH_P (operands[3])"
e075ae69
RH
14502 "* return output_387_binary_op (insn, operands);"
14503 [(set (attr "type")
ca285e07 14504 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14505 (const_string "fmul")
ca285e07 14506 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14507 (const_string "fdiv")
14508 ]
6ef67412
JH
14509 (const_string "fop")))
14510 (set_attr "mode" "XF")])
e075ae69
RH
14511
14512(define_insn "*fop_xf_2"
14513 [(set (match_operand:XF 0 "register_operand" "=f,f")
14514 (match_operator:XF 3 "binary_fp_operator"
14515 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14516 (match_operand:XF 2 "register_operand" "0,0")]))]
2b589241
JH
14517 "TARGET_80387 && TARGET_USE_FIOP"
14518 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14519 [(set (attr "type")
f8a1ebc6 14520 (cond [(match_operand:XF 3 "mult_operator" "")
2b589241 14521 (const_string "fmul")
f8a1ebc6 14522 (match_operand:XF 3 "div_operator" "")
2b589241
JH
14523 (const_string "fdiv")
14524 ]
14525 (const_string "fop")))
14526 (set_attr "fp_int_src" "true")
56bab446 14527 (set_attr "mode" "SI")])
2b589241 14528
e075ae69
RH
14529(define_insn "*fop_xf_3"
14530 [(set (match_operand:XF 0 "register_operand" "=f,f")
14531 (match_operator:XF 3 "binary_fp_operator"
14532 [(match_operand:XF 1 "register_operand" "0,0")
14533 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
f8a1ebc6 14534 "TARGET_80387 && TARGET_USE_FIOP"
e075ae69
RH
14535 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14536 [(set (attr "type")
ca285e07 14537 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14538 (const_string "fmul")
ca285e07 14539 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14540 (const_string "fdiv")
14541 ]
14542 (const_string "fop")))
14543 (set_attr "fp_int_src" "true")
56bab446 14544 (set_attr "mode" "SI")])
e075ae69
RH
14545
14546(define_insn "*fop_xf_4"
14547 [(set (match_operand:XF 0 "register_operand" "=f,f")
14548 (match_operator:XF 3 "binary_fp_operator"
4977bab6 14549 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
e075ae69 14550 (match_operand:XF 2 "register_operand" "0,f")]))]
f8a1ebc6 14551 "TARGET_80387"
e075ae69
RH
14552 "* return output_387_binary_op (insn, operands);"
14553 [(set (attr "type")
ca285e07 14554 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14555 (const_string "fmul")
ca285e07 14556 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14557 (const_string "fdiv")
14558 ]
6ef67412
JH
14559 (const_string "fop")))
14560 (set_attr "mode" "SF")])
e075ae69
RH
14561
14562(define_insn "*fop_xf_5"
14563 [(set (match_operand:XF 0 "register_operand" "=f,f")
14564 (match_operator:XF 3 "binary_fp_operator"
14565 [(match_operand:XF 1 "register_operand" "0,f")
14566 (float_extend:XF
4977bab6 14567 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
f8a1ebc6 14568 "TARGET_80387"
e075ae69
RH
14569 "* return output_387_binary_op (insn, operands);"
14570 [(set (attr "type")
ca285e07 14571 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14572 (const_string "fmul")
ca285e07 14573 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14574 (const_string "fdiv")
14575 ]
6ef67412
JH
14576 (const_string "fop")))
14577 (set_attr "mode" "SF")])
e075ae69
RH
14578
14579(define_insn "*fop_xf_6"
14580 [(set (match_operand:XF 0 "register_operand" "=f,f")
14581 (match_operator:XF 3 "binary_fp_operator"
4977bab6
ZW
14582 [(float_extend:XF
14583 (match_operand 1 "register_operand" "0,f"))
e075ae69 14584 (float_extend:XF
4977bab6 14585 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
f8a1ebc6 14586 "TARGET_80387"
e075ae69
RH
14587 "* return output_387_binary_op (insn, operands);"
14588 [(set (attr "type")
ca285e07 14589 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14590 (const_string "fmul")
ca285e07 14591 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14592 (const_string "fdiv")
14593 ]
6ef67412 14594 (const_string "fop")))
4977bab6 14595 (set_attr "mode" "SF")])
e075ae69
RH
14596
14597(define_split
14598 [(set (match_operand 0 "register_operand" "")
14599 (match_operator 3 "binary_fp_operator"
14600 [(float (match_operand:SI 1 "register_operand" ""))
14601 (match_operand 2 "register_operand" "")]))]
14602 "TARGET_80387 && reload_completed
14603 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211a8fb 14604 [(const_int 0)]
4211a8fb
JH
14605{
14606 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14607 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14608 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14609 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14610 GET_MODE (operands[3]),
14611 operands[4],
14612 operands[2])));
14613 ix86_free_from_memory (GET_MODE (operands[1]));
14614 DONE;
0f40f9f7 14615})
e075ae69
RH
14616
14617(define_split
14618 [(set (match_operand 0 "register_operand" "")
14619 (match_operator 3 "binary_fp_operator"
14620 [(match_operand 1 "register_operand" "")
14621 (float (match_operand:SI 2 "register_operand" ""))]))]
14622 "TARGET_80387 && reload_completed
14623 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211a8fb 14624 [(const_int 0)]
4211a8fb
JH
14625{
14626 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14627 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14628 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2b66da3c 14629 gen_rtx_fmt_ee (GET_CODE (operands[3]),
4211a8fb
JH
14630 GET_MODE (operands[3]),
14631 operands[1],
14632 operands[4])));
14633 ix86_free_from_memory (GET_MODE (operands[2]));
14634 DONE;
0f40f9f7 14635})
e075ae69
RH
14636\f
14637;; FPU special functions.
14638
a8083431
JH
14639(define_expand "sqrtsf2"
14640 [(set (match_operand:SF 0 "register_operand" "")
14641 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
ba2baa55 14642 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
a8083431 14643{
abf80f8f 14644 if (!TARGET_SSE_MATH)
a8083431 14645 operands[1] = force_reg (SFmode, operands[1]);
0f40f9f7 14646})
a8083431
JH
14647
14648(define_insn "sqrtsf2_1"
ca9a9b12
JH
14649 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14650 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
ba2baa55 14651 "TARGET_USE_FANCY_MATH_387
abf80f8f 14652 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
a8083431
JH
14653 "@
14654 fsqrt
0f40f9f7 14655 sqrtss\t{%1, %0|%0, %1}"
a8083431
JH
14656 [(set_attr "type" "fpspc,sse")
14657 (set_attr "mode" "SF,SF")
14658 (set_attr "athlon_decode" "direct,*")])
14659
14660(define_insn "sqrtsf2_1_sse_only"
ca9a9b12
JH
14661 [(set (match_operand:SF 0 "register_operand" "=x")
14662 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
abf80f8f 14663 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
0f40f9f7 14664 "sqrtss\t{%1, %0|%0, %1}"
a8083431
JH
14665 [(set_attr "type" "sse")
14666 (set_attr "mode" "SF")
14667 (set_attr "athlon_decode" "*")])
14668
14669(define_insn "sqrtsf2_i387"
e075ae69
RH
14670 [(set (match_operand:SF 0 "register_operand" "=f")
14671 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
ba2baa55 14672 "TARGET_USE_FANCY_MATH_387
abf80f8f 14673 && !TARGET_SSE_MATH"
e075ae69 14674 "fsqrt"
0b5107cf 14675 [(set_attr "type" "fpspc")
6ef67412 14676 (set_attr "mode" "SF")
0b5107cf 14677 (set_attr "athlon_decode" "direct")])
e075ae69 14678
a8083431
JH
14679(define_expand "sqrtdf2"
14680 [(set (match_operand:DF 0 "register_operand" "")
14681 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
ba2baa55 14682 "TARGET_USE_FANCY_MATH_387
965f5423 14683 || (TARGET_SSE2 && TARGET_SSE_MATH)"
a8083431 14684{
965f5423 14685 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
2406cfed 14686 operands[1] = force_reg (DFmode, operands[1]);
0f40f9f7 14687})
a8083431
JH
14688
14689(define_insn "sqrtdf2_1"
14690 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14691 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
ba2baa55 14692 "TARGET_USE_FANCY_MATH_387
965f5423 14693 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
a8083431
JH
14694 "@
14695 fsqrt
0f40f9f7 14696 sqrtsd\t{%1, %0|%0, %1}"
a8083431
JH
14697 [(set_attr "type" "fpspc,sse")
14698 (set_attr "mode" "DF,DF")
14699 (set_attr "athlon_decode" "direct,*")])
14700
14701(define_insn "sqrtdf2_1_sse_only"
14702 [(set (match_operand:DF 0 "register_operand" "=Y")
14703 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
965f5423 14704 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
0f40f9f7 14705 "sqrtsd\t{%1, %0|%0, %1}"
a8083431
JH
14706 [(set_attr "type" "sse")
14707 (set_attr "mode" "DF")
14708 (set_attr "athlon_decode" "*")])
14709
14710(define_insn "sqrtdf2_i387"
e075ae69
RH
14711 [(set (match_operand:DF 0 "register_operand" "=f")
14712 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
ba2baa55 14713 "TARGET_USE_FANCY_MATH_387
abf80f8f 14714 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
e075ae69 14715 "fsqrt"
0b5107cf 14716 [(set_attr "type" "fpspc")
6ef67412 14717 (set_attr "mode" "DF")
0b5107cf 14718 (set_attr "athlon_decode" "direct")])
e075ae69 14719
6343a50e 14720(define_insn "*sqrtextendsfdf2"
e075ae69
RH
14721 [(set (match_operand:DF 0 "register_operand" "=f")
14722 (sqrt:DF (float_extend:DF
14723 (match_operand:SF 1 "register_operand" "0"))))]
ba2baa55 14724 "TARGET_USE_FANCY_MATH_387
965f5423 14725 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
e075ae69 14726 "fsqrt"
0b5107cf 14727 [(set_attr "type" "fpspc")
6ef67412 14728 (set_attr "mode" "DF")
0b5107cf 14729 (set_attr "athlon_decode" "direct")])
e075ae69
RH
14730
14731(define_insn "sqrtxf2"
14732 [(set (match_operand:XF 0 "register_operand" "=f")
14733 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
ba2baa55 14734 "TARGET_USE_FANCY_MATH_387
de6c5979 14735 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
2b589241
JH
14736 "fsqrt"
14737 [(set_attr "type" "fpspc")
14738 (set_attr "mode" "XF")
14739 (set_attr "athlon_decode" "direct")])
14740
6343a50e 14741(define_insn "*sqrtextenddfxf2"
e075ae69
RH
14742 [(set (match_operand:XF 0 "register_operand" "=f")
14743 (sqrt:XF (float_extend:XF
14744 (match_operand:DF 1 "register_operand" "0"))))]
ba2baa55 14745 "TARGET_USE_FANCY_MATH_387"
2b589241
JH
14746 "fsqrt"
14747 [(set_attr "type" "fpspc")
14748 (set_attr "mode" "XF")
14749 (set_attr "athlon_decode" "direct")])
14750
6343a50e 14751(define_insn "*sqrtextendsfxf2"
e075ae69
RH
14752 [(set (match_operand:XF 0 "register_operand" "=f")
14753 (sqrt:XF (float_extend:XF
14754 (match_operand:SF 1 "register_operand" "0"))))]
ba2baa55 14755 "TARGET_USE_FANCY_MATH_387"
2b589241
JH
14756 "fsqrt"
14757 [(set_attr "type" "fpspc")
14758 (set_attr "mode" "XF")
14759 (set_attr "athlon_decode" "direct")])
14760
5ae27cfa
UB
14761(define_insn "fpremxf4"
14762 [(set (match_operand:XF 0 "register_operand" "=f")
14763 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14764 (match_operand:XF 3 "register_operand" "1")]
14765 UNSPEC_FPREM_F))
14766 (set (match_operand:XF 1 "register_operand" "=u")
14767 (unspec:XF [(match_dup 2) (match_dup 3)]
14768 UNSPEC_FPREM_U))
8bc527af 14769 (set (reg:CCFP FPSR_REG)
5ae27cfa 14770 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
ba2baa55 14771 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14772 && flag_unsafe_math_optimizations"
14773 "fprem"
14774 [(set_attr "type" "fpspc")
14775 (set_attr "mode" "XF")])
14776
14777(define_expand "fmodsf3"
14778 [(use (match_operand:SF 0 "register_operand" ""))
14779 (use (match_operand:SF 1 "register_operand" ""))
14780 (use (match_operand:SF 2 "register_operand" ""))]
ba2baa55 14781 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14782 && flag_unsafe_math_optimizations"
14783{
14784 rtx label = gen_label_rtx ();
14785
14786 rtx op1 = gen_reg_rtx (XFmode);
14787 rtx op2 = gen_reg_rtx (XFmode);
14788
14789 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14790 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14791
14792 emit_label (label);
14793
14794 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14795 ix86_emit_fp_unordered_jump (label);
14796
14797 emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14798 DONE;
14799})
14800
14801(define_expand "fmoddf3"
14802 [(use (match_operand:DF 0 "register_operand" ""))
14803 (use (match_operand:DF 1 "register_operand" ""))
14804 (use (match_operand:DF 2 "register_operand" ""))]
ba2baa55 14805 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14806 && flag_unsafe_math_optimizations"
14807{
14808 rtx label = gen_label_rtx ();
14809
14810 rtx op1 = gen_reg_rtx (XFmode);
14811 rtx op2 = gen_reg_rtx (XFmode);
14812
14813 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14814 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14815
14816 emit_label (label);
14817
14818 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14819 ix86_emit_fp_unordered_jump (label);
14820
14821 emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14822 DONE;
14823})
14824
14825(define_expand "fmodxf3"
14826 [(use (match_operand:XF 0 "register_operand" ""))
14827 (use (match_operand:XF 1 "register_operand" ""))
14828 (use (match_operand:XF 2 "register_operand" ""))]
ba2baa55 14829 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14830 && flag_unsafe_math_optimizations"
14831{
14832 rtx label = gen_label_rtx ();
14833
14834 emit_label (label);
14835
14836 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14837 operands[1], operands[2]));
14838 ix86_emit_fp_unordered_jump (label);
14839
14840 emit_move_insn (operands[0], operands[1]);
14841 DONE;
14842})
14843
14844(define_insn "fprem1xf4"
14845 [(set (match_operand:XF 0 "register_operand" "=f")
14846 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14847 (match_operand:XF 3 "register_operand" "1")]
14848 UNSPEC_FPREM1_F))
14849 (set (match_operand:XF 1 "register_operand" "=u")
14850 (unspec:XF [(match_dup 2) (match_dup 3)]
14851 UNSPEC_FPREM1_U))
8bc527af 14852 (set (reg:CCFP FPSR_REG)
5ae27cfa 14853 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
ba2baa55 14854 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14855 && flag_unsafe_math_optimizations"
14856 "fprem1"
14857 [(set_attr "type" "fpspc")
14858 (set_attr "mode" "XF")])
14859
14860(define_expand "dremsf3"
14861 [(use (match_operand:SF 0 "register_operand" ""))
14862 (use (match_operand:SF 1 "register_operand" ""))
14863 (use (match_operand:SF 2 "register_operand" ""))]
ba2baa55 14864 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14865 && flag_unsafe_math_optimizations"
14866{
14867 rtx label = gen_label_rtx ();
14868
14869 rtx op1 = gen_reg_rtx (XFmode);
14870 rtx op2 = gen_reg_rtx (XFmode);
14871
14872 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14873 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14874
14875 emit_label (label);
14876
14877 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14878 ix86_emit_fp_unordered_jump (label);
14879
14880 emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14881 DONE;
14882})
14883
14884(define_expand "dremdf3"
14885 [(use (match_operand:DF 0 "register_operand" ""))
14886 (use (match_operand:DF 1 "register_operand" ""))
14887 (use (match_operand:DF 2 "register_operand" ""))]
ba2baa55 14888 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14889 && flag_unsafe_math_optimizations"
14890{
14891 rtx label = gen_label_rtx ();
14892
14893 rtx op1 = gen_reg_rtx (XFmode);
14894 rtx op2 = gen_reg_rtx (XFmode);
14895
14896 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14897 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14898
14899 emit_label (label);
14900
14901 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14902 ix86_emit_fp_unordered_jump (label);
14903
14904 emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14905 DONE;
14906})
14907
14908(define_expand "dremxf3"
14909 [(use (match_operand:XF 0 "register_operand" ""))
14910 (use (match_operand:XF 1 "register_operand" ""))
14911 (use (match_operand:XF 2 "register_operand" ""))]
ba2baa55 14912 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14913 && flag_unsafe_math_optimizations"
14914{
14915 rtx label = gen_label_rtx ();
14916
14917 emit_label (label);
14918
14919 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14920 operands[1], operands[2]));
14921 ix86_emit_fp_unordered_jump (label);
14922
14923 emit_move_insn (operands[0], operands[1]);
14924 DONE;
14925})
14926
6c7cf1f0 14927(define_insn "*sindf2"
e075ae69 14928 [(set (match_operand:DF 0 "register_operand" "=f")
8ee41eaf 14929 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
ba2baa55 14930 "TARGET_USE_FANCY_MATH_387
de6c5979 14931 && flag_unsafe_math_optimizations"
e075ae69 14932 "fsin"
6ef67412
JH
14933 [(set_attr "type" "fpspc")
14934 (set_attr "mode" "DF")])
e075ae69 14935
6c7cf1f0 14936(define_insn "*sinsf2"
e075ae69 14937 [(set (match_operand:SF 0 "register_operand" "=f")
8ee41eaf 14938 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
ba2baa55 14939 "TARGET_USE_FANCY_MATH_387
de6c5979 14940 && flag_unsafe_math_optimizations"
e075ae69 14941 "fsin"
6ef67412
JH
14942 [(set_attr "type" "fpspc")
14943 (set_attr "mode" "SF")])
5f3d14e3 14944
6343a50e 14945(define_insn "*sinextendsfdf2"
e075ae69
RH
14946 [(set (match_operand:DF 0 "register_operand" "=f")
14947 (unspec:DF [(float_extend:DF
8ee41eaf
RH
14948 (match_operand:SF 1 "register_operand" "0"))]
14949 UNSPEC_SIN))]
ba2baa55 14950 "TARGET_USE_FANCY_MATH_387
de6c5979 14951 && flag_unsafe_math_optimizations"
e075ae69 14952 "fsin"
6ef67412
JH
14953 [(set_attr "type" "fpspc")
14954 (set_attr "mode" "DF")])
4f9ca067 14955
6c7cf1f0 14956(define_insn "*sinxf2"
e075ae69 14957 [(set (match_operand:XF 0 "register_operand" "=f")
8ee41eaf 14958 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
ba2baa55 14959 "TARGET_USE_FANCY_MATH_387
de6c5979 14960 && flag_unsafe_math_optimizations"
2b589241
JH
14961 "fsin"
14962 [(set_attr "type" "fpspc")
14963 (set_attr "mode" "XF")])
14964
6c7cf1f0 14965(define_insn "*cosdf2"
e075ae69 14966 [(set (match_operand:DF 0 "register_operand" "=f")
8ee41eaf 14967 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
ba2baa55 14968 "TARGET_USE_FANCY_MATH_387
de6c5979 14969 && flag_unsafe_math_optimizations"
e075ae69 14970 "fcos"
6ef67412
JH
14971 [(set_attr "type" "fpspc")
14972 (set_attr "mode" "DF")])
bca7cce2 14973
6c7cf1f0 14974(define_insn "*cossf2"
e075ae69 14975 [(set (match_operand:SF 0 "register_operand" "=f")
8ee41eaf 14976 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
ba2baa55 14977 "TARGET_USE_FANCY_MATH_387
de6c5979 14978 && flag_unsafe_math_optimizations"
e075ae69 14979 "fcos"
6ef67412
JH
14980 [(set_attr "type" "fpspc")
14981 (set_attr "mode" "SF")])
bca7cce2 14982
6343a50e 14983(define_insn "*cosextendsfdf2"
e075ae69
RH
14984 [(set (match_operand:DF 0 "register_operand" "=f")
14985 (unspec:DF [(float_extend:DF
8ee41eaf
RH
14986 (match_operand:SF 1 "register_operand" "0"))]
14987 UNSPEC_COS))]
ba2baa55 14988 "TARGET_USE_FANCY_MATH_387
de6c5979 14989 && flag_unsafe_math_optimizations"
e075ae69 14990 "fcos"
6ef67412
JH
14991 [(set_attr "type" "fpspc")
14992 (set_attr "mode" "DF")])
5f3d14e3 14993
6c7cf1f0 14994(define_insn "*cosxf2"
e075ae69 14995 [(set (match_operand:XF 0 "register_operand" "=f")
8ee41eaf 14996 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
ba2baa55 14997 "TARGET_USE_FANCY_MATH_387
de6c5979 14998 && flag_unsafe_math_optimizations"
2b589241
JH
14999 "fcos"
15000 [(set_attr "type" "fpspc")
15001 (set_attr "mode" "XF")])
1fb54135 15002
6c7cf1f0
UB
15003;; With sincos pattern defined, sin and cos builtin function will be
15004;; expanded to sincos pattern with one of its outputs left unused.
15005;; Cse pass will detected, if two sincos patterns can be combined,
1ae58c30 15006;; otherwise sincos pattern will be split back to sin or cos pattern,
6c7cf1f0
UB
15007;; depending on the unused output.
15008
15009(define_insn "sincosdf3"
15010 [(set (match_operand:DF 0 "register_operand" "=f")
15011 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15012 UNSPEC_SINCOS_COS))
15013 (set (match_operand:DF 1 "register_operand" "=u")
15014 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
ba2baa55 15015 "TARGET_USE_FANCY_MATH_387
6c7cf1f0
UB
15016 && flag_unsafe_math_optimizations"
15017 "fsincos"
15018 [(set_attr "type" "fpspc")
15019 (set_attr "mode" "DF")])
15020
15021(define_split
15022 [(set (match_operand:DF 0 "register_operand" "")
15023 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15024 UNSPEC_SINCOS_COS))
15025 (set (match_operand:DF 1 "register_operand" "")
15026 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15027 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15028 && !reload_completed && !reload_in_progress"
15029 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15030 "")
15031
15032(define_split
15033 [(set (match_operand:DF 0 "register_operand" "")
15034 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15035 UNSPEC_SINCOS_COS))
15036 (set (match_operand:DF 1 "register_operand" "")
15037 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15038 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15039 && !reload_completed && !reload_in_progress"
15040 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15041 "")
15042
15043(define_insn "sincossf3"
15044 [(set (match_operand:SF 0 "register_operand" "=f")
15045 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15046 UNSPEC_SINCOS_COS))
15047 (set (match_operand:SF 1 "register_operand" "=u")
15048 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
ba2baa55 15049 "TARGET_USE_FANCY_MATH_387
6c7cf1f0
UB
15050 && flag_unsafe_math_optimizations"
15051 "fsincos"
15052 [(set_attr "type" "fpspc")
15053 (set_attr "mode" "SF")])
15054
15055(define_split
15056 [(set (match_operand:SF 0 "register_operand" "")
15057 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15058 UNSPEC_SINCOS_COS))
15059 (set (match_operand:SF 1 "register_operand" "")
15060 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15061 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15062 && !reload_completed && !reload_in_progress"
15063 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15064 "")
15065
15066(define_split
15067 [(set (match_operand:SF 0 "register_operand" "")
15068 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15069 UNSPEC_SINCOS_COS))
15070 (set (match_operand:SF 1 "register_operand" "")
15071 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15072 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15073 && !reload_completed && !reload_in_progress"
15074 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15075 "")
15076
15077(define_insn "*sincosextendsfdf3"
15078 [(set (match_operand:DF 0 "register_operand" "=f")
15079 (unspec:DF [(float_extend:DF
15080 (match_operand:SF 2 "register_operand" "0"))]
15081 UNSPEC_SINCOS_COS))
15082 (set (match_operand:DF 1 "register_operand" "=u")
15083 (unspec:DF [(float_extend:DF
15084 (match_dup 2))] UNSPEC_SINCOS_SIN))]
ba2baa55 15085 "TARGET_USE_FANCY_MATH_387
6c7cf1f0
UB
15086 && flag_unsafe_math_optimizations"
15087 "fsincos"
15088 [(set_attr "type" "fpspc")
15089 (set_attr "mode" "DF")])
15090
15091(define_split
15092 [(set (match_operand:DF 0 "register_operand" "")
15093 (unspec:DF [(float_extend:DF
15094 (match_operand:SF 2 "register_operand" ""))]
15095 UNSPEC_SINCOS_COS))
15096 (set (match_operand:DF 1 "register_operand" "")
15097 (unspec:DF [(float_extend:DF
15098 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15099 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15100 && !reload_completed && !reload_in_progress"
15101 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15102 (match_dup 2))] UNSPEC_SIN))]
15103 "")
15104
15105(define_split
15106 [(set (match_operand:DF 0 "register_operand" "")
15107 (unspec:DF [(float_extend:DF
15108 (match_operand:SF 2 "register_operand" ""))]
15109 UNSPEC_SINCOS_COS))
15110 (set (match_operand:DF 1 "register_operand" "")
15111 (unspec:DF [(float_extend:DF
15112 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15113 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15114 && !reload_completed && !reload_in_progress"
15115 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15116 (match_dup 2))] UNSPEC_COS))]
15117 "")
15118
15119(define_insn "sincosxf3"
15120 [(set (match_operand:XF 0 "register_operand" "=f")
15121 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15122 UNSPEC_SINCOS_COS))
15123 (set (match_operand:XF 1 "register_operand" "=u")
15124 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
ba2baa55 15125 "TARGET_USE_FANCY_MATH_387
6c7cf1f0
UB
15126 && flag_unsafe_math_optimizations"
15127 "fsincos"
15128 [(set_attr "type" "fpspc")
15129 (set_attr "mode" "XF")])
15130
15131(define_split
15132 [(set (match_operand:XF 0 "register_operand" "")
15133 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15134 UNSPEC_SINCOS_COS))
15135 (set (match_operand:XF 1 "register_operand" "")
15136 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15137 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15138 && !reload_completed && !reload_in_progress"
15139 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15140 "")
15141
15142(define_split
15143 [(set (match_operand:XF 0 "register_operand" "")
15144 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15145 UNSPEC_SINCOS_COS))
15146 (set (match_operand:XF 1 "register_operand" "")
15147 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15148 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15149 && !reload_completed && !reload_in_progress"
15150 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15151 "")
15152
a072d43b
UB
15153(define_insn "*tandf3_1"
15154 [(set (match_operand:DF 0 "register_operand" "=f")
15155 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15156 UNSPEC_TAN_ONE))
15157 (set (match_operand:DF 1 "register_operand" "=u")
15158 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
ba2baa55 15159 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15160 && flag_unsafe_math_optimizations"
15161 "fptan"
15162 [(set_attr "type" "fpspc")
15163 (set_attr "mode" "DF")])
15164
15165;; optimize sequence: fptan
15166;; fstp %st(0)
15167;; fld1
15168;; into fptan insn.
15169
15170(define_peephole2
15171 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15172 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15173 UNSPEC_TAN_ONE))
15174 (set (match_operand:DF 1 "register_operand" "")
15175 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15176 (set (match_dup 0)
15177 (match_operand:DF 3 "immediate_operand" ""))]
15178 "standard_80387_constant_p (operands[3]) == 2"
15179 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15180 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15181 "")
15182
15183(define_expand "tandf2"
15184 [(parallel [(set (match_dup 2)
15185 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15186 UNSPEC_TAN_ONE))
15187 (set (match_operand:DF 0 "register_operand" "")
15188 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
ba2baa55 15189 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15190 && flag_unsafe_math_optimizations"
15191{
15192 operands[2] = gen_reg_rtx (DFmode);
15193})
15194
15195(define_insn "*tansf3_1"
15196 [(set (match_operand:SF 0 "register_operand" "=f")
15197 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15198 UNSPEC_TAN_ONE))
15199 (set (match_operand:SF 1 "register_operand" "=u")
15200 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
ba2baa55 15201 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15202 && flag_unsafe_math_optimizations"
15203 "fptan"
15204 [(set_attr "type" "fpspc")
15205 (set_attr "mode" "SF")])
15206
15207;; optimize sequence: fptan
15208;; fstp %st(0)
15209;; fld1
15210;; into fptan insn.
15211
15212(define_peephole2
15213 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15214 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15215 UNSPEC_TAN_ONE))
15216 (set (match_operand:SF 1 "register_operand" "")
15217 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15218 (set (match_dup 0)
15219 (match_operand:SF 3 "immediate_operand" ""))]
15220 "standard_80387_constant_p (operands[3]) == 2"
15221 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15222 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15223 "")
15224
15225(define_expand "tansf2"
15226 [(parallel [(set (match_dup 2)
15227 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15228 UNSPEC_TAN_ONE))
15229 (set (match_operand:SF 0 "register_operand" "")
15230 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
ba2baa55 15231 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15232 && flag_unsafe_math_optimizations"
15233{
15234 operands[2] = gen_reg_rtx (SFmode);
15235})
15236
15237(define_insn "*tanxf3_1"
15238 [(set (match_operand:XF 0 "register_operand" "=f")
15239 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15240 UNSPEC_TAN_ONE))
15241 (set (match_operand:XF 1 "register_operand" "=u")
15242 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
ba2baa55 15243 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15244 && flag_unsafe_math_optimizations"
15245 "fptan"
15246 [(set_attr "type" "fpspc")
15247 (set_attr "mode" "XF")])
15248
15249;; optimize sequence: fptan
15250;; fstp %st(0)
15251;; fld1
15252;; into fptan insn.
15253
15254(define_peephole2
15255 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15256 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15257 UNSPEC_TAN_ONE))
15258 (set (match_operand:XF 1 "register_operand" "")
15259 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15260 (set (match_dup 0)
15261 (match_operand:XF 3 "immediate_operand" ""))]
15262 "standard_80387_constant_p (operands[3]) == 2"
15263 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15264 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15265 "")
15266
15267(define_expand "tanxf2"
15268 [(parallel [(set (match_dup 2)
15269 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15270 UNSPEC_TAN_ONE))
15271 (set (match_operand:XF 0 "register_operand" "")
15272 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
ba2baa55 15273 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15274 && flag_unsafe_math_optimizations"
15275{
15276 operands[2] = gen_reg_rtx (XFmode);
15277})
15278
afeeac3f 15279(define_insn "atan2df3_1"
cb0bc263
JH
15280 [(set (match_operand:DF 0 "register_operand" "=f")
15281 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15282 (match_operand:DF 1 "register_operand" "u")]
15283 UNSPEC_FPATAN))
15284 (clobber (match_scratch:DF 3 "=1"))]
ba2baa55 15285 "TARGET_USE_FANCY_MATH_387
1fb54135
RS
15286 && flag_unsafe_math_optimizations"
15287 "fpatan"
15288 [(set_attr "type" "fpspc")
15289 (set_attr "mode" "DF")])
15290
afeeac3f
RS
15291(define_expand "atan2df3"
15292 [(use (match_operand:DF 0 "register_operand" "=f"))
15293 (use (match_operand:DF 2 "register_operand" "0"))
15294 (use (match_operand:DF 1 "register_operand" "u"))]
ba2baa55 15295 "TARGET_USE_FANCY_MATH_387
afeeac3f
RS
15296 && flag_unsafe_math_optimizations"
15297{
15298 rtx copy = gen_reg_rtx (DFmode);
15299 emit_move_insn (copy, operands[1]);
15300 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15301 DONE;
923c4cf2 15302})
afeeac3f 15303
a6bf61c7
UB
15304(define_expand "atandf2"
15305 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15306 (unspec:DF [(match_dup 2)
15307 (match_operand:DF 1 "register_operand" "")]
15308 UNSPEC_FPATAN))
15309 (clobber (match_scratch:DF 3 ""))])]
ba2baa55 15310 "TARGET_USE_FANCY_MATH_387
a6bf61c7
UB
15311 && flag_unsafe_math_optimizations"
15312{
15313 operands[2] = gen_reg_rtx (DFmode);
15314 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15315})
15316
afeeac3f 15317(define_insn "atan2sf3_1"
cb0bc263
JH
15318 [(set (match_operand:SF 0 "register_operand" "=f")
15319 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15320 (match_operand:SF 1 "register_operand" "u")]
15321 UNSPEC_FPATAN))
15322 (clobber (match_scratch:SF 3 "=1"))]
ba2baa55 15323 "TARGET_USE_FANCY_MATH_387
1fb54135
RS
15324 && flag_unsafe_math_optimizations"
15325 "fpatan"
15326 [(set_attr "type" "fpspc")
15327 (set_attr "mode" "SF")])
15328
afeeac3f
RS
15329(define_expand "atan2sf3"
15330 [(use (match_operand:SF 0 "register_operand" "=f"))
15331 (use (match_operand:SF 2 "register_operand" "0"))
15332 (use (match_operand:SF 1 "register_operand" "u"))]
ba2baa55 15333 "TARGET_USE_FANCY_MATH_387
afeeac3f
RS
15334 && flag_unsafe_math_optimizations"
15335{
15336 rtx copy = gen_reg_rtx (SFmode);
15337 emit_move_insn (copy, operands[1]);
15338 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15339 DONE;
923c4cf2 15340})
afeeac3f 15341
a6bf61c7
UB
15342(define_expand "atansf2"
15343 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15344 (unspec:SF [(match_dup 2)
15345 (match_operand:SF 1 "register_operand" "")]
15346 UNSPEC_FPATAN))
15347 (clobber (match_scratch:SF 3 ""))])]
ba2baa55 15348 "TARGET_USE_FANCY_MATH_387
a6bf61c7
UB
15349 && flag_unsafe_math_optimizations"
15350{
15351 operands[2] = gen_reg_rtx (SFmode);
15352 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15353})
15354
afeeac3f 15355(define_insn "atan2xf3_1"
cb0bc263
JH
15356 [(set (match_operand:XF 0 "register_operand" "=f")
15357 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15358 (match_operand:XF 1 "register_operand" "u")]
15359 UNSPEC_FPATAN))
15360 (clobber (match_scratch:XF 3 "=1"))]
ba2baa55 15361 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15362 && flag_unsafe_math_optimizations"
1fb54135
RS
15363 "fpatan"
15364 [(set_attr "type" "fpspc")
15365 (set_attr "mode" "XF")])
15366
afeeac3f
RS
15367(define_expand "atan2xf3"
15368 [(use (match_operand:XF 0 "register_operand" "=f"))
15369 (use (match_operand:XF 2 "register_operand" "0"))
15370 (use (match_operand:XF 1 "register_operand" "u"))]
ba2baa55 15371 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15372 && flag_unsafe_math_optimizations"
afeeac3f
RS
15373{
15374 rtx copy = gen_reg_rtx (XFmode);
15375 emit_move_insn (copy, operands[1]);
15376 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15377 DONE;
923c4cf2 15378})
afeeac3f 15379
a6bf61c7
UB
15380(define_expand "atanxf2"
15381 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15382 (unspec:XF [(match_dup 2)
15383 (match_operand:XF 1 "register_operand" "")]
15384 UNSPEC_FPATAN))
15385 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 15386 "TARGET_USE_FANCY_MATH_387
a6bf61c7
UB
15387 && flag_unsafe_math_optimizations"
15388{
15389 operands[2] = gen_reg_rtx (XFmode);
15390 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15391})
15392
c56122d8
UB
15393(define_expand "asindf2"
15394 [(set (match_dup 2)
15395 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15396 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15397 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15398 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15399 (parallel [(set (match_dup 7)
15400 (unspec:XF [(match_dup 6) (match_dup 2)]
15401 UNSPEC_FPATAN))
15402 (clobber (match_scratch:XF 8 ""))])
15403 (set (match_operand:DF 0 "register_operand" "")
15404 (float_truncate:DF (match_dup 7)))]
ba2baa55 15405 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15406 && flag_unsafe_math_optimizations"
15407{
15408 int i;
15409
15410 for (i=2; i<8; i++)
15411 operands[i] = gen_reg_rtx (XFmode);
15412
15413 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15414})
15415
15416(define_expand "asinsf2"
15417 [(set (match_dup 2)
15418 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15419 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15420 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15421 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15422 (parallel [(set (match_dup 7)
15423 (unspec:XF [(match_dup 6) (match_dup 2)]
15424 UNSPEC_FPATAN))
15425 (clobber (match_scratch:XF 8 ""))])
15426 (set (match_operand:SF 0 "register_operand" "")
15427 (float_truncate:SF (match_dup 7)))]
ba2baa55 15428 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15429 && flag_unsafe_math_optimizations"
15430{
15431 int i;
15432
15433 for (i=2; i<8; i++)
15434 operands[i] = gen_reg_rtx (XFmode);
15435
15436 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15437})
15438
15439(define_expand "asinxf2"
15440 [(set (match_dup 2)
15441 (mult:XF (match_operand:XF 1 "register_operand" "")
15442 (match_dup 1)))
15443 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15444 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15445 (parallel [(set (match_operand:XF 0 "register_operand" "")
15446 (unspec:XF [(match_dup 5) (match_dup 1)]
15447 UNSPEC_FPATAN))
15448 (clobber (match_scratch:XF 6 ""))])]
ba2baa55 15449 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15450 && flag_unsafe_math_optimizations"
15451{
15452 int i;
15453
15454 for (i=2; i<6; i++)
15455 operands[i] = gen_reg_rtx (XFmode);
15456
15457 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15458})
15459
15460(define_expand "acosdf2"
15461 [(set (match_dup 2)
15462 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15463 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15464 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15465 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15466 (parallel [(set (match_dup 7)
15467 (unspec:XF [(match_dup 2) (match_dup 6)]
15468 UNSPEC_FPATAN))
15469 (clobber (match_scratch:XF 8 ""))])
15470 (set (match_operand:DF 0 "register_operand" "")
15471 (float_truncate:DF (match_dup 7)))]
ba2baa55 15472 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15473 && flag_unsafe_math_optimizations"
15474{
15475 int i;
15476
15477 for (i=2; i<8; i++)
15478 operands[i] = gen_reg_rtx (XFmode);
15479
15480 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15481})
15482
15483(define_expand "acossf2"
15484 [(set (match_dup 2)
15485 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15486 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15487 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15488 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15489 (parallel [(set (match_dup 7)
15490 (unspec:XF [(match_dup 2) (match_dup 6)]
15491 UNSPEC_FPATAN))
15492 (clobber (match_scratch:XF 8 ""))])
15493 (set (match_operand:SF 0 "register_operand" "")
15494 (float_truncate:SF (match_dup 7)))]
ba2baa55 15495 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15496 && flag_unsafe_math_optimizations"
15497{
15498 int i;
15499
15500 for (i=2; i<8; i++)
15501 operands[i] = gen_reg_rtx (XFmode);
15502
15503 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15504})
15505
15506(define_expand "acosxf2"
15507 [(set (match_dup 2)
15508 (mult:XF (match_operand:XF 1 "register_operand" "")
15509 (match_dup 1)))
15510 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15511 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15512 (parallel [(set (match_operand:XF 0 "register_operand" "")
15513 (unspec:XF [(match_dup 1) (match_dup 5)]
15514 UNSPEC_FPATAN))
15515 (clobber (match_scratch:XF 6 ""))])]
ba2baa55 15516 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15517 && flag_unsafe_math_optimizations"
15518{
15519 int i;
15520
15521 for (i=2; i<6; i++)
15522 operands[i] = gen_reg_rtx (XFmode);
15523
15524 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15525})
15526
c2fcfa4f 15527(define_insn "fyl2x_xf3"
cb0bc263
JH
15528 [(set (match_operand:XF 0 "register_operand" "=f")
15529 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15530 (match_operand:XF 1 "register_operand" "u")]
15531 UNSPEC_FYL2X))
15532 (clobber (match_scratch:XF 3 "=1"))]
ba2baa55 15533 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15534 && flag_unsafe_math_optimizations"
358997e2
RS
15535 "fyl2x"
15536 [(set_attr "type" "fpspc")
15537 (set_attr "mode" "XF")])
15538
15539(define_expand "logsf2"
6adcf89d
UB
15540 [(set (match_dup 2)
15541 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15542 (parallel [(set (match_dup 4)
15543 (unspec:XF [(match_dup 2)
15544 (match_dup 3)] UNSPEC_FYL2X))
15545 (clobber (match_scratch:XF 5 ""))])
15546 (set (match_operand:SF 0 "register_operand" "")
15547 (float_truncate:SF (match_dup 4)))]
ba2baa55 15548 "TARGET_USE_FANCY_MATH_387
358997e2
RS
15549 && flag_unsafe_math_optimizations"
15550{
15551 rtx temp;
15552
f8a1ebc6 15553 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15554 operands[3] = gen_reg_rtx (XFmode);
15555 operands[4] = gen_reg_rtx (XFmode);
15556
358997e2 15557 temp = standard_80387_constant_rtx (4); /* fldln2 */
6adcf89d 15558 emit_move_insn (operands[3], temp);
358997e2
RS
15559})
15560
15561(define_expand "logdf2"
6adcf89d
UB
15562 [(set (match_dup 2)
15563 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15564 (parallel [(set (match_dup 4)
15565 (unspec:XF [(match_dup 2)
15566 (match_dup 3)] UNSPEC_FYL2X))
15567 (clobber (match_scratch:XF 5 ""))])
15568 (set (match_operand:DF 0 "register_operand" "")
15569 (float_truncate:DF (match_dup 4)))]
ba2baa55 15570 "TARGET_USE_FANCY_MATH_387
358997e2
RS
15571 && flag_unsafe_math_optimizations"
15572{
15573 rtx temp;
15574
f8a1ebc6 15575 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15576 operands[3] = gen_reg_rtx (XFmode);
15577 operands[4] = gen_reg_rtx (XFmode);
15578
358997e2 15579 temp = standard_80387_constant_rtx (4); /* fldln2 */
6adcf89d 15580 emit_move_insn (operands[3], temp);
358997e2
RS
15581})
15582
15583(define_expand "logxf2"
e43736ad
RS
15584 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15585 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15586 (match_dup 2)] UNSPEC_FYL2X))
cb0bc263 15587 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 15588 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15589 && flag_unsafe_math_optimizations"
358997e2
RS
15590{
15591 rtx temp;
15592
15593 operands[2] = gen_reg_rtx (XFmode);
15594 temp = standard_80387_constant_rtx (4); /* fldln2 */
15595 emit_move_insn (operands[2], temp);
15596})
15597
3b8e0c91 15598(define_expand "log10sf2"
6adcf89d
UB
15599 [(set (match_dup 2)
15600 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15601 (parallel [(set (match_dup 4)
15602 (unspec:XF [(match_dup 2)
15603 (match_dup 3)] UNSPEC_FYL2X))
15604 (clobber (match_scratch:XF 5 ""))])
15605 (set (match_operand:SF 0 "register_operand" "")
15606 (float_truncate:SF (match_dup 4)))]
ba2baa55 15607 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15608 && flag_unsafe_math_optimizations"
15609{
15610 rtx temp;
15611
15612 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15613 operands[3] = gen_reg_rtx (XFmode);
15614 operands[4] = gen_reg_rtx (XFmode);
15615
3b8e0c91 15616 temp = standard_80387_constant_rtx (3); /* fldlg2 */
6adcf89d 15617 emit_move_insn (operands[3], temp);
3b8e0c91
UB
15618})
15619
15620(define_expand "log10df2"
6adcf89d
UB
15621 [(set (match_dup 2)
15622 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15623 (parallel [(set (match_dup 4)
15624 (unspec:XF [(match_dup 2)
15625 (match_dup 3)] UNSPEC_FYL2X))
15626 (clobber (match_scratch:XF 5 ""))])
15627 (set (match_operand:DF 0 "register_operand" "")
15628 (float_truncate:DF (match_dup 4)))]
ba2baa55 15629 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15630 && flag_unsafe_math_optimizations"
15631{
15632 rtx temp;
15633
15634 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15635 operands[3] = gen_reg_rtx (XFmode);
15636 operands[4] = gen_reg_rtx (XFmode);
15637
3b8e0c91 15638 temp = standard_80387_constant_rtx (3); /* fldlg2 */
6adcf89d 15639 emit_move_insn (operands[3], temp);
3b8e0c91
UB
15640})
15641
15642(define_expand "log10xf2"
15643 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15644 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15645 (match_dup 2)] UNSPEC_FYL2X))
15646 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 15647 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15648 && flag_unsafe_math_optimizations"
15649{
15650 rtx temp;
15651
15652 operands[2] = gen_reg_rtx (XFmode);
15653 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15654 emit_move_insn (operands[2], temp);
15655})
15656
15657(define_expand "log2sf2"
6adcf89d
UB
15658 [(set (match_dup 2)
15659 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15660 (parallel [(set (match_dup 4)
15661 (unspec:XF [(match_dup 2)
15662 (match_dup 3)] UNSPEC_FYL2X))
15663 (clobber (match_scratch:XF 5 ""))])
15664 (set (match_operand:SF 0 "register_operand" "")
15665 (float_truncate:SF (match_dup 4)))]
ba2baa55 15666 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15667 && flag_unsafe_math_optimizations"
15668{
15669 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15670 operands[3] = gen_reg_rtx (XFmode);
15671 operands[4] = gen_reg_rtx (XFmode);
3b8e0c91 15672
6adcf89d 15673 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
3b8e0c91
UB
15674})
15675
15676(define_expand "log2df2"
6adcf89d
UB
15677 [(set (match_dup 2)
15678 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15679 (parallel [(set (match_dup 4)
15680 (unspec:XF [(match_dup 2)
15681 (match_dup 3)] UNSPEC_FYL2X))
15682 (clobber (match_scratch:XF 5 ""))])
15683 (set (match_operand:DF 0 "register_operand" "")
15684 (float_truncate:DF (match_dup 4)))]
ba2baa55 15685 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15686 && flag_unsafe_math_optimizations"
15687{
15688 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15689 operands[3] = gen_reg_rtx (XFmode);
15690 operands[4] = gen_reg_rtx (XFmode);
15691
15692 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
3b8e0c91
UB
15693})
15694
15695(define_expand "log2xf2"
15696 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15697 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15698 (match_dup 2)] UNSPEC_FYL2X))
15699 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 15700 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15701 && flag_unsafe_math_optimizations"
15702{
15703 operands[2] = gen_reg_rtx (XFmode);
15704 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15705})
15706
c2fcfa4f
UB
15707(define_insn "fyl2xp1_xf3"
15708 [(set (match_operand:XF 0 "register_operand" "=f")
15709 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15710 (match_operand:XF 1 "register_operand" "u")]
15711 UNSPEC_FYL2XP1))
15712 (clobber (match_scratch:XF 3 "=1"))]
ba2baa55 15713 "TARGET_USE_FANCY_MATH_387
c2fcfa4f
UB
15714 && flag_unsafe_math_optimizations"
15715 "fyl2xp1"
15716 [(set_attr "type" "fpspc")
15717 (set_attr "mode" "XF")])
15718
15719(define_expand "log1psf2"
15720 [(use (match_operand:XF 0 "register_operand" ""))
15721 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 15722 "TARGET_USE_FANCY_MATH_387
c2fcfa4f
UB
15723 && flag_unsafe_math_optimizations"
15724{
15725 rtx op0 = gen_reg_rtx (XFmode);
15726 rtx op1 = gen_reg_rtx (XFmode);
15727
15728 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15729 ix86_emit_i387_log1p (op0, op1);
15730 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15731 DONE;
15732})
15733
15734(define_expand "log1pdf2"
15735 [(use (match_operand:XF 0 "register_operand" ""))
15736 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 15737 "TARGET_USE_FANCY_MATH_387
c2fcfa4f
UB
15738 && flag_unsafe_math_optimizations"
15739{
15740 rtx op0 = gen_reg_rtx (XFmode);
15741 rtx op1 = gen_reg_rtx (XFmode);
15742
15743 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15744 ix86_emit_i387_log1p (op0, op1);
15745 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15746 DONE;
15747})
15748
15749(define_expand "log1pxf2"
15750 [(use (match_operand:XF 0 "register_operand" ""))
15751 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 15752 "TARGET_USE_FANCY_MATH_387
c2fcfa4f
UB
15753 && flag_unsafe_math_optimizations"
15754{
15755 ix86_emit_i387_log1p (operands[0], operands[1]);
15756 DONE;
15757})
15758
6adcf89d
UB
15759(define_insn "*fxtractxf3"
15760 [(set (match_operand:XF 0 "register_operand" "=f")
15761 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
88b28a31 15762 UNSPEC_XTRACT_FRACT))
6adcf89d
UB
15763 (set (match_operand:XF 1 "register_operand" "=u")
15764 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
ba2baa55 15765 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
15766 && flag_unsafe_math_optimizations"
15767 "fxtract"
15768 [(set_attr "type" "fpspc")
6adcf89d 15769 (set_attr "mode" "XF")])
88b28a31 15770
6adcf89d
UB
15771(define_expand "logbsf2"
15772 [(set (match_dup 2)
15773 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15774 (parallel [(set (match_dup 3)
15775 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15776 (set (match_dup 4)
15777 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15778 (set (match_operand:SF 0 "register_operand" "")
15779 (float_truncate:SF (match_dup 4)))]
ba2baa55 15780 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
15781 && flag_unsafe_math_optimizations"
15782{
6adcf89d
UB
15783 operands[2] = gen_reg_rtx (XFmode);
15784 operands[3] = gen_reg_rtx (XFmode);
15785 operands[4] = gen_reg_rtx (XFmode);
88b28a31
UB
15786})
15787
6adcf89d
UB
15788(define_expand "logbdf2"
15789 [(set (match_dup 2)
15790 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15791 (parallel [(set (match_dup 3)
15792 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15793 (set (match_dup 4)
15794 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15795 (set (match_operand:DF 0 "register_operand" "")
15796 (float_truncate:DF (match_dup 4)))]
ba2baa55 15797 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
15798 && flag_unsafe_math_optimizations"
15799{
6adcf89d
UB
15800 operands[2] = gen_reg_rtx (XFmode);
15801 operands[3] = gen_reg_rtx (XFmode);
15802 operands[4] = gen_reg_rtx (XFmode);
88b28a31
UB
15803})
15804
88b28a31
UB
15805(define_expand "logbxf2"
15806 [(parallel [(set (match_dup 2)
15807 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15808 UNSPEC_XTRACT_FRACT))
15809 (set (match_operand:XF 0 "register_operand" "")
15810 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
ba2baa55 15811 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
15812 && flag_unsafe_math_optimizations"
15813{
15814 operands[2] = gen_reg_rtx (XFmode);
15815})
15816
15817(define_expand "ilogbsi2"
15818 [(parallel [(set (match_dup 2)
15819 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15820 UNSPEC_XTRACT_FRACT))
15821 (set (match_operand:XF 3 "register_operand" "")
15822 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15823 (parallel [(set (match_operand:SI 0 "register_operand" "")
15824 (fix:SI (match_dup 3)))
8bc527af 15825 (clobber (reg:CC FLAGS_REG))])]
ba2baa55 15826 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
15827 && flag_unsafe_math_optimizations"
15828{
15829 operands[2] = gen_reg_rtx (XFmode);
15830 operands[3] = gen_reg_rtx (XFmode);
15831})
15832
9d5b9dae
RS
15833(define_insn "*f2xm1xf2"
15834 [(set (match_operand:XF 0 "register_operand" "=f")
15835 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15836 UNSPEC_F2XM1))]
ba2baa55 15837 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15838 && flag_unsafe_math_optimizations"
9d5b9dae
RS
15839 "f2xm1"
15840 [(set_attr "type" "fpspc")
15841 (set_attr "mode" "XF")])
15842
f964bd29
UB
15843(define_insn "*fscalexf4"
15844 [(set (match_operand:XF 0 "register_operand" "=f")
15845 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15846 (match_operand:XF 3 "register_operand" "1")]
15847 UNSPEC_FSCALE_FRACT))
15848 (set (match_operand:XF 1 "register_operand" "=u")
15849 (unspec:XF [(match_dup 2) (match_dup 3)]
15850 UNSPEC_FSCALE_EXP))]
ba2baa55 15851 "TARGET_USE_FANCY_MATH_387
f964bd29
UB
15852 && flag_unsafe_math_optimizations"
15853 "fscale"
15854 [(set_attr "type" "fpspc")
152e3565 15855 (set_attr "mode" "XF")])
f964bd29 15856
9d5b9dae
RS
15857(define_expand "expsf2"
15858 [(set (match_dup 2)
15859 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15860 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15861 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15862 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15863 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15864 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
f964bd29
UB
15865 (parallel [(set (match_dup 10)
15866 (unspec:XF [(match_dup 9) (match_dup 5)]
15867 UNSPEC_FSCALE_FRACT))
15868 (set (match_dup 11)
15869 (unspec:XF [(match_dup 9) (match_dup 5)]
15870 UNSPEC_FSCALE_EXP))])
15871 (set (match_operand:SF 0 "register_operand" "")
15872 (float_truncate:SF (match_dup 10)))]
ba2baa55 15873 "TARGET_USE_FANCY_MATH_387
9d5b9dae
RS
15874 && flag_unsafe_math_optimizations"
15875{
15876 rtx temp;
15877 int i;
15878
f964bd29 15879 for (i=2; i<12; i++)
9d5b9dae
RS
15880 operands[i] = gen_reg_rtx (XFmode);
15881 temp = standard_80387_constant_rtx (5); /* fldl2e */
15882 emit_move_insn (operands[3], temp);
15883 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15884})
15885
15886(define_expand "expdf2"
15887 [(set (match_dup 2)
15888 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15889 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15890 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15891 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15892 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15893 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
f964bd29
UB
15894 (parallel [(set (match_dup 10)
15895 (unspec:XF [(match_dup 9) (match_dup 5)]
15896 UNSPEC_FSCALE_FRACT))
15897 (set (match_dup 11)
15898 (unspec:XF [(match_dup 9) (match_dup 5)]
15899 UNSPEC_FSCALE_EXP))])
15900 (set (match_operand:DF 0 "register_operand" "")
15901 (float_truncate:DF (match_dup 10)))]
ba2baa55 15902 "TARGET_USE_FANCY_MATH_387
9d5b9dae
RS
15903 && flag_unsafe_math_optimizations"
15904{
15905 rtx temp;
15906 int i;
15907
f964bd29 15908 for (i=2; i<12; i++)
9d5b9dae
RS
15909 operands[i] = gen_reg_rtx (XFmode);
15910 temp = standard_80387_constant_rtx (5); /* fldl2e */
15911 emit_move_insn (operands[3], temp);
15912 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15913})
15914
15915(define_expand "expxf2"
15916 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15917 (match_dup 2)))
15918 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15919 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15920 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15921 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15922 (parallel [(set (match_operand:XF 0 "register_operand" "")
f964bd29
UB
15923 (unspec:XF [(match_dup 8) (match_dup 4)]
15924 UNSPEC_FSCALE_FRACT))
15925 (set (match_dup 9)
15926 (unspec:XF [(match_dup 8) (match_dup 4)]
15927 UNSPEC_FSCALE_EXP))])]
ba2baa55 15928 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15929 && flag_unsafe_math_optimizations"
9d5b9dae
RS
15930{
15931 rtx temp;
15932 int i;
15933
f964bd29 15934 for (i=2; i<10; i++)
9d5b9dae
RS
15935 operands[i] = gen_reg_rtx (XFmode);
15936 temp = standard_80387_constant_rtx (5); /* fldl2e */
15937 emit_move_insn (operands[2], temp);
15938 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15939})
82d397c7 15940
a251102e
UB
15941(define_expand "exp10sf2"
15942 [(set (match_dup 2)
15943 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15944 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15945 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15946 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15947 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15948 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
f964bd29
UB
15949 (parallel [(set (match_dup 10)
15950 (unspec:XF [(match_dup 9) (match_dup 5)]
15951 UNSPEC_FSCALE_FRACT))
15952 (set (match_dup 11)
15953 (unspec:XF [(match_dup 9) (match_dup 5)]
15954 UNSPEC_FSCALE_EXP))])
15955 (set (match_operand:SF 0 "register_operand" "")
15956 (float_truncate:SF (match_dup 10)))]
ba2baa55 15957 "TARGET_USE_FANCY_MATH_387
a251102e
UB
15958 && flag_unsafe_math_optimizations"
15959{
15960 rtx temp;
15961 int i;
15962
f964bd29 15963 for (i=2; i<12; i++)
a251102e
UB
15964 operands[i] = gen_reg_rtx (XFmode);
15965 temp = standard_80387_constant_rtx (6); /* fldl2t */
15966 emit_move_insn (operands[3], temp);
15967 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15968})
15969
15970(define_expand "exp10df2"
15971 [(set (match_dup 2)
15972 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15973 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15974 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15975 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15976 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15977 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
f964bd29
UB
15978 (parallel [(set (match_dup 10)
15979 (unspec:XF [(match_dup 9) (match_dup 5)]
15980 UNSPEC_FSCALE_FRACT))
15981 (set (match_dup 11)
15982 (unspec:XF [(match_dup 9) (match_dup 5)]
15983 UNSPEC_FSCALE_EXP))])
15984 (set (match_operand:DF 0 "register_operand" "")
15985 (float_truncate:DF (match_dup 10)))]
ba2baa55 15986 "TARGET_USE_FANCY_MATH_387
a251102e
UB
15987 && flag_unsafe_math_optimizations"
15988{
15989 rtx temp;
15990 int i;
15991
f964bd29 15992 for (i=2; i<12; i++)
a251102e
UB
15993 operands[i] = gen_reg_rtx (XFmode);
15994 temp = standard_80387_constant_rtx (6); /* fldl2t */
15995 emit_move_insn (operands[3], temp);
15996 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15997})
15998
15999(define_expand "exp10xf2"
16000 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16001 (match_dup 2)))
16002 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16003 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16004 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16005 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16006 (parallel [(set (match_operand:XF 0 "register_operand" "")
f964bd29
UB
16007 (unspec:XF [(match_dup 8) (match_dup 4)]
16008 UNSPEC_FSCALE_FRACT))
16009 (set (match_dup 9)
16010 (unspec:XF [(match_dup 8) (match_dup 4)]
16011 UNSPEC_FSCALE_EXP))])]
ba2baa55 16012 "TARGET_USE_FANCY_MATH_387
a251102e
UB
16013 && flag_unsafe_math_optimizations"
16014{
16015 rtx temp;
16016 int i;
16017
f964bd29 16018 for (i=2; i<10; i++)
a251102e
UB
16019 operands[i] = gen_reg_rtx (XFmode);
16020 temp = standard_80387_constant_rtx (6); /* fldl2t */
16021 emit_move_insn (operands[2], temp);
16022 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16023})
16024
16025(define_expand "exp2sf2"
16026 [(set (match_dup 2)
16027 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16028 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16029 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16030 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16031 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
f964bd29
UB
16032 (parallel [(set (match_dup 8)
16033 (unspec:XF [(match_dup 7) (match_dup 3)]
16034 UNSPEC_FSCALE_FRACT))
16035 (set (match_dup 9)
16036 (unspec:XF [(match_dup 7) (match_dup 3)]
16037 UNSPEC_FSCALE_EXP))])
16038 (set (match_operand:SF 0 "register_operand" "")
16039 (float_truncate:SF (match_dup 8)))]
ba2baa55 16040 "TARGET_USE_FANCY_MATH_387
a251102e
UB
16041 && flag_unsafe_math_optimizations"
16042{
16043 int i;
16044
f964bd29 16045 for (i=2; i<10; i++)
a251102e
UB
16046 operands[i] = gen_reg_rtx (XFmode);
16047 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16048})
16049
16050(define_expand "exp2df2"
16051 [(set (match_dup 2)
16052 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16053 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16054 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16055 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16056 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
f964bd29
UB
16057 (parallel [(set (match_dup 8)
16058 (unspec:XF [(match_dup 7) (match_dup 3)]
16059 UNSPEC_FSCALE_FRACT))
16060 (set (match_dup 9)
16061 (unspec:XF [(match_dup 7) (match_dup 3)]
16062 UNSPEC_FSCALE_EXP))])
16063 (set (match_operand:DF 0 "register_operand" "")
16064 (float_truncate:DF (match_dup 8)))]
ba2baa55 16065 "TARGET_USE_FANCY_MATH_387
a251102e
UB
16066 && flag_unsafe_math_optimizations"
16067{
16068 int i;
16069
f964bd29 16070 for (i=2; i<10; i++)
a251102e
UB
16071 operands[i] = gen_reg_rtx (XFmode);
16072 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16073})
16074
16075(define_expand "exp2xf2"
16076 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16077 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16078 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16079 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16080 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16081 (parallel [(set (match_operand:XF 0 "register_operand" "")
f964bd29
UB
16082 (unspec:XF [(match_dup 7) (match_dup 3)]
16083 UNSPEC_FSCALE_FRACT))
16084 (set (match_dup 8)
16085 (unspec:XF [(match_dup 7) (match_dup 3)]
16086 UNSPEC_FSCALE_EXP))])]
ba2baa55 16087 "TARGET_USE_FANCY_MATH_387
a251102e
UB
16088 && flag_unsafe_math_optimizations"
16089{
16090 int i;
16091
f964bd29 16092 for (i=2; i<9; i++)
a251102e
UB
16093 operands[i] = gen_reg_rtx (XFmode);
16094 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16095})
7a8e07c7
UB
16096
16097(define_expand "expm1df2"
16098 [(set (match_dup 2)
16099 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16100 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16101 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16102 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16103 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16104 (parallel [(set (match_dup 8)
16105 (unspec:XF [(match_dup 7) (match_dup 5)]
16106 UNSPEC_FSCALE_FRACT))
16107 (set (match_dup 9)
16108 (unspec:XF [(match_dup 7) (match_dup 5)]
16109 UNSPEC_FSCALE_EXP))])
16110 (parallel [(set (match_dup 11)
16111 (unspec:XF [(match_dup 10) (match_dup 9)]
16112 UNSPEC_FSCALE_FRACT))
16113 (set (match_dup 12)
16114 (unspec:XF [(match_dup 10) (match_dup 9)]
16115 UNSPEC_FSCALE_EXP))])
16116 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16117 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16118 (set (match_operand:DF 0 "register_operand" "")
16119 (float_truncate:DF (match_dup 14)))]
ba2baa55 16120 "TARGET_USE_FANCY_MATH_387
7a8e07c7
UB
16121 && flag_unsafe_math_optimizations"
16122{
16123 rtx temp;
16124 int i;
16125
16126 for (i=2; i<15; i++)
16127 operands[i] = gen_reg_rtx (XFmode);
16128 temp = standard_80387_constant_rtx (5); /* fldl2e */
16129 emit_move_insn (operands[3], temp);
16130 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16131})
16132
16133(define_expand "expm1sf2"
16134 [(set (match_dup 2)
16135 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16136 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16137 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16138 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16139 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16140 (parallel [(set (match_dup 8)
16141 (unspec:XF [(match_dup 7) (match_dup 5)]
16142 UNSPEC_FSCALE_FRACT))
16143 (set (match_dup 9)
16144 (unspec:XF [(match_dup 7) (match_dup 5)]
16145 UNSPEC_FSCALE_EXP))])
16146 (parallel [(set (match_dup 11)
16147 (unspec:XF [(match_dup 10) (match_dup 9)]
16148 UNSPEC_FSCALE_FRACT))
16149 (set (match_dup 12)
16150 (unspec:XF [(match_dup 10) (match_dup 9)]
16151 UNSPEC_FSCALE_EXP))])
16152 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16153 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16154 (set (match_operand:SF 0 "register_operand" "")
16155 (float_truncate:SF (match_dup 14)))]
ba2baa55 16156 "TARGET_USE_FANCY_MATH_387
7a8e07c7
UB
16157 && flag_unsafe_math_optimizations"
16158{
16159 rtx temp;
16160 int i;
16161
16162 for (i=2; i<15; i++)
16163 operands[i] = gen_reg_rtx (XFmode);
16164 temp = standard_80387_constant_rtx (5); /* fldl2e */
16165 emit_move_insn (operands[3], temp);
16166 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16167})
16168
16169(define_expand "expm1xf2"
16170 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16171 (match_dup 2)))
16172 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16173 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16174 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16175 (parallel [(set (match_dup 7)
16176 (unspec:XF [(match_dup 6) (match_dup 4)]
16177 UNSPEC_FSCALE_FRACT))
16178 (set (match_dup 8)
16179 (unspec:XF [(match_dup 6) (match_dup 4)]
16180 UNSPEC_FSCALE_EXP))])
16181 (parallel [(set (match_dup 10)
16182 (unspec:XF [(match_dup 9) (match_dup 8)]
16183 UNSPEC_FSCALE_FRACT))
16184 (set (match_dup 11)
16185 (unspec:XF [(match_dup 9) (match_dup 8)]
16186 UNSPEC_FSCALE_EXP))])
16187 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16188 (set (match_operand:XF 0 "register_operand" "")
16189 (plus:XF (match_dup 12) (match_dup 7)))]
ba2baa55 16190 "TARGET_USE_FANCY_MATH_387
7a8e07c7
UB
16191 && flag_unsafe_math_optimizations"
16192{
16193 rtx temp;
16194 int i;
16195
16196 for (i=2; i<13; i++)
16197 operands[i] = gen_reg_rtx (XFmode);
16198 temp = standard_80387_constant_rtx (5); /* fldl2e */
16199 emit_move_insn (operands[2], temp);
16200 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16201})
edeacc14
UB
16202\f
16203
16204(define_insn "frndintxf2"
16205 [(set (match_operand:XF 0 "register_operand" "=f")
16206 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16207 UNSPEC_FRNDINT))]
ba2baa55 16208 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16209 && flag_unsafe_math_optimizations"
16210 "frndint"
16211 [(set_attr "type" "fpspc")
16212 (set_attr "mode" "XF")])
16213
16214(define_expand "rintdf2"
16215 [(use (match_operand:DF 0 "register_operand" ""))
16216 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 16217 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16218 && flag_unsafe_math_optimizations"
16219{
16220 rtx op0 = gen_reg_rtx (XFmode);
16221 rtx op1 = gen_reg_rtx (XFmode);
16222
16223 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16224 emit_insn (gen_frndintxf2 (op0, op1));
16225
16226 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16227 DONE;
16228})
16229
16230(define_expand "rintsf2"
16231 [(use (match_operand:SF 0 "register_operand" ""))
16232 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 16233 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16234 && flag_unsafe_math_optimizations"
16235{
16236 rtx op0 = gen_reg_rtx (XFmode);
16237 rtx op1 = gen_reg_rtx (XFmode);
16238
16239 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16240 emit_insn (gen_frndintxf2 (op0, op1));
16241
16242 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16243 DONE;
16244})
16245
16246(define_expand "rintxf2"
16247 [(use (match_operand:XF 0 "register_operand" ""))
16248 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 16249 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16250 && flag_unsafe_math_optimizations"
16251{
16252 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16253 DONE;
16254})
16255
16256(define_insn "frndintxf2_floor"
16257 [(set (match_operand:XF 0 "register_operand" "=f")
16258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16259 UNSPEC_FRNDINT_FLOOR))
16260 (use (match_operand:HI 2 "memory_operand" "m"))
16261 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 16262 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16263 && flag_unsafe_math_optimizations"
16264 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16265 [(set_attr "type" "frndint")
16266 (set_attr "i387_cw" "floor")
16267 (set_attr "mode" "XF")])
16268
16269(define_expand "floordf2"
16270 [(use (match_operand:DF 0 "register_operand" ""))
16271 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 16272 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16273 && flag_unsafe_math_optimizations"
16274{
16275 rtx op0 = gen_reg_rtx (XFmode);
16276 rtx op1 = gen_reg_rtx (XFmode);
16277 rtx op2 = assign_386_stack_local (HImode, 1);
16278 rtx op3 = assign_386_stack_local (HImode, 2);
16279
16280 ix86_optimize_mode_switching = 1;
16281
16282 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16283 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16284
16285 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16286 DONE;
16287})
16288
16289(define_expand "floorsf2"
16290 [(use (match_operand:SF 0 "register_operand" ""))
16291 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 16292 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16293 && flag_unsafe_math_optimizations"
16294{
16295 rtx op0 = gen_reg_rtx (XFmode);
16296 rtx op1 = gen_reg_rtx (XFmode);
16297 rtx op2 = assign_386_stack_local (HImode, 1);
16298 rtx op3 = assign_386_stack_local (HImode, 2);
16299
16300 ix86_optimize_mode_switching = 1;
16301
16302 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16303 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16304
16305 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16306 DONE;
16307})
16308
16309(define_expand "floorxf2"
16310 [(use (match_operand:XF 0 "register_operand" ""))
16311 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 16312 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16313 && flag_unsafe_math_optimizations"
16314{
16315 rtx op2 = assign_386_stack_local (HImode, 1);
16316 rtx op3 = assign_386_stack_local (HImode, 2);
16317
16318 ix86_optimize_mode_switching = 1;
16319
16320 emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16321 DONE;
16322})
16323
16324(define_insn "frndintxf2_ceil"
16325 [(set (match_operand:XF 0 "register_operand" "=f")
16326 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16327 UNSPEC_FRNDINT_CEIL))
16328 (use (match_operand:HI 2 "memory_operand" "m"))
16329 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 16330 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16331 && flag_unsafe_math_optimizations"
16332 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16333 [(set_attr "type" "frndint")
16334 (set_attr "i387_cw" "ceil")
16335 (set_attr "mode" "XF")])
16336
16337(define_expand "ceildf2"
16338 [(use (match_operand:DF 0 "register_operand" ""))
16339 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 16340 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16341 && flag_unsafe_math_optimizations"
16342{
16343 rtx op0 = gen_reg_rtx (XFmode);
16344 rtx op1 = gen_reg_rtx (XFmode);
16345 rtx op2 = assign_386_stack_local (HImode, 1);
16346 rtx op3 = assign_386_stack_local (HImode, 2);
16347
16348 ix86_optimize_mode_switching = 1;
16349
16350 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16351 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16352
16353 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16354 DONE;
16355})
16356
16357(define_expand "ceilsf2"
16358 [(use (match_operand:SF 0 "register_operand" ""))
16359 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 16360 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16361 && flag_unsafe_math_optimizations"
16362{
16363 rtx op0 = gen_reg_rtx (XFmode);
16364 rtx op1 = gen_reg_rtx (XFmode);
16365 rtx op2 = assign_386_stack_local (HImode, 1);
16366 rtx op3 = assign_386_stack_local (HImode, 2);
16367
16368 ix86_optimize_mode_switching = 1;
16369
16370 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16371 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16372
16373 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16374 DONE;
16375})
16376
16377(define_expand "ceilxf2"
16378 [(use (match_operand:XF 0 "register_operand" ""))
16379 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 16380 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16381 && flag_unsafe_math_optimizations"
16382{
16383 rtx op2 = assign_386_stack_local (HImode, 1);
16384 rtx op3 = assign_386_stack_local (HImode, 2);
16385
16386 ix86_optimize_mode_switching = 1;
16387
16388 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16389 DONE;
16390})
16391
16392(define_insn "frndintxf2_trunc"
16393 [(set (match_operand:XF 0 "register_operand" "=f")
16394 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16395 UNSPEC_FRNDINT_TRUNC))
16396 (use (match_operand:HI 2 "memory_operand" "m"))
16397 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 16398 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16399 && flag_unsafe_math_optimizations"
16400 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16401 [(set_attr "type" "frndint")
16402 (set_attr "i387_cw" "trunc")
16403 (set_attr "mode" "XF")])
16404
16405(define_expand "btruncdf2"
16406 [(use (match_operand:DF 0 "register_operand" ""))
16407 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 16408 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16409 && flag_unsafe_math_optimizations"
16410{
16411 rtx op0 = gen_reg_rtx (XFmode);
16412 rtx op1 = gen_reg_rtx (XFmode);
16413 rtx op2 = assign_386_stack_local (HImode, 1);
16414 rtx op3 = assign_386_stack_local (HImode, 2);
16415
16416 ix86_optimize_mode_switching = 1;
16417
16418 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16419 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16420
16421 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16422 DONE;
16423})
16424
16425(define_expand "btruncsf2"
16426 [(use (match_operand:SF 0 "register_operand" ""))
16427 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 16428 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16429 && flag_unsafe_math_optimizations"
16430{
16431 rtx op0 = gen_reg_rtx (XFmode);
16432 rtx op1 = gen_reg_rtx (XFmode);
16433 rtx op2 = assign_386_stack_local (HImode, 1);
16434 rtx op3 = assign_386_stack_local (HImode, 2);
16435
16436 ix86_optimize_mode_switching = 1;
16437
16438 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16439 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16440
16441 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16442 DONE;
16443})
16444
16445(define_expand "btruncxf2"
16446 [(use (match_operand:XF 0 "register_operand" ""))
16447 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 16448 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16449 && flag_unsafe_math_optimizations"
16450{
16451 rtx op2 = assign_386_stack_local (HImode, 1);
16452 rtx op3 = assign_386_stack_local (HImode, 2);
16453
16454 ix86_optimize_mode_switching = 1;
16455
16456 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16457 DONE;
16458})
16459
16460(define_insn "frndintxf2_mask_pm"
16461 [(set (match_operand:XF 0 "register_operand" "=f")
16462 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16463 UNSPEC_FRNDINT_MASK_PM))
16464 (use (match_operand:HI 2 "memory_operand" "m"))
16465 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 16466 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16467 && flag_unsafe_math_optimizations"
16468 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16469 [(set_attr "type" "frndint")
16470 (set_attr "i387_cw" "mask_pm")
16471 (set_attr "mode" "XF")])
16472
16473(define_expand "nearbyintdf2"
16474 [(use (match_operand:DF 0 "register_operand" ""))
16475 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 16476 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16477 && flag_unsafe_math_optimizations"
16478{
16479 rtx op0 = gen_reg_rtx (XFmode);
16480 rtx op1 = gen_reg_rtx (XFmode);
16481 rtx op2 = assign_386_stack_local (HImode, 1);
16482 rtx op3 = assign_386_stack_local (HImode, 2);
16483
16484 ix86_optimize_mode_switching = 1;
16485
16486 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16487 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16488
16489 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16490 DONE;
16491})
16492
16493(define_expand "nearbyintsf2"
16494 [(use (match_operand:SF 0 "register_operand" ""))
16495 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 16496 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16497 && flag_unsafe_math_optimizations"
16498{
16499 rtx op0 = gen_reg_rtx (XFmode);
16500 rtx op1 = gen_reg_rtx (XFmode);
16501 rtx op2 = assign_386_stack_local (HImode, 1);
16502 rtx op3 = assign_386_stack_local (HImode, 2);
16503
16504 ix86_optimize_mode_switching = 1;
16505
16506 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16507 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16508
16509 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16510 DONE;
16511})
16512
16513(define_expand "nearbyintxf2"
16514 [(use (match_operand:XF 0 "register_operand" ""))
16515 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 16516 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16517 && flag_unsafe_math_optimizations"
16518{
16519 rtx op2 = assign_386_stack_local (HImode, 1);
16520 rtx op3 = assign_386_stack_local (HImode, 2);
16521
16522 ix86_optimize_mode_switching = 1;
16523
16524 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16525 op2, op3));
16526 DONE;
16527})
16528
e075ae69
RH
16529\f
16530;; Block operation instructions
886c62d1 16531
7c7ef435 16532(define_insn "cld"
8bc527af 16533 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
7c7ef435
JH
16534 ""
16535 "cld"
16536 [(set_attr "type" "cld")])
16537
70128ad9 16538(define_expand "movmemsi"
f90800f8
JH
16539 [(use (match_operand:BLK 0 "memory_operand" ""))
16540 (use (match_operand:BLK 1 "memory_operand" ""))
79f05c19 16541 (use (match_operand:SI 2 "nonmemory_operand" ""))
f90800f8 16542 (use (match_operand:SI 3 "const_int_operand" ""))]
c43fa1f5 16543 "! optimize_size"
886c62d1 16544{
70128ad9 16545 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
0945b39d
JH
16546 DONE;
16547 else
16548 FAIL;
0f40f9f7 16549})
79f05c19 16550
70128ad9 16551(define_expand "movmemdi"
0945b39d
JH
16552 [(use (match_operand:BLK 0 "memory_operand" ""))
16553 (use (match_operand:BLK 1 "memory_operand" ""))
16554 (use (match_operand:DI 2 "nonmemory_operand" ""))
16555 (use (match_operand:DI 3 "const_int_operand" ""))]
16556 "TARGET_64BIT"
0945b39d 16557{
70128ad9 16558 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
0945b39d
JH
16559 DONE;
16560 else
16561 FAIL;
0f40f9f7 16562})
79f05c19 16563
0945b39d
JH
16564;; Most CPUs don't like single string operations
16565;; Handle this case here to simplify previous expander.
79f05c19 16566
4e44c1ef
JJ
16567(define_expand "strmov"
16568 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16569 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16570 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
8bc527af 16571 (clobber (reg:CC FLAGS_REG))])
4e44c1ef 16572 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
8bc527af 16573 (clobber (reg:CC FLAGS_REG))])]
79f05c19 16574 ""
79f05c19 16575{
4e44c1ef 16576 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
79f05c19 16577
4e44c1ef
JJ
16578 /* If .md ever supports :P for Pmode, these can be directly
16579 in the pattern above. */
16580 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16581 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
0945b39d 16582
f90800f8 16583 if (TARGET_SINGLE_STRINGOP || optimize_size)
886c62d1 16584 {
4e44c1ef
JJ
16585 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16586 operands[2], operands[3],
16587 operands[5], operands[6]));
f90800f8
JH
16588 DONE;
16589 }
886c62d1 16590
4e44c1ef 16591 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
0f40f9f7 16592})
f90800f8 16593
4e44c1ef
JJ
16594(define_expand "strmov_singleop"
16595 [(parallel [(set (match_operand 1 "memory_operand" "")
16596 (match_operand 3 "memory_operand" ""))
16597 (set (match_operand 0 "register_operand" "")
16598 (match_operand 4 "" ""))
16599 (set (match_operand 2 "register_operand" "")
16600 (match_operand 5 "" ""))
8bc527af 16601 (use (reg:SI DIRFLAG_REG))])]
4e44c1ef
JJ
16602 "TARGET_SINGLE_STRINGOP || optimize_size"
16603 "")
0945b39d 16604
4e44c1ef 16605(define_insn "*strmovdi_rex_1"
0945b39d
JH
16606 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16607 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16608 (set (match_operand:DI 0 "register_operand" "=D")
16609 (plus:DI (match_dup 2)
16610 (const_int 8)))
16611 (set (match_operand:DI 1 "register_operand" "=S")
16612 (plus:DI (match_dup 3)
16613 (const_int 8)))
8bc527af 16614 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16615 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16616 "movsq"
16617 [(set_attr "type" "str")
16618 (set_attr "mode" "DI")
16619 (set_attr "memory" "both")])
16620
4e44c1ef 16621(define_insn "*strmovsi_1"
79f05c19
JH
16622 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16623 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16624 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16625 (plus:SI (match_dup 2)
79f05c19
JH
16626 (const_int 4)))
16627 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 16628 (plus:SI (match_dup 3)
79f05c19 16629 (const_int 4)))
8bc527af 16630 (use (reg:SI DIRFLAG_REG))]
0945b39d 16631 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
371bc54b 16632 "{movsl|movsd}"
0945b39d
JH
16633 [(set_attr "type" "str")
16634 (set_attr "mode" "SI")
16635 (set_attr "memory" "both")])
16636
4e44c1ef 16637(define_insn "*strmovsi_rex_1"
0945b39d
JH
16638 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16639 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16640 (set (match_operand:DI 0 "register_operand" "=D")
16641 (plus:DI (match_dup 2)
16642 (const_int 4)))
16643 (set (match_operand:DI 1 "register_operand" "=S")
16644 (plus:DI (match_dup 3)
16645 (const_int 4)))
8bc527af 16646 (use (reg:SI DIRFLAG_REG))]
0945b39d 16647 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
371bc54b 16648 "{movsl|movsd}"
79f05c19 16649 [(set_attr "type" "str")
6ef67412 16650 (set_attr "mode" "SI")
79f05c19
JH
16651 (set_attr "memory" "both")])
16652
4e44c1ef 16653(define_insn "*strmovhi_1"
f90800f8
JH
16654 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16655 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16656 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16657 (plus:SI (match_dup 2)
f90800f8
JH
16658 (const_int 2)))
16659 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 16660 (plus:SI (match_dup 3)
f90800f8 16661 (const_int 2)))
8bc527af 16662 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16663 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16664 "movsw"
16665 [(set_attr "type" "str")
16666 (set_attr "memory" "both")
16667 (set_attr "mode" "HI")])
16668
4e44c1ef 16669(define_insn "*strmovhi_rex_1"
0945b39d
JH
16670 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16671 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16672 (set (match_operand:DI 0 "register_operand" "=D")
16673 (plus:DI (match_dup 2)
16674 (const_int 2)))
16675 (set (match_operand:DI 1 "register_operand" "=S")
16676 (plus:DI (match_dup 3)
16677 (const_int 2)))
8bc527af 16678 (use (reg:SI DIRFLAG_REG))]
0945b39d 16679 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
f90800f8
JH
16680 "movsw"
16681 [(set_attr "type" "str")
16682 (set_attr "memory" "both")
6ef67412 16683 (set_attr "mode" "HI")])
f90800f8 16684
4e44c1ef 16685(define_insn "*strmovqi_1"
f90800f8
JH
16686 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16687 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16688 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16689 (plus:SI (match_dup 2)
f90800f8
JH
16690 (const_int 1)))
16691 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 16692 (plus:SI (match_dup 3)
f90800f8 16693 (const_int 1)))
8bc527af 16694 (use (reg:SI DIRFLAG_REG))]
0945b39d 16695 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
f90800f8
JH
16696 "movsb"
16697 [(set_attr "type" "str")
6ef67412
JH
16698 (set_attr "memory" "both")
16699 (set_attr "mode" "QI")])
f90800f8 16700
4e44c1ef 16701(define_insn "*strmovqi_rex_1"
0945b39d
JH
16702 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16703 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16704 (set (match_operand:DI 0 "register_operand" "=D")
16705 (plus:DI (match_dup 2)
16706 (const_int 1)))
16707 (set (match_operand:DI 1 "register_operand" "=S")
16708 (plus:DI (match_dup 3)
16709 (const_int 1)))
8bc527af 16710 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16711 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16712 "movsb"
16713 [(set_attr "type" "str")
16714 (set_attr "memory" "both")
16715 (set_attr "mode" "QI")])
16716
4e44c1ef
JJ
16717(define_expand "rep_mov"
16718 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16719 (set (match_operand 0 "register_operand" "")
16720 (match_operand 5 "" ""))
16721 (set (match_operand 2 "register_operand" "")
16722 (match_operand 6 "" ""))
16723 (set (match_operand 1 "memory_operand" "")
16724 (match_operand 3 "memory_operand" ""))
16725 (use (match_dup 4))
8bc527af 16726 (use (reg:SI DIRFLAG_REG))])]
4e44c1ef
JJ
16727 ""
16728 "")
16729
16730(define_insn "*rep_movdi_rex64"
0945b39d
JH
16731 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16732 (set (match_operand:DI 0 "register_operand" "=D")
16733 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16734 (const_int 3))
16735 (match_operand:DI 3 "register_operand" "0")))
16736 (set (match_operand:DI 1 "register_operand" "=S")
16737 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16738 (match_operand:DI 4 "register_operand" "1")))
16739 (set (mem:BLK (match_dup 3))
16740 (mem:BLK (match_dup 4)))
16741 (use (match_dup 5))
8bc527af 16742 (use (reg:SI DIRFLAG_REG))]
0945b39d 16743 "TARGET_64BIT"
8554d9a4 16744 "{rep\;movsq|rep movsq}"
0945b39d
JH
16745 [(set_attr "type" "str")
16746 (set_attr "prefix_rep" "1")
16747 (set_attr "memory" "both")
16748 (set_attr "mode" "DI")])
16749
4e44c1ef 16750(define_insn "*rep_movsi"
f90800f8 16751 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
f90800f8 16752 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
16753 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16754 (const_int 2))
16755 (match_operand:SI 3 "register_operand" "0")))
f90800f8 16756 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb
JH
16757 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16758 (match_operand:SI 4 "register_operand" "1")))
f90800f8
JH
16759 (set (mem:BLK (match_dup 3))
16760 (mem:BLK (match_dup 4)))
b1cdafbb 16761 (use (match_dup 5))
8bc527af 16762 (use (reg:SI DIRFLAG_REG))]
0945b39d 16763 "!TARGET_64BIT"
8554d9a4 16764 "{rep\;movsl|rep movsd}"
0945b39d
JH
16765 [(set_attr "type" "str")
16766 (set_attr "prefix_rep" "1")
16767 (set_attr "memory" "both")
16768 (set_attr "mode" "SI")])
16769
4e44c1ef 16770(define_insn "*rep_movsi_rex64"
0945b39d
JH
16771 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16772 (set (match_operand:DI 0 "register_operand" "=D")
16773 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16774 (const_int 2))
16775 (match_operand:DI 3 "register_operand" "0")))
16776 (set (match_operand:DI 1 "register_operand" "=S")
16777 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16778 (match_operand:DI 4 "register_operand" "1")))
16779 (set (mem:BLK (match_dup 3))
16780 (mem:BLK (match_dup 4)))
16781 (use (match_dup 5))
8bc527af 16782 (use (reg:SI DIRFLAG_REG))]
0945b39d 16783 "TARGET_64BIT"
8554d9a4 16784 "{rep\;movsl|rep movsd}"
f90800f8 16785 [(set_attr "type" "str")
6ef67412
JH
16786 (set_attr "prefix_rep" "1")
16787 (set_attr "memory" "both")
16788 (set_attr "mode" "SI")])
f90800f8 16789
4e44c1ef 16790(define_insn "*rep_movqi"
f90800f8 16791 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
f90800f8 16792 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
16793 (plus:SI (match_operand:SI 3 "register_operand" "0")
16794 (match_operand:SI 5 "register_operand" "2")))
f90800f8 16795 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 16796 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
f90800f8
JH
16797 (set (mem:BLK (match_dup 3))
16798 (mem:BLK (match_dup 4)))
b1cdafbb 16799 (use (match_dup 5))
8bc527af 16800 (use (reg:SI DIRFLAG_REG))]
0945b39d 16801 "!TARGET_64BIT"
8554d9a4 16802 "{rep\;movsb|rep movsb}"
0945b39d
JH
16803 [(set_attr "type" "str")
16804 (set_attr "prefix_rep" "1")
16805 (set_attr "memory" "both")
16806 (set_attr "mode" "SI")])
16807
4e44c1ef 16808(define_insn "*rep_movqi_rex64"
0945b39d
JH
16809 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16810 (set (match_operand:DI 0 "register_operand" "=D")
16811 (plus:DI (match_operand:DI 3 "register_operand" "0")
16812 (match_operand:DI 5 "register_operand" "2")))
16813 (set (match_operand:DI 1 "register_operand" "=S")
16814 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16815 (set (mem:BLK (match_dup 3))
16816 (mem:BLK (match_dup 4)))
16817 (use (match_dup 5))
8bc527af 16818 (use (reg:SI DIRFLAG_REG))]
0945b39d 16819 "TARGET_64BIT"
8554d9a4 16820 "{rep\;movsb|rep movsb}"
f90800f8 16821 [(set_attr "type" "str")
6ef67412
JH
16822 (set_attr "prefix_rep" "1")
16823 (set_attr "memory" "both")
16824 (set_attr "mode" "SI")])
886c62d1 16825
70128ad9 16826(define_expand "clrmemsi"
e2e52e1b 16827 [(use (match_operand:BLK 0 "memory_operand" ""))
79f05c19 16828 (use (match_operand:SI 1 "nonmemory_operand" ""))
0945b39d 16829 (use (match_operand 2 "const_int_operand" ""))]
0ae40045 16830 ""
0ae40045 16831{
70128ad9 16832 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
0945b39d
JH
16833 DONE;
16834 else
16835 FAIL;
0f40f9f7 16836})
e2e52e1b 16837
70128ad9 16838(define_expand "clrmemdi"
0945b39d
JH
16839 [(use (match_operand:BLK 0 "memory_operand" ""))
16840 (use (match_operand:DI 1 "nonmemory_operand" ""))
16841 (use (match_operand 2 "const_int_operand" ""))]
16842 "TARGET_64BIT"
0945b39d 16843{
70128ad9 16844 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
0945b39d
JH
16845 DONE;
16846 else
16847 FAIL;
0f40f9f7 16848})
e2e52e1b 16849
0945b39d
JH
16850;; Most CPUs don't like single string operations
16851;; Handle this case here to simplify previous expander.
79f05c19 16852
4e44c1ef
JJ
16853(define_expand "strset"
16854 [(set (match_operand 1 "memory_operand" "")
16855 (match_operand 2 "register_operand" ""))
16856 (parallel [(set (match_operand 0 "register_operand" "")
16857 (match_dup 3))
8bc527af 16858 (clobber (reg:CC FLAGS_REG))])]
79f05c19 16859 ""
79f05c19 16860{
4e44c1ef
JJ
16861 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16862 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
79f05c19 16863
4e44c1ef
JJ
16864 /* If .md ever supports :P for Pmode, this can be directly
16865 in the pattern above. */
16866 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16867 GEN_INT (GET_MODE_SIZE (GET_MODE
16868 (operands[2]))));
0945b39d
JH
16869 if (TARGET_SINGLE_STRINGOP || optimize_size)
16870 {
4e44c1ef
JJ
16871 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16872 operands[3]));
0945b39d
JH
16873 DONE;
16874 }
0f40f9f7 16875})
0945b39d 16876
4e44c1ef
JJ
16877(define_expand "strset_singleop"
16878 [(parallel [(set (match_operand 1 "memory_operand" "")
16879 (match_operand 2 "register_operand" ""))
16880 (set (match_operand 0 "register_operand" "")
16881 (match_operand 3 "" ""))
8bc527af 16882 (use (reg:SI DIRFLAG_REG))])]
4e44c1ef
JJ
16883 "TARGET_SINGLE_STRINGOP || optimize_size"
16884 "")
0945b39d 16885
4e44c1ef 16886(define_insn "*strsetdi_rex_1"
22116d84
L
16887 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16888 (match_operand:DI 2 "register_operand" "a"))
0945b39d
JH
16889 (set (match_operand:DI 0 "register_operand" "=D")
16890 (plus:DI (match_dup 1)
16891 (const_int 8)))
8bc527af 16892 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16893 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16894 "stosq"
16895 [(set_attr "type" "str")
16896 (set_attr "memory" "store")
16897 (set_attr "mode" "DI")])
16898
4e44c1ef 16899(define_insn "*strsetsi_1"
79f05c19
JH
16900 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16901 (match_operand:SI 2 "register_operand" "a"))
16902 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16903 (plus:SI (match_dup 1)
79f05c19 16904 (const_int 4)))
8bc527af 16905 (use (reg:SI DIRFLAG_REG))]
0945b39d 16906 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
8554d9a4 16907 "{stosl|stosd}"
0945b39d
JH
16908 [(set_attr "type" "str")
16909 (set_attr "memory" "store")
16910 (set_attr "mode" "SI")])
16911
4e44c1ef 16912(define_insn "*strsetsi_rex_1"
0945b39d
JH
16913 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16914 (match_operand:SI 2 "register_operand" "a"))
16915 (set (match_operand:DI 0 "register_operand" "=D")
16916 (plus:DI (match_dup 1)
16917 (const_int 4)))
8bc527af 16918 (use (reg:SI DIRFLAG_REG))]
0945b39d 16919 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
8554d9a4 16920 "{stosl|stosd}"
79f05c19 16921 [(set_attr "type" "str")
6ef67412
JH
16922 (set_attr "memory" "store")
16923 (set_attr "mode" "SI")])
79f05c19 16924
4e44c1ef 16925(define_insn "*strsethi_1"
e2e52e1b
JH
16926 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16927 (match_operand:HI 2 "register_operand" "a"))
16928 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16929 (plus:SI (match_dup 1)
e2e52e1b 16930 (const_int 2)))
8bc527af 16931 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16932 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16933 "stosw"
16934 [(set_attr "type" "str")
16935 (set_attr "memory" "store")
16936 (set_attr "mode" "HI")])
16937
4e44c1ef 16938(define_insn "*strsethi_rex_1"
0945b39d
JH
16939 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16940 (match_operand:HI 2 "register_operand" "a"))
16941 (set (match_operand:DI 0 "register_operand" "=D")
16942 (plus:DI (match_dup 1)
16943 (const_int 2)))
8bc527af 16944 (use (reg:SI DIRFLAG_REG))]
0945b39d 16945 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
e2e52e1b
JH
16946 "stosw"
16947 [(set_attr "type" "str")
16948 (set_attr "memory" "store")
6ef67412 16949 (set_attr "mode" "HI")])
e2e52e1b 16950
4e44c1ef 16951(define_insn "*strsetqi_1"
e2e52e1b
JH
16952 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16953 (match_operand:QI 2 "register_operand" "a"))
16954 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16955 (plus:SI (match_dup 1)
e2e52e1b 16956 (const_int 1)))
8bc527af 16957 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16958 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16959 "stosb"
16960 [(set_attr "type" "str")
16961 (set_attr "memory" "store")
16962 (set_attr "mode" "QI")])
16963
4e44c1ef 16964(define_insn "*strsetqi_rex_1"
0945b39d
JH
16965 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16966 (match_operand:QI 2 "register_operand" "a"))
16967 (set (match_operand:DI 0 "register_operand" "=D")
16968 (plus:DI (match_dup 1)
16969 (const_int 1)))
8bc527af 16970 (use (reg:SI DIRFLAG_REG))]
0945b39d 16971 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
e2e52e1b
JH
16972 "stosb"
16973 [(set_attr "type" "str")
6ef67412
JH
16974 (set_attr "memory" "store")
16975 (set_attr "mode" "QI")])
e2e52e1b 16976
4e44c1ef
JJ
16977(define_expand "rep_stos"
16978 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16979 (set (match_operand 0 "register_operand" "")
16980 (match_operand 4 "" ""))
16981 (set (match_operand 2 "memory_operand" "") (const_int 0))
16982 (use (match_operand 3 "register_operand" ""))
16983 (use (match_dup 1))
8bc527af 16984 (use (reg:SI DIRFLAG_REG))])]
4e44c1ef
JJ
16985 ""
16986 "")
16987
16988(define_insn "*rep_stosdi_rex64"
0945b39d
JH
16989 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16990 (set (match_operand:DI 0 "register_operand" "=D")
16991 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16992 (const_int 3))
16993 (match_operand:DI 3 "register_operand" "0")))
16994 (set (mem:BLK (match_dup 3))
16995 (const_int 0))
16996 (use (match_operand:DI 2 "register_operand" "a"))
16997 (use (match_dup 4))
8bc527af 16998 (use (reg:SI DIRFLAG_REG))]
0945b39d 16999 "TARGET_64BIT"
8554d9a4 17000 "{rep\;stosq|rep stosq}"
0945b39d
JH
17001 [(set_attr "type" "str")
17002 (set_attr "prefix_rep" "1")
17003 (set_attr "memory" "store")
17004 (set_attr "mode" "DI")])
17005
4e44c1ef 17006(define_insn "*rep_stossi"
e2e52e1b 17007 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
e2e52e1b 17008 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
17009 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17010 (const_int 2))
17011 (match_operand:SI 3 "register_operand" "0")))
e2e52e1b 17012 (set (mem:BLK (match_dup 3))
0ae40045 17013 (const_int 0))
b1cdafbb
JH
17014 (use (match_operand:SI 2 "register_operand" "a"))
17015 (use (match_dup 4))
8bc527af 17016 (use (reg:SI DIRFLAG_REG))]
0945b39d 17017 "!TARGET_64BIT"
8554d9a4 17018 "{rep\;stosl|rep stosd}"
0945b39d
JH
17019 [(set_attr "type" "str")
17020 (set_attr "prefix_rep" "1")
17021 (set_attr "memory" "store")
17022 (set_attr "mode" "SI")])
17023
4e44c1ef 17024(define_insn "*rep_stossi_rex64"
0945b39d
JH
17025 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17026 (set (match_operand:DI 0 "register_operand" "=D")
17027 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17028 (const_int 2))
17029 (match_operand:DI 3 "register_operand" "0")))
17030 (set (mem:BLK (match_dup 3))
17031 (const_int 0))
17032 (use (match_operand:SI 2 "register_operand" "a"))
17033 (use (match_dup 4))
8bc527af 17034 (use (reg:SI DIRFLAG_REG))]
0945b39d 17035 "TARGET_64BIT"
8554d9a4 17036 "{rep\;stosl|rep stosd}"
e2e52e1b 17037 [(set_attr "type" "str")
6ef67412
JH
17038 (set_attr "prefix_rep" "1")
17039 (set_attr "memory" "store")
17040 (set_attr "mode" "SI")])
0ae40045 17041
4e44c1ef 17042(define_insn "*rep_stosqi"
e2e52e1b 17043 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
e2e52e1b 17044 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
17045 (plus:SI (match_operand:SI 3 "register_operand" "0")
17046 (match_operand:SI 4 "register_operand" "1")))
e2e52e1b
JH
17047 (set (mem:BLK (match_dup 3))
17048 (const_int 0))
b1cdafbb
JH
17049 (use (match_operand:QI 2 "register_operand" "a"))
17050 (use (match_dup 4))
8bc527af 17051 (use (reg:SI DIRFLAG_REG))]
0945b39d 17052 "!TARGET_64BIT"
8554d9a4 17053 "{rep\;stosb|rep stosb}"
0945b39d
JH
17054 [(set_attr "type" "str")
17055 (set_attr "prefix_rep" "1")
17056 (set_attr "memory" "store")
17057 (set_attr "mode" "QI")])
17058
4e44c1ef 17059(define_insn "*rep_stosqi_rex64"
0945b39d
JH
17060 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17061 (set (match_operand:DI 0 "register_operand" "=D")
17062 (plus:DI (match_operand:DI 3 "register_operand" "0")
17063 (match_operand:DI 4 "register_operand" "1")))
17064 (set (mem:BLK (match_dup 3))
17065 (const_int 0))
17066 (use (match_operand:QI 2 "register_operand" "a"))
17067 (use (match_dup 4))
8bc527af 17068 (use (reg:SI DIRFLAG_REG))]
0945b39d 17069 "TARGET_64BIT"
8554d9a4 17070 "{rep\;stosb|rep stosb}"
e2e52e1b 17071 [(set_attr "type" "str")
6ef67412
JH
17072 (set_attr "prefix_rep" "1")
17073 (set_attr "memory" "store")
17074 (set_attr "mode" "QI")])
0ae40045 17075
886c62d1 17076(define_expand "cmpstrsi"
e075ae69
RH
17077 [(set (match_operand:SI 0 "register_operand" "")
17078 (compare:SI (match_operand:BLK 1 "general_operand" "")
17079 (match_operand:BLK 2 "general_operand" "")))
0945b39d
JH
17080 (use (match_operand 3 "general_operand" ""))
17081 (use (match_operand 4 "immediate_operand" ""))]
87383233 17082 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
886c62d1 17083{
e075ae69
RH
17084 rtx addr1, addr2, out, outlow, count, countreg, align;
17085
d0a5295a
RH
17086 /* Can't use this if the user has appropriated esi or edi. */
17087 if (global_regs[4] || global_regs[5])
17088 FAIL;
17089
e075ae69
RH
17090 out = operands[0];
17091 if (GET_CODE (out) != REG)
17092 out = gen_reg_rtx (SImode);
783cdf65
JVA
17093
17094 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17095 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
4e44c1ef
JJ
17096 if (addr1 != XEXP (operands[1], 0))
17097 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17098 if (addr2 != XEXP (operands[2], 0))
17099 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17100
e075ae69 17101 count = operands[3];
d24b3457 17102 countreg = ix86_zero_extend_to_Pmode (count);
e075ae69
RH
17103
17104 /* %%% Iff we are testing strict equality, we can use known alignment
17105 to good advantage. This may be possible with combine, particularly
17106 once cc0 is dead. */
17107 align = operands[4];
783cdf65 17108
7c7ef435 17109 emit_insn (gen_cld ());
e075ae69
RH
17110 if (GET_CODE (count) == CONST_INT)
17111 {
17112 if (INTVAL (count) == 0)
17113 {
17114 emit_move_insn (operands[0], const0_rtx);
17115 DONE;
17116 }
4e44c1ef
JJ
17117 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17118 operands[1], operands[2]));
e075ae69
RH
17119 }
17120 else
e2e52e1b 17121 {
0945b39d 17122 if (TARGET_64BIT)
4e44c1ef 17123 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
0945b39d 17124 else
4e44c1ef
JJ
17125 emit_insn (gen_cmpsi_1 (countreg, countreg));
17126 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17127 operands[1], operands[2]));
e2e52e1b 17128 }
e075ae69
RH
17129
17130 outlow = gen_lowpart (QImode, out);
17131 emit_insn (gen_cmpintqi (outlow));
17132 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
783cdf65 17133
e075ae69
RH
17134 if (operands[0] != out)
17135 emit_move_insn (operands[0], out);
783cdf65 17136
e075ae69 17137 DONE;
0f40f9f7 17138})
886c62d1 17139
e075ae69
RH
17140;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17141
17142(define_expand "cmpintqi"
17143 [(set (match_dup 1)
8bc527af 17144 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
e075ae69 17145 (set (match_dup 2)
8bc527af 17146 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
e075ae69
RH
17147 (parallel [(set (match_operand:QI 0 "register_operand" "")
17148 (minus:QI (match_dup 1)
17149 (match_dup 2)))
8bc527af 17150 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
17151 ""
17152 "operands[1] = gen_reg_rtx (QImode);
17153 operands[2] = gen_reg_rtx (QImode);")
17154
f76e3b05
JVA
17155;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17156;; zero. Emit extra code to make sure that a zero-length compare is EQ.
56c0e8fa 17157
4e44c1ef 17158(define_expand "cmpstrqi_nz_1"
8bc527af 17159 [(parallel [(set (reg:CC FLAGS_REG)
4e44c1ef
JJ
17160 (compare:CC (match_operand 4 "memory_operand" "")
17161 (match_operand 5 "memory_operand" "")))
17162 (use (match_operand 2 "register_operand" ""))
17163 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af 17164 (use (reg:SI DIRFLAG_REG))
4e44c1ef
JJ
17165 (clobber (match_operand 0 "register_operand" ""))
17166 (clobber (match_operand 1 "register_operand" ""))
17167 (clobber (match_dup 2))])]
17168 ""
17169 "")
17170
17171(define_insn "*cmpstrqi_nz_1"
8bc527af 17172 [(set (reg:CC FLAGS_REG)
b1cdafbb
JH
17173 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17174 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17175 (use (match_operand:SI 6 "register_operand" "2"))
886c62d1 17176 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af 17177 (use (reg:SI DIRFLAG_REG))
b1cdafbb
JH
17178 (clobber (match_operand:SI 0 "register_operand" "=S"))
17179 (clobber (match_operand:SI 1 "register_operand" "=D"))
17180 (clobber (match_operand:SI 2 "register_operand" "=c"))]
0945b39d
JH
17181 "!TARGET_64BIT"
17182 "repz{\;| }cmpsb"
17183 [(set_attr "type" "str")
17184 (set_attr "mode" "QI")
17185 (set_attr "prefix_rep" "1")])
17186
4e44c1ef 17187(define_insn "*cmpstrqi_nz_rex_1"
8bc527af 17188 [(set (reg:CC FLAGS_REG)
0945b39d
JH
17189 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17190 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17191 (use (match_operand:DI 6 "register_operand" "2"))
17192 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af 17193 (use (reg:SI DIRFLAG_REG))
0945b39d
JH
17194 (clobber (match_operand:DI 0 "register_operand" "=S"))
17195 (clobber (match_operand:DI 1 "register_operand" "=D"))
17196 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17197 "TARGET_64BIT"
7c7ef435 17198 "repz{\;| }cmpsb"
e2e52e1b 17199 [(set_attr "type" "str")
6ef67412
JH
17200 (set_attr "mode" "QI")
17201 (set_attr "prefix_rep" "1")])
886c62d1 17202
e075ae69 17203;; The same, but the count is not known to not be zero.
886c62d1 17204
4e44c1ef 17205(define_expand "cmpstrqi_1"
8bc527af 17206 [(parallel [(set (reg:CC FLAGS_REG)
4e44c1ef
JJ
17207 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17208 (const_int 0))
17209 (compare:CC (match_operand 4 "memory_operand" "")
17210 (match_operand 5 "memory_operand" ""))
17211 (const_int 0)))
17212 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af
SB
17213 (use (reg:CC FLAGS_REG))
17214 (use (reg:SI DIRFLAG_REG))
4e44c1ef
JJ
17215 (clobber (match_operand 0 "register_operand" ""))
17216 (clobber (match_operand 1 "register_operand" ""))
17217 (clobber (match_dup 2))])]
17218 ""
17219 "")
17220
17221(define_insn "*cmpstrqi_1"
8bc527af 17222 [(set (reg:CC FLAGS_REG)
b1cdafbb 17223 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
e075ae69 17224 (const_int 0))
2bed3391 17225 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
b1cdafbb 17226 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
e075ae69
RH
17227 (const_int 0)))
17228 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af
SB
17229 (use (reg:CC FLAGS_REG))
17230 (use (reg:SI DIRFLAG_REG))
b1cdafbb
JH
17231 (clobber (match_operand:SI 0 "register_operand" "=S"))
17232 (clobber (match_operand:SI 1 "register_operand" "=D"))
17233 (clobber (match_operand:SI 2 "register_operand" "=c"))]
0945b39d
JH
17234 "!TARGET_64BIT"
17235 "repz{\;| }cmpsb"
17236 [(set_attr "type" "str")
17237 (set_attr "mode" "QI")
17238 (set_attr "prefix_rep" "1")])
17239
4e44c1ef 17240(define_insn "*cmpstrqi_rex_1"
8bc527af 17241 [(set (reg:CC FLAGS_REG)
0945b39d
JH
17242 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17243 (const_int 0))
17244 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17245 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17246 (const_int 0)))
17247 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af
SB
17248 (use (reg:CC FLAGS_REG))
17249 (use (reg:SI DIRFLAG_REG))
0945b39d
JH
17250 (clobber (match_operand:DI 0 "register_operand" "=S"))
17251 (clobber (match_operand:DI 1 "register_operand" "=D"))
17252 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17253 "TARGET_64BIT"
e2e52e1b
JH
17254 "repz{\;| }cmpsb"
17255 [(set_attr "type" "str")
6ef67412
JH
17256 (set_attr "mode" "QI")
17257 (set_attr "prefix_rep" "1")])
886c62d1 17258
e075ae69
RH
17259(define_expand "strlensi"
17260 [(set (match_operand:SI 0 "register_operand" "")
17261 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17262 (match_operand:QI 2 "immediate_operand" "")
8ee41eaf 17263 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
886c62d1 17264 ""
886c62d1 17265{
0945b39d
JH
17266 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17267 DONE;
17268 else
17269 FAIL;
0f40f9f7 17270})
e075ae69 17271
0945b39d
JH
17272(define_expand "strlendi"
17273 [(set (match_operand:DI 0 "register_operand" "")
17274 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17275 (match_operand:QI 2 "immediate_operand" "")
8ee41eaf 17276 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
0945b39d 17277 ""
0945b39d
JH
17278{
17279 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17280 DONE;
17281 else
17282 FAIL;
0f40f9f7 17283})
19c3fc24 17284
4e44c1ef
JJ
17285(define_expand "strlenqi_1"
17286 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
8bc527af 17287 (use (reg:SI DIRFLAG_REG))
4e44c1ef 17288 (clobber (match_operand 1 "register_operand" ""))
8bc527af 17289 (clobber (reg:CC FLAGS_REG))])]
4e44c1ef
JJ
17290 ""
17291 "")
17292
17293(define_insn "*strlenqi_1"
e075ae69 17294 [(set (match_operand:SI 0 "register_operand" "=&c")
b1cdafbb 17295 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
0945b39d 17296 (match_operand:QI 2 "register_operand" "a")
e075ae69 17297 (match_operand:SI 3 "immediate_operand" "i")
8ee41eaf 17298 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
8bc527af 17299 (use (reg:SI DIRFLAG_REG))
b1cdafbb 17300 (clobber (match_operand:SI 1 "register_operand" "=D"))
8bc527af 17301 (clobber (reg:CC FLAGS_REG))]
0945b39d
JH
17302 "!TARGET_64BIT"
17303 "repnz{\;| }scasb"
17304 [(set_attr "type" "str")
17305 (set_attr "mode" "QI")
17306 (set_attr "prefix_rep" "1")])
17307
4e44c1ef 17308(define_insn "*strlenqi_rex_1"
0945b39d
JH
17309 [(set (match_operand:DI 0 "register_operand" "=&c")
17310 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17311 (match_operand:QI 2 "register_operand" "a")
17312 (match_operand:DI 3 "immediate_operand" "i")
8ee41eaf 17313 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
8bc527af 17314 (use (reg:SI DIRFLAG_REG))
0945b39d 17315 (clobber (match_operand:DI 1 "register_operand" "=D"))
8bc527af 17316 (clobber (reg:CC FLAGS_REG))]
0945b39d 17317 "TARGET_64BIT"
7c7ef435 17318 "repnz{\;| }scasb"
e2e52e1b 17319 [(set_attr "type" "str")
6ef67412
JH
17320 (set_attr "mode" "QI")
17321 (set_attr "prefix_rep" "1")])
a3e991f2
ZW
17322
17323;; Peephole optimizations to clean up after cmpstr*. This should be
17324;; handled in combine, but it is not currently up to the task.
17325;; When used for their truth value, the cmpstr* expanders generate
17326;; code like this:
17327;;
17328;; repz cmpsb
17329;; seta %al
17330;; setb %dl
17331;; cmpb %al, %dl
17332;; jcc label
17333;;
17334;; The intermediate three instructions are unnecessary.
17335
17336;; This one handles cmpstr*_nz_1...
17337(define_peephole2
17338 [(parallel[
8bc527af 17339 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
17340 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17341 (mem:BLK (match_operand 5 "register_operand" ""))))
17342 (use (match_operand 6 "register_operand" ""))
17343 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af 17344 (use (reg:SI DIRFLAG_REG))
a3e991f2
ZW
17345 (clobber (match_operand 0 "register_operand" ""))
17346 (clobber (match_operand 1 "register_operand" ""))
17347 (clobber (match_operand 2 "register_operand" ""))])
17348 (set (match_operand:QI 7 "register_operand" "")
8bc527af 17349 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
a3e991f2 17350 (set (match_operand:QI 8 "register_operand" "")
8bc527af 17351 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
42fabf21 17352 (set (reg FLAGS_REG)
a3e991f2
ZW
17353 (compare (match_dup 7) (match_dup 8)))
17354 ]
244ec848 17355 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
a3e991f2 17356 [(parallel[
8bc527af 17357 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
17358 (compare:CC (mem:BLK (match_dup 4))
17359 (mem:BLK (match_dup 5))))
17360 (use (match_dup 6))
17361 (use (match_dup 3))
8bc527af 17362 (use (reg:SI DIRFLAG_REG))
a3e991f2
ZW
17363 (clobber (match_dup 0))
17364 (clobber (match_dup 1))
244ec848 17365 (clobber (match_dup 2))])]
a3e991f2
ZW
17366 "")
17367
17368;; ...and this one handles cmpstr*_1.
17369(define_peephole2
17370 [(parallel[
8bc527af 17371 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
17372 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17373 (const_int 0))
17374 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17375 (mem:BLK (match_operand 5 "register_operand" "")))
17376 (const_int 0)))
17377 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af
SB
17378 (use (reg:CC FLAGS_REG))
17379 (use (reg:SI DIRFLAG_REG))
a3e991f2
ZW
17380 (clobber (match_operand 0 "register_operand" ""))
17381 (clobber (match_operand 1 "register_operand" ""))
17382 (clobber (match_operand 2 "register_operand" ""))])
17383 (set (match_operand:QI 7 "register_operand" "")
8bc527af 17384 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
a3e991f2 17385 (set (match_operand:QI 8 "register_operand" "")
8bc527af 17386 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
42fabf21 17387 (set (reg FLAGS_REG)
a3e991f2
ZW
17388 (compare (match_dup 7) (match_dup 8)))
17389 ]
244ec848 17390 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
a3e991f2 17391 [(parallel[
8bc527af 17392 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
17393 (if_then_else:CC (ne (match_dup 6)
17394 (const_int 0))
17395 (compare:CC (mem:BLK (match_dup 4))
17396 (mem:BLK (match_dup 5)))
17397 (const_int 0)))
17398 (use (match_dup 3))
8bc527af
SB
17399 (use (reg:CC FLAGS_REG))
17400 (use (reg:SI DIRFLAG_REG))
a3e991f2
ZW
17401 (clobber (match_dup 0))
17402 (clobber (match_dup 1))
244ec848 17403 (clobber (match_dup 2))])]
a3e991f2
ZW
17404 "")
17405
17406
e075ae69
RH
17407\f
17408;; Conditional move instructions.
726e2d54 17409
44cf5b6a 17410(define_expand "movdicc"
885a70fd
JH
17411 [(set (match_operand:DI 0 "register_operand" "")
17412 (if_then_else:DI (match_operand 1 "comparison_operator" "")
44cf5b6a
JH
17413 (match_operand:DI 2 "general_operand" "")
17414 (match_operand:DI 3 "general_operand" "")))]
885a70fd
JH
17415 "TARGET_64BIT"
17416 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17417
e74061a9 17418(define_insn "x86_movdicc_0_m1_rex64"
885a70fd 17419 [(set (match_operand:DI 0 "register_operand" "=r")
e6e81735 17420 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
885a70fd
JH
17421 (const_int -1)
17422 (const_int 0)))
8bc527af 17423 (clobber (reg:CC FLAGS_REG))]
885a70fd 17424 "TARGET_64BIT"
0f40f9f7 17425 "sbb{q}\t%0, %0"
885a70fd
JH
17426 ; Since we don't have the proper number of operands for an alu insn,
17427 ; fill in all the blanks.
17428 [(set_attr "type" "alu")
890d52e8 17429 (set_attr "pent_pair" "pu")
885a70fd
JH
17430 (set_attr "memory" "none")
17431 (set_attr "imm_disp" "false")
17432 (set_attr "mode" "DI")
17433 (set_attr "length_immediate" "0")])
17434
e6e81735 17435(define_insn "movdicc_c_rex64"
885a70fd
JH
17436 [(set (match_operand:DI 0 "register_operand" "=r,r")
17437 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
42fabf21 17438 [(reg FLAGS_REG) (const_int 0)])
885a70fd
JH
17439 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17440 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17441 "TARGET_64BIT && TARGET_CMOVE
17442 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17443 "@
048b1c95
JJ
17444 cmov%O2%C1\t{%2, %0|%0, %2}
17445 cmov%O2%c1\t{%3, %0|%0, %3}"
885a70fd
JH
17446 [(set_attr "type" "icmov")
17447 (set_attr "mode" "DI")])
17448
e075ae69 17449(define_expand "movsicc"
6a4a5d95 17450 [(set (match_operand:SI 0 "register_operand" "")
e075ae69
RH
17451 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17452 (match_operand:SI 2 "general_operand" "")
17453 (match_operand:SI 3 "general_operand" "")))]
17454 ""
17455 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
726e2d54 17456
e075ae69
RH
17457;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17458;; the register first winds up with `sbbl $0,reg', which is also weird.
17459;; So just document what we're doing explicitly.
17460
17461(define_insn "x86_movsicc_0_m1"
17462 [(set (match_operand:SI 0 "register_operand" "=r")
e6e81735 17463 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
e075ae69
RH
17464 (const_int -1)
17465 (const_int 0)))
8bc527af 17466 (clobber (reg:CC FLAGS_REG))]
e075ae69 17467 ""
0f40f9f7 17468 "sbb{l}\t%0, %0"
e075ae69
RH
17469 ; Since we don't have the proper number of operands for an alu insn,
17470 ; fill in all the blanks.
17471 [(set_attr "type" "alu")
890d52e8 17472 (set_attr "pent_pair" "pu")
e075ae69
RH
17473 (set_attr "memory" "none")
17474 (set_attr "imm_disp" "false")
6ef67412
JH
17475 (set_attr "mode" "SI")
17476 (set_attr "length_immediate" "0")])
e075ae69 17477
6343a50e 17478(define_insn "*movsicc_noc"
e075ae69 17479 [(set (match_operand:SI 0 "register_operand" "=r,r")
9076b9c1 17480 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
42fabf21 17481 [(reg FLAGS_REG) (const_int 0)])
e075ae69
RH
17482 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17483 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
d525dfdf
JH
17484 "TARGET_CMOVE
17485 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 17486 "@
048b1c95
JJ
17487 cmov%O2%C1\t{%2, %0|%0, %2}
17488 cmov%O2%c1\t{%3, %0|%0, %3}"
6ef67412
JH
17489 [(set_attr "type" "icmov")
17490 (set_attr "mode" "SI")])
726e2d54 17491
726e2d54
JW
17492(define_expand "movhicc"
17493 [(set (match_operand:HI 0 "register_operand" "")
17494 (if_then_else:HI (match_operand 1 "comparison_operator" "")
4977bab6
ZW
17495 (match_operand:HI 2 "general_operand" "")
17496 (match_operand:HI 3 "general_operand" "")))]
17497 "TARGET_HIMODE_MATH"
e075ae69 17498 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
726e2d54 17499
6343a50e 17500(define_insn "*movhicc_noc"
e075ae69 17501 [(set (match_operand:HI 0 "register_operand" "=r,r")
9076b9c1 17502 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
42fabf21 17503 [(reg FLAGS_REG) (const_int 0)])
e075ae69
RH
17504 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17505 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
d525dfdf
JH
17506 "TARGET_CMOVE
17507 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 17508 "@
048b1c95
JJ
17509 cmov%O2%C1\t{%2, %0|%0, %2}
17510 cmov%O2%c1\t{%3, %0|%0, %3}"
6ef67412
JH
17511 [(set_attr "type" "icmov")
17512 (set_attr "mode" "HI")])
726e2d54 17513
4977bab6
ZW
17514(define_expand "movqicc"
17515 [(set (match_operand:QI 0 "register_operand" "")
17516 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17517 (match_operand:QI 2 "general_operand" "")
17518 (match_operand:QI 3 "general_operand" "")))]
17519 "TARGET_QIMODE_MATH"
17520 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17521
17522(define_insn_and_split "*movqicc_noc"
17523 [(set (match_operand:QI 0 "register_operand" "=r,r")
17524 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17525 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17526 (match_operand:QI 2 "register_operand" "r,0")
17527 (match_operand:QI 3 "register_operand" "0,r")))]
17528 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17529 "#"
17530 "&& reload_completed"
17531 [(set (match_dup 0)
17532 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17533 (match_dup 2)
17534 (match_dup 3)))]
17535 "operands[0] = gen_lowpart (SImode, operands[0]);
17536 operands[2] = gen_lowpart (SImode, operands[2]);
17537 operands[3] = gen_lowpart (SImode, operands[3]);"
17538 [(set_attr "type" "icmov")
17539 (set_attr "mode" "SI")])
17540
56710e42 17541(define_expand "movsfcc"
726e2d54 17542 [(set (match_operand:SF 0 "register_operand" "")
56710e42 17543 (if_then_else:SF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
17544 (match_operand:SF 2 "register_operand" "")
17545 (match_operand:SF 3 "register_operand" "")))]
726e2d54 17546 "TARGET_CMOVE"
e075ae69 17547 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
726e2d54 17548
6343a50e 17549(define_insn "*movsfcc_1"
f380a0ce 17550 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
e075ae69 17551 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
42fabf21 17552 [(reg FLAGS_REG) (const_int 0)])
f380a0ce
JH
17553 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17554 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
7093c9ea
JH
17555 "TARGET_CMOVE
17556 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 17557 "@
0f40f9f7
ZW
17558 fcmov%F1\t{%2, %0|%0, %2}
17559 fcmov%f1\t{%3, %0|%0, %3}
048b1c95
JJ
17560 cmov%O2%C1\t{%2, %0|%0, %2}
17561 cmov%O2%c1\t{%3, %0|%0, %3}"
7093c9ea
JH
17562 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17563 (set_attr "mode" "SF,SF,SI,SI")])
56710e42
SC
17564
17565(define_expand "movdfcc"
726e2d54 17566 [(set (match_operand:DF 0 "register_operand" "")
56710e42 17567 (if_then_else:DF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
17568 (match_operand:DF 2 "register_operand" "")
17569 (match_operand:DF 3 "register_operand" "")))]
726e2d54 17570 "TARGET_CMOVE"
e075ae69 17571 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
726e2d54 17572
6343a50e 17573(define_insn "*movdfcc_1"
f380a0ce 17574 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
e075ae69 17575 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
42fabf21 17576 [(reg FLAGS_REG) (const_int 0)])
f380a0ce
JH
17577 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17578 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
1b0c37d7 17579 "!TARGET_64BIT && TARGET_CMOVE
7093c9ea 17580 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 17581 "@
0f40f9f7
ZW
17582 fcmov%F1\t{%2, %0|%0, %2}
17583 fcmov%f1\t{%3, %0|%0, %3}
7093c9ea
JH
17584 #
17585 #"
17586 [(set_attr "type" "fcmov,fcmov,multi,multi")
6ef67412 17587 (set_attr "mode" "DF")])
56710e42 17588
1e07edd3 17589(define_insn "*movdfcc_1_rex64"
cd48dadc 17590 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
1e07edd3 17591 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
42fabf21 17592 [(reg FLAGS_REG) (const_int 0)])
f380a0ce
JH
17593 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17594 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
1b0c37d7 17595 "TARGET_64BIT && TARGET_CMOVE
1e07edd3
JH
17596 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17597 "@
0f40f9f7
ZW
17598 fcmov%F1\t{%2, %0|%0, %2}
17599 fcmov%f1\t{%3, %0|%0, %3}
048b1c95
JJ
17600 cmov%O2%C1\t{%2, %0|%0, %2}
17601 cmov%O2%c1\t{%3, %0|%0, %3}"
1e07edd3
JH
17602 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17603 (set_attr "mode" "DF")])
17604
7093c9ea 17605(define_split
c3c637e3 17606 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
7093c9ea 17607 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
4977bab6 17608 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
7093c9ea
JH
17609 (match_operand:DF 2 "nonimmediate_operand" "")
17610 (match_operand:DF 3 "nonimmediate_operand" "")))]
c3c637e3 17611 "!TARGET_64BIT && reload_completed"
7093c9ea
JH
17612 [(set (match_dup 2)
17613 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17614 (match_dup 5)
17615 (match_dup 7)))
17616 (set (match_dup 3)
17617 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17618 (match_dup 6)
17619 (match_dup 8)))]
17620 "split_di (operands+2, 1, operands+5, operands+6);
17621 split_di (operands+3, 1, operands+7, operands+8);
17622 split_di (operands, 1, operands+2, operands+3);")
17623
56710e42 17624(define_expand "movxfcc"
726e2d54 17625 [(set (match_operand:XF 0 "register_operand" "")
56710e42 17626 (if_then_else:XF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
17627 (match_operand:XF 2 "register_operand" "")
17628 (match_operand:XF 3 "register_operand" "")))]
2b589241
JH
17629 "TARGET_CMOVE"
17630 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17631
6343a50e 17632(define_insn "*movxfcc_1"
3aeae608 17633 [(set (match_operand:XF 0 "register_operand" "=f,f")
e075ae69 17634 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
42fabf21 17635 [(reg FLAGS_REG) (const_int 0)])
3aeae608
JW
17636 (match_operand:XF 2 "register_operand" "f,0")
17637 (match_operand:XF 3 "register_operand" "0,f")))]
2b589241
JH
17638 "TARGET_CMOVE"
17639 "@
0f40f9f7
ZW
17640 fcmov%F1\t{%2, %0|%0, %2}
17641 fcmov%f1\t{%3, %0|%0, %3}"
2b589241
JH
17642 [(set_attr "type" "fcmov")
17643 (set_attr "mode" "XF")])
7ada6625
JH
17644
17645(define_expand "minsf3"
17646 [(parallel [
17647 (set (match_operand:SF 0 "register_operand" "")
17648 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17649 (match_operand:SF 2 "nonimmediate_operand" ""))
17650 (match_dup 1)
17651 (match_dup 2)))
8bc527af 17652 (clobber (reg:CC FLAGS_REG))])]
7ada6625
JH
17653 "TARGET_SSE"
17654 "")
17655
17656(define_insn "*minsf"
17657 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17658 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17659 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17660 (match_dup 1)
17661 (match_dup 2)))
8bc527af 17662 (clobber (reg:CC FLAGS_REG))]
7ada6625
JH
17663 "TARGET_SSE && TARGET_IEEE_FP"
17664 "#")
17665
17666(define_insn "*minsf_nonieee"
17667 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
558740bf 17668 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
3987b9db 17669 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
7ada6625
JH
17670 (match_dup 1)
17671 (match_dup 2)))
8bc527af 17672 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
17673 "TARGET_SSE && !TARGET_IEEE_FP
17674 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7ada6625
JH
17675 "#")
17676
17677(define_split
17678 [(set (match_operand:SF 0 "register_operand" "")
17679 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17680 (match_operand:SF 2 "nonimmediate_operand" ""))
138b7342
JH
17681 (match_operand:SF 3 "register_operand" "")
17682 (match_operand:SF 4 "nonimmediate_operand" "")))
8bc527af 17683 (clobber (reg:CC FLAGS_REG))]
ef6257cd
JH
17684 "SSE_REG_P (operands[0]) && reload_completed
17685 && ((operands_match_p (operands[1], operands[3])
17686 && operands_match_p (operands[2], operands[4]))
17687 || (operands_match_p (operands[1], operands[4])
17688 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
17689 [(set (match_dup 0)
17690 (if_then_else:SF (lt (match_dup 1)
17691 (match_dup 2))
17692 (match_dup 1)
17693 (match_dup 2)))])
17694
7b52eede
JH
17695;; Conditional addition patterns
17696(define_expand "addqicc"
17697 [(match_operand:QI 0 "register_operand" "")
17698 (match_operand 1 "comparison_operator" "")
17699 (match_operand:QI 2 "register_operand" "")
17700 (match_operand:QI 3 "const_int_operand" "")]
17701 ""
17702 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17703
17704(define_expand "addhicc"
17705 [(match_operand:HI 0 "register_operand" "")
17706 (match_operand 1 "comparison_operator" "")
17707 (match_operand:HI 2 "register_operand" "")
17708 (match_operand:HI 3 "const_int_operand" "")]
17709 ""
17710 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17711
17712(define_expand "addsicc"
17713 [(match_operand:SI 0 "register_operand" "")
17714 (match_operand 1 "comparison_operator" "")
17715 (match_operand:SI 2 "register_operand" "")
17716 (match_operand:SI 3 "const_int_operand" "")]
17717 ""
17718 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17719
17720(define_expand "adddicc"
17721 [(match_operand:DI 0 "register_operand" "")
17722 (match_operand 1 "comparison_operator" "")
17723 (match_operand:DI 2 "register_operand" "")
17724 (match_operand:DI 3 "const_int_operand" "")]
17725 "TARGET_64BIT"
17726 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17727
7ada6625 17728;; We can't represent the LT test directly. Do this by swapping the operands.
ef6257cd 17729
7ada6625 17730(define_split
c3c637e3 17731 [(set (match_operand:SF 0 "fp_register_operand" "")
7ada6625
JH
17732 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17733 (match_operand:SF 2 "register_operand" ""))
14d920c0
JH
17734 (match_operand:SF 3 "register_operand" "")
17735 (match_operand:SF 4 "register_operand" "")))
8bc527af 17736 (clobber (reg:CC FLAGS_REG))]
c3c637e3 17737 "reload_completed
ef6257cd
JH
17738 && ((operands_match_p (operands[1], operands[3])
17739 && operands_match_p (operands[2], operands[4]))
17740 || (operands_match_p (operands[1], operands[4])
17741 && operands_match_p (operands[2], operands[3])))"
8bc527af 17742 [(set (reg:CCFP FLAGS_REG)
7ada6625
JH
17743 (compare:CCFP (match_dup 2)
17744 (match_dup 1)))
17745 (set (match_dup 0)
8bc527af 17746 (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
7ada6625
JH
17747 (match_dup 1)
17748 (match_dup 2)))])
17749
17750(define_insn "*minsf_sse"
17751 [(set (match_operand:SF 0 "register_operand" "=x")
17752 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17753 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17754 (match_dup 1)
17755 (match_dup 2)))]
17756 "TARGET_SSE && reload_completed"
0f40f9f7 17757 "minss\t{%2, %0|%0, %2}"
7ada6625
JH
17758 [(set_attr "type" "sse")
17759 (set_attr "mode" "SF")])
17760
17761(define_expand "mindf3"
17762 [(parallel [
17763 (set (match_operand:DF 0 "register_operand" "")
17764 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17765 (match_operand:DF 2 "nonimmediate_operand" ""))
17766 (match_dup 1)
17767 (match_dup 2)))
8bc527af 17768 (clobber (reg:CC FLAGS_REG))])]
965f5423 17769 "TARGET_SSE2 && TARGET_SSE_MATH"
7ada6625
JH
17770 "#")
17771
17772(define_insn "*mindf"
17773 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17774 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17775 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17776 (match_dup 1)
17777 (match_dup 2)))
8bc527af 17778 (clobber (reg:CC FLAGS_REG))]
965f5423 17779 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
7ada6625
JH
17780 "#")
17781
17782(define_insn "*mindf_nonieee"
17783 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
558740bf 17784 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
3987b9db 17785 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
7ada6625
JH
17786 (match_dup 1)
17787 (match_dup 2)))
8bc527af 17788 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
17789 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17790 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7ada6625
JH
17791 "#")
17792
17793(define_split
17794 [(set (match_operand:DF 0 "register_operand" "")
17795 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17796 (match_operand:DF 2 "nonimmediate_operand" ""))
ef6257cd
JH
17797 (match_operand:DF 3 "register_operand" "")
17798 (match_operand:DF 4 "nonimmediate_operand" "")))
8bc527af 17799 (clobber (reg:CC FLAGS_REG))]
ef6257cd
JH
17800 "SSE_REG_P (operands[0]) && reload_completed
17801 && ((operands_match_p (operands[1], operands[3])
17802 && operands_match_p (operands[2], operands[4]))
17803 || (operands_match_p (operands[1], operands[4])
17804 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
17805 [(set (match_dup 0)
17806 (if_then_else:DF (lt (match_dup 1)
17807 (match_dup 2))
17808 (match_dup 1)
17809 (match_dup 2)))])
17810
17811;; We can't represent the LT test directly. Do this by swapping the operands.
17812(define_split
c3c637e3 17813 [(set (match_operand:DF 0 "fp_register_operand" "")
7ada6625
JH
17814 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17815 (match_operand:DF 2 "register_operand" ""))
ef6257cd
JH
17816 (match_operand:DF 3 "register_operand" "")
17817 (match_operand:DF 4 "register_operand" "")))
8bc527af 17818 (clobber (reg:CC FLAGS_REG))]
c3c637e3 17819 "reload_completed
ef6257cd
JH
17820 && ((operands_match_p (operands[1], operands[3])
17821 && operands_match_p (operands[2], operands[4]))
17822 || (operands_match_p (operands[1], operands[4])
17823 && operands_match_p (operands[2], operands[3])))"
8bc527af 17824 [(set (reg:CCFP FLAGS_REG)
7ada6625 17825 (compare:CCFP (match_dup 2)
86b40947 17826 (match_dup 1)))
7ada6625 17827 (set (match_dup 0)
8bc527af 17828 (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
7ada6625
JH
17829 (match_dup 1)
17830 (match_dup 2)))])
17831
17832(define_insn "*mindf_sse"
17833 [(set (match_operand:DF 0 "register_operand" "=Y")
17834 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17835 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17836 (match_dup 1)
17837 (match_dup 2)))]
965f5423 17838 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
0f40f9f7 17839 "minsd\t{%2, %0|%0, %2}"
7ada6625
JH
17840 [(set_attr "type" "sse")
17841 (set_attr "mode" "DF")])
17842
17843(define_expand "maxsf3"
17844 [(parallel [
17845 (set (match_operand:SF 0 "register_operand" "")
17846 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17847 (match_operand:SF 2 "nonimmediate_operand" ""))
17848 (match_dup 1)
17849 (match_dup 2)))
8bc527af 17850 (clobber (reg:CC FLAGS_REG))])]
7ada6625
JH
17851 "TARGET_SSE"
17852 "#")
17853
17854(define_insn "*maxsf"
17855 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17856 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
3987b9db 17857 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
7ada6625
JH
17858 (match_dup 1)
17859 (match_dup 2)))
8bc527af 17860 (clobber (reg:CC FLAGS_REG))]
7ada6625
JH
17861 "TARGET_SSE && TARGET_IEEE_FP"
17862 "#")
17863
17864(define_insn "*maxsf_nonieee"
17865 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
558740bf 17866 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
3987b9db 17867 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
7ada6625
JH
17868 (match_dup 1)
17869 (match_dup 2)))
8bc527af 17870 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
17871 "TARGET_SSE && !TARGET_IEEE_FP
17872 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7ada6625
JH
17873 "#")
17874
17875(define_split
17876 [(set (match_operand:SF 0 "register_operand" "")
17877 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17878 (match_operand:SF 2 "nonimmediate_operand" ""))
ef6257cd
JH
17879 (match_operand:SF 3 "register_operand" "")
17880 (match_operand:SF 4 "nonimmediate_operand" "")))
8bc527af 17881 (clobber (reg:CC FLAGS_REG))]
ef6257cd
JH
17882 "SSE_REG_P (operands[0]) && reload_completed
17883 && ((operands_match_p (operands[1], operands[3])
17884 && operands_match_p (operands[2], operands[4]))
17885 || (operands_match_p (operands[1], operands[4])
17886 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
17887 [(set (match_dup 0)
17888 (if_then_else:SF (gt (match_dup 1)
17889 (match_dup 2))
17890 (match_dup 1)
17891 (match_dup 2)))])
17892
17893(define_split
c3c637e3 17894 [(set (match_operand:SF 0 "fp_register_operand" "")
7ada6625
JH
17895 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17896 (match_operand:SF 2 "register_operand" ""))
ef6257cd
JH
17897 (match_operand:SF 3 "register_operand" "")
17898 (match_operand:SF 4 "register_operand" "")))
8bc527af 17899 (clobber (reg:CC FLAGS_REG))]
c3c637e3 17900 "reload_completed
ef6257cd
JH
17901 && ((operands_match_p (operands[1], operands[3])
17902 && operands_match_p (operands[2], operands[4]))
17903 || (operands_match_p (operands[1], operands[4])
17904 && operands_match_p (operands[2], operands[3])))"
8bc527af 17905 [(set (reg:CCFP FLAGS_REG)
7ada6625
JH
17906 (compare:CCFP (match_dup 1)
17907 (match_dup 2)))
17908 (set (match_dup 0)
8bc527af 17909 (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
7ada6625
JH
17910 (match_dup 1)
17911 (match_dup 2)))])
17912
17913(define_insn "*maxsf_sse"
17914 [(set (match_operand:SF 0 "register_operand" "=x")
17915 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17916 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17917 (match_dup 1)
17918 (match_dup 2)))]
17919 "TARGET_SSE && reload_completed"
0f40f9f7 17920 "maxss\t{%2, %0|%0, %2}"
7ada6625
JH
17921 [(set_attr "type" "sse")
17922 (set_attr "mode" "SF")])
17923
17924(define_expand "maxdf3"
17925 [(parallel [
17926 (set (match_operand:DF 0 "register_operand" "")
17927 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17928 (match_operand:DF 2 "nonimmediate_operand" ""))
17929 (match_dup 1)
17930 (match_dup 2)))
8bc527af 17931 (clobber (reg:CC FLAGS_REG))])]
965f5423 17932 "TARGET_SSE2 && TARGET_SSE_MATH"
7ada6625
JH
17933 "#")
17934
17935(define_insn "*maxdf"
17936 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17937 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
3987b9db 17938 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
7ada6625
JH
17939 (match_dup 1)
17940 (match_dup 2)))
8bc527af 17941 (clobber (reg:CC FLAGS_REG))]
965f5423 17942 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
7ada6625
JH
17943 "#")
17944
17945(define_insn "*maxdf_nonieee"
17946 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
558740bf 17947 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
3987b9db 17948 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
7ada6625
JH
17949 (match_dup 1)
17950 (match_dup 2)))
8bc527af 17951 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
17952 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17953 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7ada6625
JH
17954 "#")
17955
17956(define_split
17957 [(set (match_operand:DF 0 "register_operand" "")
17958 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17959 (match_operand:DF 2 "nonimmediate_operand" ""))
ef6257cd
JH
17960 (match_operand:DF 3 "register_operand" "")
17961 (match_operand:DF 4 "nonimmediate_operand" "")))
8bc527af 17962 (clobber (reg:CC FLAGS_REG))]
ef6257cd
JH
17963 "SSE_REG_P (operands[0]) && reload_completed
17964 && ((operands_match_p (operands[1], operands[3])
17965 && operands_match_p (operands[2], operands[4]))
17966 || (operands_match_p (operands[1], operands[4])
17967 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
17968 [(set (match_dup 0)
17969 (if_then_else:DF (gt (match_dup 1)
17970 (match_dup 2))
17971 (match_dup 1)
17972 (match_dup 2)))])
17973
17974(define_split
c3c637e3 17975 [(set (match_operand:DF 0 "fp_register_operand" "")
7ada6625
JH
17976 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17977 (match_operand:DF 2 "register_operand" ""))
ef6257cd
JH
17978 (match_operand:DF 3 "register_operand" "")
17979 (match_operand:DF 4 "register_operand" "")))
8bc527af 17980 (clobber (reg:CC FLAGS_REG))]
c3c637e3 17981 "reload_completed
ef6257cd
JH
17982 && ((operands_match_p (operands[1], operands[3])
17983 && operands_match_p (operands[2], operands[4]))
17984 || (operands_match_p (operands[1], operands[4])
17985 && operands_match_p (operands[2], operands[3])))"
8bc527af 17986 [(set (reg:CCFP FLAGS_REG)
7ada6625
JH
17987 (compare:CCFP (match_dup 1)
17988 (match_dup 2)))
17989 (set (match_dup 0)
8bc527af 17990 (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
7ada6625
JH
17991 (match_dup 1)
17992 (match_dup 2)))])
17993
17994(define_insn "*maxdf_sse"
17995 [(set (match_operand:DF 0 "register_operand" "=Y")
17996 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17997 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17998 (match_dup 1)
17999 (match_dup 2)))]
965f5423 18000 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
0f40f9f7 18001 "maxsd\t{%2, %0|%0, %2}"
7ada6625
JH
18002 [(set_attr "type" "sse")
18003 (set_attr "mode" "DF")])
e075ae69
RH
18004\f
18005;; Misc patterns (?)
726e2d54 18006
f5143c46 18007;; This pattern exists to put a dependency on all ebp-based memory accesses.
e075ae69
RH
18008;; Otherwise there will be nothing to keep
18009;;
18010;; [(set (reg ebp) (reg esp))]
18011;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18012;; (clobber (eflags)]
18013;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18014;;
18015;; in proper program order.
b19ee4bd 18016(define_insn "pro_epilogue_adjust_stack_1"
1c71e60e
JH
18017 [(set (match_operand:SI 0 "register_operand" "=r,r")
18018 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18019 (match_operand:SI 2 "immediate_operand" "i,i")))
8bc527af 18020 (clobber (reg:CC FLAGS_REG))
f2042df3 18021 (clobber (mem:BLK (scratch)))]
8362f420 18022 "!TARGET_64BIT"
e075ae69 18023{
1c71e60e 18024 switch (get_attr_type (insn))
e075ae69 18025 {
1c71e60e 18026 case TYPE_IMOV:
0f40f9f7 18027 return "mov{l}\t{%1, %0|%0, %1}";
1c71e60e
JH
18028
18029 case TYPE_ALU:
18030 if (GET_CODE (operands[2]) == CONST_INT
18031 && (INTVAL (operands[2]) == 128
18032 || (INTVAL (operands[2]) < 0
18033 && INTVAL (operands[2]) != -128)))
18034 {
18035 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 18036 return "sub{l}\t{%2, %0|%0, %2}";
1c71e60e 18037 }
0f40f9f7 18038 return "add{l}\t{%2, %0|%0, %2}";
1c71e60e
JH
18039
18040 case TYPE_LEA:
18041 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 18042 return "lea{l}\t{%a2, %0|%0, %a2}";
1c71e60e
JH
18043
18044 default:
18045 abort ();
e075ae69 18046 }
0f40f9f7 18047}
1c71e60e
JH
18048 [(set (attr "type")
18049 (cond [(eq_attr "alternative" "0")
18050 (const_string "alu")
18051 (match_operand:SI 2 "const0_operand" "")
18052 (const_string "imov")
18053 ]
6ef67412
JH
18054 (const_string "lea")))
18055 (set_attr "mode" "SI")])
578b58f5 18056
8362f420
JH
18057(define_insn "pro_epilogue_adjust_stack_rex64"
18058 [(set (match_operand:DI 0 "register_operand" "=r,r")
18059 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18060 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
8bc527af 18061 (clobber (reg:CC FLAGS_REG))
f2042df3 18062 (clobber (mem:BLK (scratch)))]
8362f420 18063 "TARGET_64BIT"
8362f420
JH
18064{
18065 switch (get_attr_type (insn))
18066 {
18067 case TYPE_IMOV:
0f40f9f7 18068 return "mov{q}\t{%1, %0|%0, %1}";
8362f420
JH
18069
18070 case TYPE_ALU:
18071 if (GET_CODE (operands[2]) == CONST_INT
b19ee4bd
JJ
18072 /* Avoid overflows. */
18073 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
8362f420
JH
18074 && (INTVAL (operands[2]) == 128
18075 || (INTVAL (operands[2]) < 0
18076 && INTVAL (operands[2]) != -128)))
18077 {
18078 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 18079 return "sub{q}\t{%2, %0|%0, %2}";
8362f420 18080 }
0f40f9f7 18081 return "add{q}\t{%2, %0|%0, %2}";
8362f420
JH
18082
18083 case TYPE_LEA:
18084 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 18085 return "lea{q}\t{%a2, %0|%0, %a2}";
8362f420
JH
18086
18087 default:
18088 abort ();
18089 }
0f40f9f7 18090}
8362f420
JH
18091 [(set (attr "type")
18092 (cond [(eq_attr "alternative" "0")
18093 (const_string "alu")
18094 (match_operand:DI 2 "const0_operand" "")
18095 (const_string "imov")
18096 ]
18097 (const_string "lea")))
18098 (set_attr "mode" "DI")])
18099
b19ee4bd
JJ
18100(define_insn "pro_epilogue_adjust_stack_rex64_2"
18101 [(set (match_operand:DI 0 "register_operand" "=r,r")
18102 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18103 (match_operand:DI 3 "immediate_operand" "i,i")))
18104 (use (match_operand:DI 2 "register_operand" "r,r"))
8bc527af 18105 (clobber (reg:CC FLAGS_REG))
b19ee4bd
JJ
18106 (clobber (mem:BLK (scratch)))]
18107 "TARGET_64BIT"
18108{
18109 switch (get_attr_type (insn))
18110 {
18111 case TYPE_ALU:
18112 return "add{q}\t{%2, %0|%0, %2}";
18113
18114 case TYPE_LEA:
18115 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18116 return "lea{q}\t{%a2, %0|%0, %a2}";
18117
18118 default:
18119 abort ();
18120 }
18121}
18122 [(set_attr "type" "alu,lea")
18123 (set_attr "mode" "DI")])
8362f420 18124
d6a7951f 18125;; Placeholder for the conditional moves. This one is split either to SSE
0073023d
JH
18126;; based moves emulation or to usual cmove sequence. Little bit unfortunate
18127;; fact is that compares supported by the cmp??ss instructions are exactly
18128;; swapped of those supported by cmove sequence.
fa9f36a1
JH
18129;; The EQ/NE comparisons also needs bit care, since they are not directly
18130;; supported by i387 comparisons and we do need to emit two conditional moves
18131;; in tandem.
0073023d
JH
18132
18133(define_insn "sse_movsfcc"
18134 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
18135 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
44aefada
JH
18136 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
18137 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
0073023d
JH
18138 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
18139 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
bf71a4f8 18140 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
8bc527af 18141 (clobber (reg:CC FLAGS_REG))]
fa9f36a1
JH
18142 "TARGET_SSE
18143 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
4977bab6
ZW
18144 /* Avoid combine from being smart and converting min/max
18145 instruction patterns into conditional moves. */
18146 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18147 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18148 || !rtx_equal_p (operands[4], operands[2])
18149 || !rtx_equal_p (operands[5], operands[3]))
fa9f36a1
JH
18150 && (!TARGET_IEEE_FP
18151 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18152 "#")
18153
18154(define_insn "sse_movsfcc_eq"
18155 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
44aefada
JH
18156 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18157 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
fa9f36a1
JH
18158 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18159 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
f021d6fc 18160 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
8bc527af 18161 (clobber (reg:CC FLAGS_REG))]
0073023d
JH
18162 "TARGET_SSE
18163 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18164 "#")
18165
18166(define_insn "sse_movdfcc"
66b408f2 18167 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
0073023d 18168 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
66b408f2
JJ
18169 [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
18170 (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
18171 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
18172 (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
bf71a4f8 18173 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
8bc527af 18174 (clobber (reg:CC FLAGS_REG))]
0073023d 18175 "TARGET_SSE2
fa9f36a1 18176 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
4977bab6
ZW
18177 /* Avoid combine from being smart and converting min/max
18178 instruction patterns into conditional moves. */
18179 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18180 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18181 || !rtx_equal_p (operands[4], operands[2])
18182 || !rtx_equal_p (operands[5], operands[3]))
fa9f36a1
JH
18183 && (!TARGET_IEEE_FP
18184 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18185 "#")
18186
18187(define_insn "sse_movdfcc_eq"
66b408f2
JJ
18188 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18189 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18190 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18191 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18192 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
fa9f36a1 18193 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
8bc527af 18194 (clobber (reg:CC FLAGS_REG))]
fa9f36a1 18195 "TARGET_SSE
0073023d
JH
18196 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18197 "#")
18198
18199;; For non-sse moves just expand the usual cmove sequence.
18200(define_split
18201 [(set (match_operand 0 "register_operand" "")
18202 (if_then_else (match_operator 1 "comparison_operator"
18203 [(match_operand 4 "nonimmediate_operand" "")
44aefada 18204 (match_operand 5 "register_operand" "")])
0073023d
JH
18205 (match_operand 2 "nonimmediate_operand" "")
18206 (match_operand 3 "nonimmediate_operand" "")))
18207 (clobber (match_operand 6 "" ""))
8bc527af 18208 (clobber (reg:CC FLAGS_REG))]
0073023d
JH
18209 "!SSE_REG_P (operands[0]) && reload_completed
18210 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18211 [(const_int 0)]
0073023d
JH
18212{
18213 ix86_compare_op0 = operands[5];
18214 ix86_compare_op1 = operands[4];
18215 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18216 VOIDmode, operands[5], operands[4]);
18217 ix86_expand_fp_movcc (operands);
18218 DONE;
0f40f9f7 18219})
0073023d 18220
d1f87653 18221;; Split SSE based conditional move into sequence:
0073023d
JH
18222;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
18223;; and op2, op0 - zero op2 if comparison was false
18224;; nand op0, op3 - load op3 to op0 if comparison was false
9cd10576 18225;; or op2, op0 - get the nonzero one into the result.
0073023d 18226(define_split
79ae63b1 18227 [(set (match_operand:SF 0 "register_operand" "")
0022b96a
RH
18228 (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18229 [(match_operand:SF 4 "register_operand" "")
18230 (match_operand:SF 5 "nonimmediate_operand" "")])
18231 (match_operand:SF 2 "register_operand" "")
18232 (match_operand:SF 3 "register_operand" "")))
bf71a4f8 18233 (clobber (match_operand 6 "" ""))
8bc527af 18234 (clobber (reg:CC FLAGS_REG))]
0073023d
JH
18235 "SSE_REG_P (operands[0]) && reload_completed"
18236 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
79ae63b1
JH
18237 (set (match_dup 2) (and:V4SF (match_dup 2)
18238 (match_dup 8)))
18239 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18240 (match_dup 3)))
18241 (set (match_dup 0) (ior:V4SF (match_dup 6)
18242 (match_dup 7)))]
18243{
18244 /* If op2 == op3, op3 would be clobbered before it is used. */
18245 if (operands_match_p (operands[2], operands[3]))
18246 {
18247 emit_move_insn (operands[0], operands[2]);
18248 DONE;
18249 }
18250
18251 PUT_MODE (operands[1], GET_MODE (operands[0]));
18252 if (operands_match_p (operands[0], operands[4]))
18253 operands[6] = operands[4], operands[7] = operands[2];
18254 else
18255 operands[6] = operands[2], operands[7] = operands[4];
18256 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18257 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18258 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18259 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18260 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18261 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18262})
18263
18264(define_split
18265 [(set (match_operand:DF 0 "register_operand" "")
0022b96a
RH
18266 (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18267 [(match_operand:DF 4 "register_operand" "")
18268 (match_operand:DF 5 "nonimmediate_operand" "")])
18269 (match_operand:DF 2 "register_operand" "")
18270 (match_operand:DF 3 "register_operand" "")))
79ae63b1 18271 (clobber (match_operand 6 "" ""))
8bc527af 18272 (clobber (reg:CC FLAGS_REG))]
79ae63b1
JH
18273 "SSE_REG_P (operands[0]) && reload_completed"
18274 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18275 (set (match_dup 2) (and:V2DF (match_dup 2)
18276 (match_dup 8)))
18277 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18278 (match_dup 3)))
18279 (set (match_dup 0) (ior:V2DF (match_dup 6)
18280 (match_dup 7)))]
0073023d 18281{
4977bab6
ZW
18282 if (GET_MODE (operands[2]) == DFmode
18283 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18284 {
18285 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18286 emit_insn (gen_sse2_unpcklpd (op, op, op));
18287 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18288 emit_insn (gen_sse2_unpcklpd (op, op, op));
18289 }
4f6ae35d
JJ
18290
18291 /* If op2 == op3, op3 would be clobbered before it is used. */
66b408f2 18292 if (operands_match_p (operands[2], operands[3]))
4f6ae35d
JJ
18293 {
18294 emit_move_insn (operands[0], operands[2]);
18295 DONE;
18296 }
18297
0073023d 18298 PUT_MODE (operands[1], GET_MODE (operands[0]));
f021d6fc 18299 if (operands_match_p (operands[0], operands[4]))
0073023d
JH
18300 operands[6] = operands[4], operands[7] = operands[2];
18301 else
f021d6fc 18302 operands[6] = operands[2], operands[7] = operands[4];
79ae63b1
JH
18303 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18304 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18305 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18306 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18307 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18308 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
0f40f9f7 18309})
0073023d 18310
d1f87653 18311;; Special case of conditional move we can handle effectively.
0073023d
JH
18312;; Do not brother with the integer/floating point case, since these are
18313;; bot considerably slower, unlike in the generic case.
18314(define_insn "*sse_movsfcc_const0_1"
66b408f2 18315 [(set (match_operand:SF 0 "register_operand" "=&x")
0073023d
JH
18316 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18317 [(match_operand:SF 4 "register_operand" "0")
18318 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18319 (match_operand:SF 2 "register_operand" "x")
18320 (match_operand:SF 3 "const0_operand" "X")))]
18321 "TARGET_SSE"
18322 "#")
18323
18324(define_insn "*sse_movsfcc_const0_2"
66b408f2 18325 [(set (match_operand:SF 0 "register_operand" "=&x")
0073023d
JH
18326 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18327 [(match_operand:SF 4 "register_operand" "0")
18328 (match_operand:SF 5 "nonimmediate_operand" "xm")])
adc7fcb8
JH
18329 (match_operand:SF 2 "const0_operand" "X")
18330 (match_operand:SF 3 "register_operand" "x")))]
0073023d
JH
18331 "TARGET_SSE"
18332 "#")
18333
18334(define_insn "*sse_movsfcc_const0_3"
66b408f2 18335 [(set (match_operand:SF 0 "register_operand" "=&x")
0073023d
JH
18336 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18337 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18338 (match_operand:SF 5 "register_operand" "0")])
18339 (match_operand:SF 2 "register_operand" "x")
18340 (match_operand:SF 3 "const0_operand" "X")))]
18341 "TARGET_SSE"
18342 "#")
18343
18344(define_insn "*sse_movsfcc_const0_4"
66b408f2 18345 [(set (match_operand:SF 0 "register_operand" "=&x")
0073023d
JH
18346 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18347 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18348 (match_operand:SF 5 "register_operand" "0")])
adc7fcb8
JH
18349 (match_operand:SF 2 "const0_operand" "X")
18350 (match_operand:SF 3 "register_operand" "x")))]
0073023d
JH
18351 "TARGET_SSE"
18352 "#")
18353
18354(define_insn "*sse_movdfcc_const0_1"
66b408f2
JJ
18355 [(set (match_operand:DF 0 "register_operand" "=&Y")
18356 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18357 [(match_operand:DF 4 "register_operand" "0")
18358 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18359 (match_operand:DF 2 "register_operand" "Y")
18360 (match_operand:DF 3 "const0_operand" "X")))]
0073023d
JH
18361 "TARGET_SSE2"
18362 "#")
18363
18364(define_insn "*sse_movdfcc_const0_2"
66b408f2
JJ
18365 [(set (match_operand:DF 0 "register_operand" "=&Y")
18366 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18367 [(match_operand:DF 4 "register_operand" "0")
18368 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18369 (match_operand:DF 2 "const0_operand" "X")
18370 (match_operand:DF 3 "register_operand" "Y")))]
0073023d
JH
18371 "TARGET_SSE2"
18372 "#")
18373
18374(define_insn "*sse_movdfcc_const0_3"
66b408f2
JJ
18375 [(set (match_operand:DF 0 "register_operand" "=&Y")
18376 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18377 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18378 (match_operand:DF 5 "register_operand" "0")])
18379 (match_operand:DF 2 "register_operand" "Y")
18380 (match_operand:DF 3 "const0_operand" "X")))]
0073023d
JH
18381 "TARGET_SSE2"
18382 "#")
18383
18384(define_insn "*sse_movdfcc_const0_4"
66b408f2
JJ
18385 [(set (match_operand:DF 0 "register_operand" "=&Y")
18386 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18387 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18388 (match_operand:DF 5 "register_operand" "0")])
18389 (match_operand:DF 2 "const0_operand" "X")
18390 (match_operand:DF 3 "register_operand" "Y")))]
0073023d
JH
18391 "TARGET_SSE2"
18392 "#")
18393
18394(define_split
79ae63b1 18395 [(set (match_operand:SF 0 "register_operand" "")
0022b96a
RH
18396 (if_then_else:SF (match_operator 1 "comparison_operator"
18397 [(match_operand:SF 4 "nonimmediate_operand" "")
18398 (match_operand:SF 5 "nonimmediate_operand" "")])
18399 (match_operand:SF 2 "nonmemory_operand" "")
18400 (match_operand:SF 3 "nonmemory_operand" "")))]
79ae63b1
JH
18401 "SSE_REG_P (operands[0]) && reload_completed
18402 && (const0_operand (operands[2], GET_MODE (operands[0]))
18403 || const0_operand (operands[3], GET_MODE (operands[0])))"
18404 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18405 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18406{
18407 PUT_MODE (operands[1], GET_MODE (operands[0]));
18408 if (!sse_comparison_operator (operands[1], VOIDmode)
18409 || !rtx_equal_p (operands[0], operands[4]))
18410 {
18411 rtx tmp = operands[5];
18412 operands[5] = operands[4];
18413 operands[4] = tmp;
18414 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18415 }
18416 if (!rtx_equal_p (operands[0], operands[4]))
18417 abort ();
18418 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18419 if (const0_operand (operands[2], GET_MODE (operands[2])))
18420 {
18421 operands[7] = operands[3];
0620be18 18422 operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
79ae63b1
JH
18423 }
18424 else
18425 {
18426 operands[7] = operands[2];
0620be18 18427 operands[6] = operands[8];
79ae63b1
JH
18428 }
18429 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18430})
18431
18432(define_split
18433 [(set (match_operand:DF 0 "register_operand" "")
0022b96a
RH
18434 (if_then_else:DF (match_operator 1 "comparison_operator"
18435 [(match_operand:DF 4 "nonimmediate_operand" "")
18436 (match_operand:DF 5 "nonimmediate_operand" "")])
18437 (match_operand:DF 2 "nonmemory_operand" "")
18438 (match_operand:DF 3 "nonmemory_operand" "")))]
0073023d
JH
18439 "SSE_REG_P (operands[0]) && reload_completed
18440 && (const0_operand (operands[2], GET_MODE (operands[0]))
18441 || const0_operand (operands[3], GET_MODE (operands[0])))"
18442 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
79ae63b1 18443 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
0073023d 18444{
4977bab6
ZW
18445 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18446 && GET_MODE (operands[2]) == DFmode)
18447 {
18448 if (REG_P (operands[2]))
18449 {
18450 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18451 emit_insn (gen_sse2_unpcklpd (op, op, op));
18452 }
18453 if (REG_P (operands[3]))
18454 {
18455 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18456 emit_insn (gen_sse2_unpcklpd (op, op, op));
18457 }
18458 }
0073023d 18459 PUT_MODE (operands[1], GET_MODE (operands[0]));
5794139a
JH
18460 if (!sse_comparison_operator (operands[1], VOIDmode)
18461 || !rtx_equal_p (operands[0], operands[4]))
0073023d
JH
18462 {
18463 rtx tmp = operands[5];
18464 operands[5] = operands[4];
18465 operands[4] = tmp;
18466 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18467 }
5794139a
JH
18468 if (!rtx_equal_p (operands[0], operands[4]))
18469 abort ();
79ae63b1
JH
18470 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18471 if (const0_operand (operands[2], GET_MODE (operands[2])))
0073023d
JH
18472 {
18473 operands[7] = operands[3];
79ae63b1 18474 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
0073023d
JH
18475 }
18476 else
18477 {
18478 operands[7] = operands[2];
79ae63b1 18479 operands[6] = operands[8];
0073023d 18480 }
79ae63b1 18481 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
0f40f9f7 18482})
0073023d 18483
885a70fd
JH
18484(define_expand "allocate_stack_worker"
18485 [(match_operand:SI 0 "register_operand" "")]
18486 "TARGET_STACK_PROBE"
885a70fd 18487{
af9fb8ab
JH
18488 if (reload_completed)
18489 {
18490 if (TARGET_64BIT)
18491 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18492 else
18493 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18494 }
885a70fd 18495 else
af9fb8ab
JH
18496 {
18497 if (TARGET_64BIT)
18498 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18499 else
18500 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18501 }
885a70fd 18502 DONE;
0f40f9f7 18503})
885a70fd
JH
18504
18505(define_insn "allocate_stack_worker_1"
8e2cd6dd
KC
18506 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18507 UNSPECV_STACK_PROBE)
8bc527af 18508 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
af9fb8ab 18509 (clobber (match_scratch:SI 1 "=0"))
8bc527af 18510 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 18511 "!TARGET_64BIT && TARGET_STACK_PROBE"
0f40f9f7 18512 "call\t__alloca"
885a70fd
JH
18513 [(set_attr "type" "multi")
18514 (set_attr "length" "5")])
18515
af9fb8ab 18516(define_expand "allocate_stack_worker_postreload"
8e2cd6dd
KC
18517 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18518 UNSPECV_STACK_PROBE)
8bc527af 18519 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
af9fb8ab 18520 (clobber (match_dup 0))
8bc527af 18521 (clobber (reg:CC FLAGS_REG))])]
af9fb8ab
JH
18522 ""
18523 "")
18524
885a70fd 18525(define_insn "allocate_stack_worker_rex64"
8e2cd6dd
KC
18526 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18527 UNSPECV_STACK_PROBE)
8bc527af 18528 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
af9fb8ab 18529 (clobber (match_scratch:DI 1 "=0"))
8bc527af 18530 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 18531 "TARGET_64BIT && TARGET_STACK_PROBE"
0f40f9f7 18532 "call\t__alloca"
e075ae69
RH
18533 [(set_attr "type" "multi")
18534 (set_attr "length" "5")])
578b58f5 18535
af9fb8ab 18536(define_expand "allocate_stack_worker_rex64_postreload"
8e2cd6dd
KC
18537 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18538 UNSPECV_STACK_PROBE)
8bc527af 18539 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
af9fb8ab 18540 (clobber (match_dup 0))
8bc527af 18541 (clobber (reg:CC FLAGS_REG))])]
af9fb8ab
JH
18542 ""
18543 "")
18544
578b58f5 18545(define_expand "allocate_stack"
e075ae69 18546 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
8bc527af 18547 (minus:SI (reg:SI SP_REG)
e075ae69 18548 (match_operand:SI 1 "general_operand" "")))
8bc527af
SB
18549 (clobber (reg:CC FLAGS_REG))])
18550 (parallel [(set (reg:SI SP_REG)
18551 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18552 (clobber (reg:CC FLAGS_REG))])]
e075ae69 18553 "TARGET_STACK_PROBE"
578b58f5
RK
18554{
18555#ifdef CHECK_STACK_LIMIT
e9a25f70
JL
18556 if (GET_CODE (operands[1]) == CONST_INT
18557 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
578b58f5 18558 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
e9a25f70 18559 operands[1]));
578b58f5
RK
18560 else
18561#endif
18562 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
e9a25f70 18563 operands[1])));
578b58f5 18564
e9a25f70
JL
18565 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18566 DONE;
0f40f9f7 18567})
e31ca113 18568
fb754025
AG
18569(define_expand "builtin_setjmp_receiver"
18570 [(label_ref (match_operand 0 "" ""))]
1b0c37d7 18571 "!TARGET_64BIT && flag_pic"
fb754025 18572{
c8c03509 18573 emit_insn (gen_set_got (pic_offset_table_rtx));
fb754025 18574 DONE;
0f40f9f7 18575})
e9e80858
JH
18576\f
18577;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18578
18579(define_split
18580 [(set (match_operand 0 "register_operand" "")
18581 (match_operator 3 "promotable_binary_operator"
18582 [(match_operand 1 "register_operand" "")
2247f6ed 18583 (match_operand 2 "aligned_operand" "")]))
8bc527af 18584 (clobber (reg:CC FLAGS_REG))]
e9e80858
JH
18585 "! TARGET_PARTIAL_REG_STALL && reload_completed
18586 && ((GET_MODE (operands[0]) == HImode
285464d0
JH
18587 && ((!optimize_size && !TARGET_FAST_PREFIX)
18588 || GET_CODE (operands[2]) != CONST_INT
e9e80858
JH
18589 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18590 || (GET_MODE (operands[0]) == QImode
18591 && (TARGET_PROMOTE_QImode || optimize_size)))"
18592 [(parallel [(set (match_dup 0)
18593 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8bc527af 18594 (clobber (reg:CC FLAGS_REG))])]
e9e80858
JH
18595 "operands[0] = gen_lowpart (SImode, operands[0]);
18596 operands[1] = gen_lowpart (SImode, operands[1]);
18597 if (GET_CODE (operands[3]) != ASHIFT)
18598 operands[2] = gen_lowpart (SImode, operands[2]);
dbbbbf3b 18599 PUT_MODE (operands[3], SImode);")
e9e80858 18600
d2fc7725
EB
18601; Promote the QImode tests, as i386 has encoding of the AND
18602; instruction with 32-bit sign-extended immediate and thus the
18603; instruction size is unchanged, except in the %eax case for
18604; which it is increased by one byte, hence the ! optimize_size.
e9e80858 18605(define_split
25da5dc7
RH
18606 [(set (match_operand 0 "flags_reg_operand" "")
18607 (match_operator 2 "compare_operator"
18608 [(and (match_operand 3 "aligned_operand" "")
18609 (match_operand 4 "const_int_operand" ""))
18610 (const_int 0)]))
18611 (set (match_operand 1 "register_operand" "")
18612 (and (match_dup 3) (match_dup 4)))]
e9e80858 18613 "! TARGET_PARTIAL_REG_STALL && reload_completed
d2fc7725 18614 /* Ensure that the operand will remain sign-extended immediate. */
25da5dc7 18615 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
d2fc7725 18616 && ! optimize_size
25da5dc7
RH
18617 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18618 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18619 [(parallel [(set (match_dup 0)
18620 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18621 (const_int 0)]))
18622 (set (match_dup 1)
18623 (and:SI (match_dup 3) (match_dup 4)))])]
18624{
18625 operands[4]
18626 = gen_int_mode (INTVAL (operands[4])
18627 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18628 operands[1] = gen_lowpart (SImode, operands[1]);
18629 operands[3] = gen_lowpart (SImode, operands[3]);
18630})
e9e80858 18631
d2fc7725
EB
18632; Don't promote the QImode tests, as i386 doesn't have encoding of
18633; the TEST instruction with 32-bit sign-extended immediate and thus
18634; the instruction size would at least double, which is not what we
18635; want even with ! optimize_size.
e9e80858 18636(define_split
25da5dc7
RH
18637 [(set (match_operand 0 "flags_reg_operand" "")
18638 (match_operator 1 "compare_operator"
18639 [(and (match_operand:HI 2 "aligned_operand" "")
18640 (match_operand:HI 3 "const_int_operand" ""))
18641 (const_int 0)]))]
e9e80858 18642 "! TARGET_PARTIAL_REG_STALL && reload_completed
d2fc7725 18643 /* Ensure that the operand will remain sign-extended immediate. */
25da5dc7 18644 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
d2fc7725
EB
18645 && ! TARGET_FAST_PREFIX
18646 && ! optimize_size"
25da5dc7
RH
18647 [(set (match_dup 0)
18648 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18649 (const_int 0)]))]
18650{
18651 operands[3]
18652 = gen_int_mode (INTVAL (operands[3])
18653 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18654 operands[2] = gen_lowpart (SImode, operands[2]);
18655})
e9e80858
JH
18656
18657(define_split
18658 [(set (match_operand 0 "register_operand" "")
18659 (neg (match_operand 1 "register_operand" "")))
8bc527af 18660 (clobber (reg:CC FLAGS_REG))]
e9e80858
JH
18661 "! TARGET_PARTIAL_REG_STALL && reload_completed
18662 && (GET_MODE (operands[0]) == HImode
18663 || (GET_MODE (operands[0]) == QImode
18664 && (TARGET_PROMOTE_QImode || optimize_size)))"
18665 [(parallel [(set (match_dup 0)
18666 (neg:SI (match_dup 1)))
8bc527af 18667 (clobber (reg:CC FLAGS_REG))])]
e9e80858
JH
18668 "operands[0] = gen_lowpart (SImode, operands[0]);
18669 operands[1] = gen_lowpart (SImode, operands[1]);")
18670
18671(define_split
18672 [(set (match_operand 0 "register_operand" "")
18673 (not (match_operand 1 "register_operand" "")))]
18674 "! TARGET_PARTIAL_REG_STALL && reload_completed
18675 && (GET_MODE (operands[0]) == HImode
18676 || (GET_MODE (operands[0]) == QImode
18677 && (TARGET_PROMOTE_QImode || optimize_size)))"
18678 [(set (match_dup 0)
18679 (not:SI (match_dup 1)))]
18680 "operands[0] = gen_lowpart (SImode, operands[0]);
18681 operands[1] = gen_lowpart (SImode, operands[1]);")
18682
18683(define_split
18684 [(set (match_operand 0 "register_operand" "")
18685 (if_then_else (match_operator 1 "comparison_operator"
42fabf21 18686 [(reg FLAGS_REG) (const_int 0)])
e9e80858
JH
18687 (match_operand 2 "register_operand" "")
18688 (match_operand 3 "register_operand" "")))]
18689 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18690 && (GET_MODE (operands[0]) == HImode
18691 || (GET_MODE (operands[0]) == QImode
18692 && (TARGET_PROMOTE_QImode || optimize_size)))"
18693 [(set (match_dup 0)
18694 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18695 "operands[0] = gen_lowpart (SImode, operands[0]);
18696 operands[2] = gen_lowpart (SImode, operands[2]);
18697 operands[3] = gen_lowpart (SImode, operands[3]);")
18698
e075ae69
RH
18699\f
18700;; RTL Peephole optimizations, run before sched2. These primarily look to
18701;; transform a complex memory operation into two memory to register operations.
18702
18703;; Don't push memory operands
18704(define_peephole2
3071fab5
RH
18705 [(set (match_operand:SI 0 "push_operand" "")
18706 (match_operand:SI 1 "memory_operand" ""))
18707 (match_scratch:SI 2 "r")]
e075ae69
RH
18708 "! optimize_size && ! TARGET_PUSH_MEMORY"
18709 [(set (match_dup 2) (match_dup 1))
18710 (set (match_dup 0) (match_dup 2))]
18711 "")
18712
cc2e591b
JH
18713(define_peephole2
18714 [(set (match_operand:DI 0 "push_operand" "")
18715 (match_operand:DI 1 "memory_operand" ""))
18716 (match_scratch:DI 2 "r")]
18717 "! optimize_size && ! TARGET_PUSH_MEMORY"
18718 [(set (match_dup 2) (match_dup 1))
18719 (set (match_dup 0) (match_dup 2))]
18720 "")
18721
e9e80858
JH
18722;; We need to handle SFmode only, because DFmode and XFmode is split to
18723;; SImode pushes.
18724(define_peephole2
18725 [(set (match_operand:SF 0 "push_operand" "")
18726 (match_operand:SF 1 "memory_operand" ""))
18727 (match_scratch:SF 2 "r")]
18728 "! optimize_size && ! TARGET_PUSH_MEMORY"
18729 [(set (match_dup 2) (match_dup 1))
18730 (set (match_dup 0) (match_dup 2))]
18731 "")
18732
e075ae69 18733(define_peephole2
3071fab5
RH
18734 [(set (match_operand:HI 0 "push_operand" "")
18735 (match_operand:HI 1 "memory_operand" ""))
18736 (match_scratch:HI 2 "r")]
e075ae69
RH
18737 "! optimize_size && ! TARGET_PUSH_MEMORY"
18738 [(set (match_dup 2) (match_dup 1))
18739 (set (match_dup 0) (match_dup 2))]
18740 "")
18741
18742(define_peephole2
3071fab5
RH
18743 [(set (match_operand:QI 0 "push_operand" "")
18744 (match_operand:QI 1 "memory_operand" ""))
18745 (match_scratch:QI 2 "q")]
e075ae69
RH
18746 "! optimize_size && ! TARGET_PUSH_MEMORY"
18747 [(set (match_dup 2) (match_dup 1))
18748 (set (match_dup 0) (match_dup 2))]
18749 "")
18750
18751;; Don't move an immediate directly to memory when the instruction
18752;; gets too big.
18753(define_peephole2
18754 [(match_scratch:SI 1 "r")
18755 (set (match_operand:SI 0 "memory_operand" "")
18756 (const_int 0))]
23280139 18757 "! optimize_size
591702de 18758 && ! TARGET_USE_MOV0
23280139
RH
18759 && TARGET_SPLIT_LONG_MOVES
18760 && get_attr_length (insn) >= ix86_cost->large_insn
18761 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69 18762 [(parallel [(set (match_dup 1) (const_int 0))
8bc527af 18763 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
18764 (set (match_dup 0) (match_dup 1))]
18765 "")
18766
18767(define_peephole2
18768 [(match_scratch:HI 1 "r")
18769 (set (match_operand:HI 0 "memory_operand" "")
18770 (const_int 0))]
23280139 18771 "! optimize_size
591702de 18772 && ! TARGET_USE_MOV0
23280139
RH
18773 && TARGET_SPLIT_LONG_MOVES
18774 && get_attr_length (insn) >= ix86_cost->large_insn
18775 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 18776 [(parallel [(set (match_dup 2) (const_int 0))
8bc527af 18777 (clobber (reg:CC FLAGS_REG))])
e075ae69 18778 (set (match_dup 0) (match_dup 1))]
1e2115dc 18779 "operands[2] = gen_lowpart (SImode, operands[1]);")
e075ae69
RH
18780
18781(define_peephole2
18782 [(match_scratch:QI 1 "q")
18783 (set (match_operand:QI 0 "memory_operand" "")
18784 (const_int 0))]
23280139 18785 "! optimize_size
591702de 18786 && ! TARGET_USE_MOV0
23280139
RH
18787 && TARGET_SPLIT_LONG_MOVES
18788 && get_attr_length (insn) >= ix86_cost->large_insn
18789 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 18790 [(parallel [(set (match_dup 2) (const_int 0))
8bc527af 18791 (clobber (reg:CC FLAGS_REG))])
e075ae69 18792 (set (match_dup 0) (match_dup 1))]
1e2115dc 18793 "operands[2] = gen_lowpart (SImode, operands[1]);")
e075ae69
RH
18794
18795(define_peephole2
18796 [(match_scratch:SI 2 "r")
18797 (set (match_operand:SI 0 "memory_operand" "")
18798 (match_operand:SI 1 "immediate_operand" ""))]
23280139
RH
18799 "! optimize_size
18800 && get_attr_length (insn) >= ix86_cost->large_insn
18801 && TARGET_SPLIT_LONG_MOVES"
e075ae69
RH
18802 [(set (match_dup 2) (match_dup 1))
18803 (set (match_dup 0) (match_dup 2))]
18804 "")
18805
18806(define_peephole2
18807 [(match_scratch:HI 2 "r")
18808 (set (match_operand:HI 0 "memory_operand" "")
18809 (match_operand:HI 1 "immediate_operand" ""))]
18810 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18811 && TARGET_SPLIT_LONG_MOVES"
18812 [(set (match_dup 2) (match_dup 1))
18813 (set (match_dup 0) (match_dup 2))]
18814 "")
18815
18816(define_peephole2
18817 [(match_scratch:QI 2 "q")
18818 (set (match_operand:QI 0 "memory_operand" "")
18819 (match_operand:QI 1 "immediate_operand" ""))]
18820 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18821 && TARGET_SPLIT_LONG_MOVES"
18822 [(set (match_dup 2) (match_dup 1))
18823 (set (match_dup 0) (match_dup 2))]
18824 "")
18825
18826;; Don't compare memory with zero, load and use a test instead.
18827(define_peephole2
25da5dc7
RH
18828 [(set (match_operand 0 "flags_reg_operand" "")
18829 (match_operator 1 "compare_operator"
18830 [(match_operand:SI 2 "memory_operand" "")
18831 (const_int 0)]))
3071fab5 18832 (match_scratch:SI 3 "r")]
16189740 18833 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
25da5dc7
RH
18834 [(set (match_dup 3) (match_dup 2))
18835 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
e075ae69
RH
18836 "")
18837
18838;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18839;; Don't split NOTs with a displacement operand, because resulting XOR
d1f87653 18840;; will not be pairable anyway.
e075ae69 18841;;
1e5f1716 18842;; On AMD K6, NOT is vector decoded with memory operand that cannot be
e075ae69
RH
18843;; represented using a modRM byte. The XOR replacement is long decoded,
18844;; so this split helps here as well.
18845;;
23280139
RH
18846;; Note: Can't do this as a regular split because we can't get proper
18847;; lifetime information then.
e075ae69
RH
18848
18849(define_peephole2
d5d6a58b
RH
18850 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18851 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
e075ae69 18852 "!optimize_size
23280139 18853 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
18854 && ((TARGET_PENTIUM
18855 && (GET_CODE (operands[0]) != MEM
18856 || !memory_displacement_operand (operands[0], SImode)))
18857 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18858 [(parallel [(set (match_dup 0)
18859 (xor:SI (match_dup 1) (const_int -1)))
8bc527af 18860 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18861 "")
18862
18863(define_peephole2
d5d6a58b
RH
18864 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18865 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
e075ae69 18866 "!optimize_size
23280139 18867 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
18868 && ((TARGET_PENTIUM
18869 && (GET_CODE (operands[0]) != MEM
18870 || !memory_displacement_operand (operands[0], HImode)))
18871 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18872 [(parallel [(set (match_dup 0)
18873 (xor:HI (match_dup 1) (const_int -1)))
8bc527af 18874 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18875 "")
18876
18877(define_peephole2
d5d6a58b
RH
18878 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18879 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
e075ae69 18880 "!optimize_size
23280139 18881 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
18882 && ((TARGET_PENTIUM
18883 && (GET_CODE (operands[0]) != MEM
18884 || !memory_displacement_operand (operands[0], QImode)))
18885 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18886 [(parallel [(set (match_dup 0)
18887 (xor:QI (match_dup 1) (const_int -1)))
8bc527af 18888 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18889 "")
18890
18891;; Non pairable "test imm, reg" instructions can be translated to
18892;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18893;; byte opcode instead of two, have a short form for byte operands),
18894;; so do it for other CPUs as well. Given that the value was dead,
f5143c46 18895;; this should not create any new dependencies. Pass on the sub-word
e075ae69
RH
18896;; versions if we're concerned about partial register stalls.
18897
18898(define_peephole2
25da5dc7
RH
18899 [(set (match_operand 0 "flags_reg_operand" "")
18900 (match_operator 1 "compare_operator"
18901 [(and:SI (match_operand:SI 2 "register_operand" "")
18902 (match_operand:SI 3 "immediate_operand" ""))
18903 (const_int 0)]))]
16189740 18904 "ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
18905 && (true_regnum (operands[2]) != 0
18906 || (GET_CODE (operands[3]) == CONST_INT
18907 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18908 && peep2_reg_dead_p (1, operands[2])"
e075ae69 18909 [(parallel
25da5dc7
RH
18910 [(set (match_dup 0)
18911 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18912 (const_int 0)]))
18913 (set (match_dup 2)
18914 (and:SI (match_dup 2) (match_dup 3)))])]
e075ae69
RH
18915 "")
18916
e9e80858
JH
18917;; We don't need to handle HImode case, because it will be promoted to SImode
18918;; on ! TARGET_PARTIAL_REG_STALL
e075ae69
RH
18919
18920(define_peephole2
25da5dc7
RH
18921 [(set (match_operand 0 "flags_reg_operand" "")
18922 (match_operator 1 "compare_operator"
18923 [(and:QI (match_operand:QI 2 "register_operand" "")
18924 (match_operand:QI 3 "immediate_operand" ""))
18925 (const_int 0)]))]
e075ae69 18926 "! TARGET_PARTIAL_REG_STALL
16189740 18927 && ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
18928 && true_regnum (operands[2]) != 0
18929 && peep2_reg_dead_p (1, operands[2])"
e075ae69 18930 [(parallel
25da5dc7
RH
18931 [(set (match_dup 0)
18932 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18933 (const_int 0)]))
18934 (set (match_dup 2)
18935 (and:QI (match_dup 2) (match_dup 3)))])]
e075ae69
RH
18936 "")
18937
18938(define_peephole2
25da5dc7
RH
18939 [(set (match_operand 0 "flags_reg_operand" "")
18940 (match_operator 1 "compare_operator"
18941 [(and:SI
18942 (zero_extract:SI
18943 (match_operand 2 "ext_register_operand" "")
18944 (const_int 8)
18945 (const_int 8))
18946 (match_operand 3 "const_int_operand" ""))
18947 (const_int 0)]))]
e075ae69 18948 "! TARGET_PARTIAL_REG_STALL
16189740 18949 && ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
18950 && true_regnum (operands[2]) != 0
18951 && peep2_reg_dead_p (1, operands[2])"
18952 [(parallel [(set (match_dup 0)
18953 (match_op_dup 1
18954 [(and:SI
18955 (zero_extract:SI
18956 (match_dup 2)
18957 (const_int 8)
18958 (const_int 8))
18959 (match_dup 3))
18960 (const_int 0)]))
18961 (set (zero_extract:SI (match_dup 2)
e075ae69
RH
18962 (const_int 8)
18963 (const_int 8))
18964 (and:SI
18965 (zero_extract:SI
25da5dc7 18966 (match_dup 2)
e075ae69
RH
18967 (const_int 8)
18968 (const_int 8))
25da5dc7 18969 (match_dup 3)))])]
e075ae69
RH
18970 "")
18971
18972;; Don't do logical operations with memory inputs.
18973(define_peephole2
18974 [(match_scratch:SI 2 "r")
18975 (parallel [(set (match_operand:SI 0 "register_operand" "")
18976 (match_operator:SI 3 "arith_or_logical_operator"
18977 [(match_dup 0)
18978 (match_operand:SI 1 "memory_operand" "")]))
8bc527af 18979 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18980 "! optimize_size && ! TARGET_READ_MODIFY"
18981 [(set (match_dup 2) (match_dup 1))
18982 (parallel [(set (match_dup 0)
18983 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
8bc527af 18984 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18985 "")
18986
18987(define_peephole2
18988 [(match_scratch:SI 2 "r")
18989 (parallel [(set (match_operand:SI 0 "register_operand" "")
18990 (match_operator:SI 3 "arith_or_logical_operator"
18991 [(match_operand:SI 1 "memory_operand" "")
18992 (match_dup 0)]))
8bc527af 18993 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18994 "! optimize_size && ! TARGET_READ_MODIFY"
18995 [(set (match_dup 2) (match_dup 1))
18996 (parallel [(set (match_dup 0)
18997 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
8bc527af 18998 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18999 "")
19000
19001; Don't do logical operations with memory outputs
19002;
19003; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19004; instruction into two 1-uop insns plus a 2-uop insn. That last has
19005; the same decoder scheduling characteristics as the original.
19006
19007(define_peephole2
19008 [(match_scratch:SI 2 "r")
19009 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19010 (match_operator:SI 3 "arith_or_logical_operator"
19011 [(match_dup 0)
19012 (match_operand:SI 1 "nonmemory_operand" "")]))
8bc527af 19013 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
19014 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19015 [(set (match_dup 2) (match_dup 0))
19016 (parallel [(set (match_dup 2)
19017 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
8bc527af 19018 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
19019 (set (match_dup 0) (match_dup 2))]
19020 "")
19021
19022(define_peephole2
19023 [(match_scratch:SI 2 "r")
19024 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19025 (match_operator:SI 3 "arith_or_logical_operator"
19026 [(match_operand:SI 1 "nonmemory_operand" "")
19027 (match_dup 0)]))
8bc527af 19028 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
19029 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19030 [(set (match_dup 2) (match_dup 0))
19031 (parallel [(set (match_dup 2)
19032 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8bc527af 19033 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
19034 (set (match_dup 0) (match_dup 2))]
19035 "")
19036
19037;; Attempt to always use XOR for zeroing registers.
19038(define_peephole2
19039 [(set (match_operand 0 "register_operand" "")
19040 (const_int 0))]
19041 "(GET_MODE (operands[0]) == QImode
19042 || GET_MODE (operands[0]) == HImode
cc2e591b
JH
19043 || GET_MODE (operands[0]) == SImode
19044 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
e075ae69 19045 && (! TARGET_USE_MOV0 || optimize_size)
23280139 19046 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69 19047 [(parallel [(set (match_dup 0) (const_int 0))
8bc527af 19048 (clobber (reg:CC FLAGS_REG))])]
1e2115dc
JZ
19049 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19050 operands[0]);")
d3a923ee 19051
6ef67412
JH
19052(define_peephole2
19053 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19054 (const_int 0))]
19055 "(GET_MODE (operands[0]) == QImode
19056 || GET_MODE (operands[0]) == HImode)
19057 && (! TARGET_USE_MOV0 || optimize_size)
19058 && peep2_regno_dead_p (0, FLAGS_REG)"
19059 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
8bc527af 19060 (clobber (reg:CC FLAGS_REG))])])
6ef67412 19061
e075ae69
RH
19062;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19063(define_peephole2
591702de 19064 [(set (match_operand 0 "register_operand" "")
e075ae69 19065 (const_int -1))]
591702de 19066 "(GET_MODE (operands[0]) == HImode
cc2e591b
JH
19067 || GET_MODE (operands[0]) == SImode
19068 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
591702de 19069 && (optimize_size || TARGET_PENTIUM)
23280139 19070 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 19071 [(parallel [(set (match_dup 0) (const_int -1))
8bc527af 19072 (clobber (reg:CC FLAGS_REG))])]
1e2115dc
JZ
19073 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19074 operands[0]);")
1c27d4b2
JH
19075
19076;; Attempt to convert simple leas to adds. These can be created by
19077;; move expanders.
19078(define_peephole2
19079 [(set (match_operand:SI 0 "register_operand" "")
19080 (plus:SI (match_dup 0)
19081 (match_operand:SI 1 "nonmemory_operand" "")))]
23280139 19082 "peep2_regno_dead_p (0, FLAGS_REG)"
1c27d4b2 19083 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
8bc527af 19084 (clobber (reg:CC FLAGS_REG))])]
1c27d4b2
JH
19085 "")
19086
cc2e591b
JH
19087(define_peephole2
19088 [(set (match_operand:SI 0 "register_operand" "")
19089 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19090 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19091 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19092 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
8bc527af 19093 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
19094 "operands[2] = gen_lowpart (SImode, operands[2]);")
19095
19096(define_peephole2
19097 [(set (match_operand:DI 0 "register_operand" "")
19098 (plus:DI (match_dup 0)
19099 (match_operand:DI 1 "x86_64_general_operand" "")))]
19100 "peep2_regno_dead_p (0, FLAGS_REG)"
19101 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
8bc527af 19102 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
19103 "")
19104
1c27d4b2
JH
19105(define_peephole2
19106 [(set (match_operand:SI 0 "register_operand" "")
19107 (mult:SI (match_dup 0)
cc2e591b 19108 (match_operand:SI 1 "const_int_operand" "")))]
23280139
RH
19109 "exact_log2 (INTVAL (operands[1])) >= 0
19110 && peep2_regno_dead_p (0, FLAGS_REG)"
1c27d4b2 19111 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
8bc527af 19112 (clobber (reg:CC FLAGS_REG))])]
1c27d4b2 19113 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
bdeb029c 19114
cc2e591b
JH
19115(define_peephole2
19116 [(set (match_operand:DI 0 "register_operand" "")
19117 (mult:DI (match_dup 0)
19118 (match_operand:DI 1 "const_int_operand" "")))]
19119 "exact_log2 (INTVAL (operands[1])) >= 0
19120 && peep2_regno_dead_p (0, FLAGS_REG)"
19121 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
8bc527af 19122 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
19123 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19124
19125(define_peephole2
19126 [(set (match_operand:SI 0 "register_operand" "")
19127 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19128 (match_operand:DI 2 "const_int_operand" "")) 0))]
4c9c9a3d 19129 "exact_log2 (INTVAL (operands[2])) >= 0
cc2e591b
JH
19130 && REGNO (operands[0]) == REGNO (operands[1])
19131 && peep2_regno_dead_p (0, FLAGS_REG)"
19132 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
8bc527af 19133 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
19134 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19135
bdeb029c
JH
19136;; The ESP adjustments can be done by the push and pop instructions. Resulting
19137;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19138;; many CPUs it is also faster, since special hardware to avoid esp
f5143c46 19139;; dependencies is present.
bdeb029c 19140
d6a7951f 19141;; While some of these conversions may be done using splitters, we use peepholes
bdeb029c
JH
19142;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19143
f5143c46 19144;; Convert prologue esp subtractions to push.
bdeb029c
JH
19145;; We need register to push. In order to keep verify_flow_info happy we have
19146;; two choices
19147;; - use scratch and clobber it in order to avoid dependencies
19148;; - use already live register
19149;; We can't use the second way right now, since there is no reliable way how to
19150;; verify that given register is live. First choice will also most likely in
19151;; fewer dependencies. On the place of esp adjustments it is very likely that
19152;; call clobbered registers are dead. We may want to use base pointer as an
19153;; alternative when no register is available later.
19154
19155(define_peephole2
19156 [(match_scratch:SI 0 "r")
8bc527af
SB
19157 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19158 (clobber (reg:CC FLAGS_REG))
f2042df3 19159 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
19160 "optimize_size || !TARGET_SUB_ESP_4"
19161 [(clobber (match_dup 0))
8bc527af 19162 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
f2042df3 19163 (clobber (mem:BLK (scratch)))])])
bdeb029c
JH
19164
19165(define_peephole2
19166 [(match_scratch:SI 0 "r")
8bc527af
SB
19167 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19168 (clobber (reg:CC FLAGS_REG))
f2042df3 19169 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
19170 "optimize_size || !TARGET_SUB_ESP_8"
19171 [(clobber (match_dup 0))
8bc527af
SB
19172 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19173 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
f2042df3 19174 (clobber (mem:BLK (scratch)))])])
bdeb029c 19175
f5143c46 19176;; Convert esp subtractions to push.
bdeb029c
JH
19177(define_peephole2
19178 [(match_scratch:SI 0 "r")
8bc527af
SB
19179 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19180 (clobber (reg:CC FLAGS_REG))])]
bdeb029c
JH
19181 "optimize_size || !TARGET_SUB_ESP_4"
19182 [(clobber (match_dup 0))
8bc527af 19183 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
bdeb029c
JH
19184
19185(define_peephole2
19186 [(match_scratch:SI 0 "r")
8bc527af
SB
19187 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19188 (clobber (reg:CC FLAGS_REG))])]
bdeb029c
JH
19189 "optimize_size || !TARGET_SUB_ESP_8"
19190 [(clobber (match_dup 0))
8bc527af
SB
19191 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19192 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
bdeb029c
JH
19193
19194;; Convert epilogue deallocator to pop.
19195(define_peephole2
19196 [(match_scratch:SI 0 "r")
8bc527af
SB
19197 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19198 (clobber (reg:CC FLAGS_REG))
f2042df3 19199 (clobber (mem:BLK (scratch)))])]
bdeb029c 19200 "optimize_size || !TARGET_ADD_ESP_4"
8bc527af
SB
19201 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19202 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 19203 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
19204 "")
19205
19206;; Two pops case is tricky, since pop causes dependency on destination register.
19207;; We use two registers if available.
19208(define_peephole2
19209 [(match_scratch:SI 0 "r")
19210 (match_scratch:SI 1 "r")
8bc527af
SB
19211 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19212 (clobber (reg:CC FLAGS_REG))
f2042df3 19213 (clobber (mem:BLK (scratch)))])]
bdeb029c 19214 "optimize_size || !TARGET_ADD_ESP_8"
8bc527af
SB
19215 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19216 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 19217 (clobber (mem:BLK (scratch)))])
8bc527af
SB
19218 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19219 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
19220 "")
19221
19222(define_peephole2
19223 [(match_scratch:SI 0 "r")
8bc527af
SB
19224 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19225 (clobber (reg:CC FLAGS_REG))
f2042df3 19226 (clobber (mem:BLK (scratch)))])]
bdeb029c 19227 "optimize_size"
8bc527af
SB
19228 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19229 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 19230 (clobber (mem:BLK (scratch)))])
8bc527af
SB
19231 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19232 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
19233 "")
19234
19235;; Convert esp additions to pop.
19236(define_peephole2
19237 [(match_scratch:SI 0 "r")
8bc527af
SB
19238 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19239 (clobber (reg:CC FLAGS_REG))])]
bdeb029c 19240 ""
8bc527af
SB
19241 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19242 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
19243 "")
19244
19245;; Two pops case is tricky, since pop causes dependency on destination register.
19246;; We use two registers if available.
19247(define_peephole2
19248 [(match_scratch:SI 0 "r")
19249 (match_scratch:SI 1 "r")
8bc527af
SB
19250 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19251 (clobber (reg:CC FLAGS_REG))])]
bdeb029c 19252 ""
8bc527af
SB
19253 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19254 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19255 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19256 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
19257 "")
19258
19259(define_peephole2
19260 [(match_scratch:SI 0 "r")
8bc527af
SB
19261 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19262 (clobber (reg:CC FLAGS_REG))])]
bdeb029c 19263 "optimize_size"
8bc527af
SB
19264 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19265 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19266 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19267 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c 19268 "")
69404d6f 19269\f
9dcbdc7e 19270;; Convert compares with 1 to shorter inc/dec operations when CF is not
25da5dc7 19271;; required and register dies. Similarly for 128 to plus -128.
9dcbdc7e 19272(define_peephole2
25da5dc7
RH
19273 [(set (match_operand 0 "flags_reg_operand" "")
19274 (match_operator 1 "compare_operator"
19275 [(match_operand 2 "register_operand" "")
19276 (match_operand 3 "const_int_operand" "")]))]
19277 "(INTVAL (operands[3]) == -1
19278 || INTVAL (operands[3]) == 1
19279 || INTVAL (operands[3]) == 128)
19280 && ix86_match_ccmode (insn, CCGCmode)
19281 && peep2_reg_dead_p (1, operands[2])"
19282 [(parallel [(set (match_dup 0)
19283 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19284 (clobber (match_dup 2))])]
9dcbdc7e
JH
19285 "")
19286\f
cc2e591b
JH
19287(define_peephole2
19288 [(match_scratch:DI 0 "r")
8bc527af
SB
19289 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19290 (clobber (reg:CC FLAGS_REG))
f2042df3 19291 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
19292 "optimize_size || !TARGET_SUB_ESP_4"
19293 [(clobber (match_dup 0))
8bc527af 19294 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
f2042df3 19295 (clobber (mem:BLK (scratch)))])])
cc2e591b
JH
19296
19297(define_peephole2
19298 [(match_scratch:DI 0 "r")
8bc527af
SB
19299 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19300 (clobber (reg:CC FLAGS_REG))
f2042df3 19301 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
19302 "optimize_size || !TARGET_SUB_ESP_8"
19303 [(clobber (match_dup 0))
8bc527af
SB
19304 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19305 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
f2042df3 19306 (clobber (mem:BLK (scratch)))])])
cc2e591b 19307
f5143c46 19308;; Convert esp subtractions to push.
cc2e591b
JH
19309(define_peephole2
19310 [(match_scratch:DI 0 "r")
8bc527af
SB
19311 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19312 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
19313 "optimize_size || !TARGET_SUB_ESP_4"
19314 [(clobber (match_dup 0))
8bc527af 19315 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
cc2e591b
JH
19316
19317(define_peephole2
19318 [(match_scratch:DI 0 "r")
8bc527af
SB
19319 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19320 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
19321 "optimize_size || !TARGET_SUB_ESP_8"
19322 [(clobber (match_dup 0))
8bc527af
SB
19323 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19324 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
cc2e591b
JH
19325
19326;; Convert epilogue deallocator to pop.
19327(define_peephole2
19328 [(match_scratch:DI 0 "r")
8bc527af
SB
19329 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19330 (clobber (reg:CC FLAGS_REG))
f2042df3 19331 (clobber (mem:BLK (scratch)))])]
cc2e591b 19332 "optimize_size || !TARGET_ADD_ESP_4"
8bc527af
SB
19333 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19334 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 19335 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
19336 "")
19337
19338;; Two pops case is tricky, since pop causes dependency on destination register.
19339;; We use two registers if available.
19340(define_peephole2
19341 [(match_scratch:DI 0 "r")
19342 (match_scratch:DI 1 "r")
8bc527af
SB
19343 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19344 (clobber (reg:CC FLAGS_REG))
f2042df3 19345 (clobber (mem:BLK (scratch)))])]
cc2e591b 19346 "optimize_size || !TARGET_ADD_ESP_8"
8bc527af
SB
19347 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19348 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 19349 (clobber (mem:BLK (scratch)))])
8bc527af
SB
19350 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19351 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
19352 "")
19353
19354(define_peephole2
19355 [(match_scratch:DI 0 "r")
8bc527af
SB
19356 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19357 (clobber (reg:CC FLAGS_REG))
f2042df3 19358 (clobber (mem:BLK (scratch)))])]
cc2e591b 19359 "optimize_size"
8bc527af
SB
19360 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19361 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 19362 (clobber (mem:BLK (scratch)))])
8bc527af
SB
19363 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19364 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
19365 "")
19366
19367;; Convert esp additions to pop.
19368(define_peephole2
19369 [(match_scratch:DI 0 "r")
8bc527af
SB
19370 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19371 (clobber (reg:CC FLAGS_REG))])]
cc2e591b 19372 ""
8bc527af
SB
19373 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19374 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
19375 "")
19376
19377;; Two pops case is tricky, since pop causes dependency on destination register.
19378;; We use two registers if available.
19379(define_peephole2
19380 [(match_scratch:DI 0 "r")
19381 (match_scratch:DI 1 "r")
8bc527af
SB
19382 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19383 (clobber (reg:CC FLAGS_REG))])]
cc2e591b 19384 ""
8bc527af
SB
19385 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19386 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19387 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19388 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
19389 "")
19390
19391(define_peephole2
19392 [(match_scratch:DI 0 "r")
8bc527af
SB
19393 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19394 (clobber (reg:CC FLAGS_REG))])]
cc2e591b 19395 "optimize_size"
8bc527af
SB
19396 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19397 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19398 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19399 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
19400 "")
19401\f
cf14e33d
RS
19402;; Convert imul by three, five and nine into lea
19403(define_peephole2
19404 [(parallel
19405 [(set (match_operand:SI 0 "register_operand" "")
19406 (mult:SI (match_operand:SI 1 "register_operand" "")
19407 (match_operand:SI 2 "const_int_operand" "")))
19408 (clobber (reg:CC FLAGS_REG))])]
19409 "INTVAL (operands[2]) == 3
19410 || INTVAL (operands[2]) == 5
19411 || INTVAL (operands[2]) == 9"
19412 [(set (match_dup 0)
19413 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19414 (match_dup 1)))]
19415 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19416
19417(define_peephole2
19418 [(parallel
19419 [(set (match_operand:SI 0 "register_operand" "")
19420 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19421 (match_operand:SI 2 "const_int_operand" "")))
19422 (clobber (reg:CC FLAGS_REG))])]
19423 "!optimize_size
19424 && (INTVAL (operands[2]) == 3
19425 || INTVAL (operands[2]) == 5
19426 || INTVAL (operands[2]) == 9)"
19427 [(set (match_dup 0) (match_dup 1))
19428 (set (match_dup 0)
19429 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19430 (match_dup 0)))]
19431 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19432
19433(define_peephole2
19434 [(parallel
19435 [(set (match_operand:DI 0 "register_operand" "")
19436 (mult:DI (match_operand:DI 1 "register_operand" "")
19437 (match_operand:DI 2 "const_int_operand" "")))
19438 (clobber (reg:CC FLAGS_REG))])]
19439 "TARGET_64BIT
19440 && (INTVAL (operands[2]) == 3
19441 || INTVAL (operands[2]) == 5
19442 || INTVAL (operands[2]) == 9)"
19443 [(set (match_dup 0)
19444 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19445 (match_dup 1)))]
19446 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19447
19448(define_peephole2
19449 [(parallel
19450 [(set (match_operand:DI 0 "register_operand" "")
19451 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19452 (match_operand:DI 2 "const_int_operand" "")))
19453 (clobber (reg:CC FLAGS_REG))])]
19454 "TARGET_64BIT
19455 && !optimize_size
19456 && (INTVAL (operands[2]) == 3
19457 || INTVAL (operands[2]) == 5
19458 || INTVAL (operands[2]) == 9)"
19459 [(set (match_dup 0) (match_dup 1))
19460 (set (match_dup 0)
19461 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19462 (match_dup 0)))]
19463 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19464
f56e86bd
JH
19465;; Imul $32bit_imm, mem, reg is vector decoded, while
19466;; imul $32bit_imm, reg, reg is direct decoded.
19467(define_peephole2
19468 [(match_scratch:DI 3 "r")
19469 (parallel [(set (match_operand:DI 0 "register_operand" "")
19470 (mult:DI (match_operand:DI 1 "memory_operand" "")
19471 (match_operand:DI 2 "immediate_operand" "")))
8bc527af 19472 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
19473 "TARGET_K8 && !optimize_size
19474 && (GET_CODE (operands[2]) != CONST_INT
19475 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19476 [(set (match_dup 3) (match_dup 1))
19477 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
8bc527af 19478 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
19479"")
19480
19481(define_peephole2
19482 [(match_scratch:SI 3 "r")
19483 (parallel [(set (match_operand:SI 0 "register_operand" "")
19484 (mult:SI (match_operand:SI 1 "memory_operand" "")
19485 (match_operand:SI 2 "immediate_operand" "")))
8bc527af 19486 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
19487 "TARGET_K8 && !optimize_size
19488 && (GET_CODE (operands[2]) != CONST_INT
19489 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19490 [(set (match_dup 3) (match_dup 1))
19491 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
8bc527af 19492 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
19493"")
19494
19495(define_peephole2
19496 [(match_scratch:SI 3 "r")
19497 (parallel [(set (match_operand:DI 0 "register_operand" "")
19498 (zero_extend:DI
19499 (mult:SI (match_operand:SI 1 "memory_operand" "")
19500 (match_operand:SI 2 "immediate_operand" ""))))
8bc527af 19501 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
19502 "TARGET_K8 && !optimize_size
19503 && (GET_CODE (operands[2]) != CONST_INT
19504 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19505 [(set (match_dup 3) (match_dup 1))
19506 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
8bc527af 19507 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
19508"")
19509
19510;; imul $8/16bit_imm, regmem, reg is vector decoded.
19511;; Convert it into imul reg, reg
19512;; It would be better to force assembler to encode instruction using long
19513;; immediate, but there is apparently no way to do so.
19514(define_peephole2
19515 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19516 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19517 (match_operand:DI 2 "const_int_operand" "")))
8bc527af 19518 (clobber (reg:CC FLAGS_REG))])
f56e86bd
JH
19519 (match_scratch:DI 3 "r")]
19520 "TARGET_K8 && !optimize_size
19521 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19522 [(set (match_dup 3) (match_dup 2))
19523 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
8bc527af 19524 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
19525{
19526 if (!rtx_equal_p (operands[0], operands[1]))
19527 emit_move_insn (operands[0], operands[1]);
19528})
19529
19530(define_peephole2
19531 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19532 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19533 (match_operand:SI 2 "const_int_operand" "")))
8bc527af 19534 (clobber (reg:CC FLAGS_REG))])
f56e86bd
JH
19535 (match_scratch:SI 3 "r")]
19536 "TARGET_K8 && !optimize_size
19537 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19538 [(set (match_dup 3) (match_dup 2))
19539 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
8bc527af 19540 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
19541{
19542 if (!rtx_equal_p (operands[0], operands[1]))
19543 emit_move_insn (operands[0], operands[1]);
19544})
19545
19546(define_peephole2
19547 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19548 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19549 (match_operand:HI 2 "immediate_operand" "")))
8bc527af 19550 (clobber (reg:CC FLAGS_REG))])
f56e86bd
JH
19551 (match_scratch:HI 3 "r")]
19552 "TARGET_K8 && !optimize_size"
19553 [(set (match_dup 3) (match_dup 2))
19554 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
8bc527af 19555 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
19556{
19557 if (!rtx_equal_p (operands[0], operands[1]))
19558 emit_move_insn (operands[0], operands[1]);
19559})
19560\f
69404d6f
RH
19561;; Call-value patterns last so that the wildcard operand does not
19562;; disrupt insn-recog's switch tables.
19563
94bb5d0c
RH
19564(define_insn "*call_value_pop_0"
19565 [(set (match_operand 0 "" "")
e1ff012c 19566 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c 19567 (match_operand:SI 2 "" "")))
8bc527af 19568 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 19569 (match_operand:SI 3 "immediate_operand" "")))]
1e07edd3 19570 "!TARGET_64BIT"
94bb5d0c
RH
19571{
19572 if (SIBLING_CALL_P (insn))
0f40f9f7 19573 return "jmp\t%P1";
94bb5d0c 19574 else
0f40f9f7
ZW
19575 return "call\t%P1";
19576}
94bb5d0c
RH
19577 [(set_attr "type" "callv")])
19578
69404d6f
RH
19579(define_insn "*call_value_pop_1"
19580 [(set (match_operand 0 "" "")
e1ff012c 19581 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
94bb5d0c 19582 (match_operand:SI 2 "" "")))
8bc527af 19583 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 19584 (match_operand:SI 3 "immediate_operand" "i")))]
1e07edd3 19585 "!TARGET_64BIT"
69404d6f 19586{
e427abbf 19587 if (constant_call_address_operand (operands[1], Pmode))
94bb5d0c
RH
19588 {
19589 if (SIBLING_CALL_P (insn))
0f40f9f7 19590 return "jmp\t%P1";
94bb5d0c 19591 else
0f40f9f7 19592 return "call\t%P1";
94bb5d0c 19593 }
94bb5d0c 19594 if (SIBLING_CALL_P (insn))
0f40f9f7 19595 return "jmp\t%A1";
94bb5d0c 19596 else
0f40f9f7
ZW
19597 return "call\t%A1";
19598}
94bb5d0c
RH
19599 [(set_attr "type" "callv")])
19600
19601(define_insn "*call_value_0"
19602 [(set (match_operand 0 "" "")
e1ff012c 19603 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c 19604 (match_operand:SI 2 "" "")))]
32ee7d1d 19605 "!TARGET_64BIT"
32ee7d1d
JH
19606{
19607 if (SIBLING_CALL_P (insn))
0f40f9f7 19608 return "jmp\t%P1";
32ee7d1d 19609 else
0f40f9f7
ZW
19610 return "call\t%P1";
19611}
32ee7d1d
JH
19612 [(set_attr "type" "callv")])
19613
19614(define_insn "*call_value_0_rex64"
19615 [(set (match_operand 0 "" "")
19616 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19617 (match_operand:DI 2 "const_int_operand" "")))]
19618 "TARGET_64BIT"
94bb5d0c
RH
19619{
19620 if (SIBLING_CALL_P (insn))
0f40f9f7 19621 return "jmp\t%P1";
94bb5d0c 19622 else
0f40f9f7
ZW
19623 return "call\t%P1";
19624}
69404d6f
RH
19625 [(set_attr "type" "callv")])
19626
69404d6f
RH
19627(define_insn "*call_value_1"
19628 [(set (match_operand 0 "" "")
e1ff012c 19629 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
94bb5d0c 19630 (match_operand:SI 2 "" "")))]
4977bab6 19631 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
32ee7d1d 19632{
e427abbf 19633 if (constant_call_address_operand (operands[1], Pmode))
4977bab6 19634 return "call\t%P1";
6a46f71d 19635 return "call\t%A1";
4977bab6
ZW
19636}
19637 [(set_attr "type" "callv")])
19638
19639(define_insn "*sibcall_value_1"
19640 [(set (match_operand 0 "" "")
19641 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19642 (match_operand:SI 2 "" "")))]
19643 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19644{
e427abbf 19645 if (constant_call_address_operand (operands[1], Pmode))
4977bab6 19646 return "jmp\t%P1";
6a46f71d 19647 return "jmp\t%A1";
0f40f9f7 19648}
32ee7d1d
JH
19649 [(set_attr "type" "callv")])
19650
19651(define_insn "*call_value_1_rex64"
19652 [(set (match_operand 0 "" "")
19653 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19654 (match_operand:DI 2 "" "")))]
4977bab6 19655 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
69404d6f 19656{
e427abbf 19657 if (constant_call_address_operand (operands[1], Pmode))
4977bab6
ZW
19658 return "call\t%P1";
19659 return "call\t%A1";
0f40f9f7 19660}
69404d6f 19661 [(set_attr "type" "callv")])
4977bab6
ZW
19662
19663(define_insn "*sibcall_value_1_rex64"
19664 [(set (match_operand 0 "" "")
19665 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19666 (match_operand:DI 2 "" "")))]
19667 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19668 "jmp\t%P1"
19669 [(set_attr "type" "callv")])
19670
19671(define_insn "*sibcall_value_1_rex64_v"
19672 [(set (match_operand 0 "" "")
19673 (call (mem:QI (reg:DI 40))
19674 (match_operand:DI 1 "" "")))]
19675 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19676 "jmp\t*%%r11"
19677 [(set_attr "type" "callv")])
9e3e266c
GM
19678\f
19679(define_insn "trap"
19680 [(trap_if (const_int 1) (const_int 5))]
19681 ""
0f40f9f7 19682 "int\t$5")
9e3e266c
GM
19683
19684;;; ix86 doesn't have conditional trap instructions, but we fake them
19685;;; for the sake of bounds checking. By emitting bounds checks as
19686;;; conditional traps rather than as conditional jumps around
19687;;; unconditional traps we avoid introducing spurious basic-block
19688;;; boundaries and facilitate elimination of redundant checks. In
19689;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19690;;; interrupt 5.
19691;;;
19692;;; FIXME: Static branch prediction rules for ix86 are such that
19693;;; forward conditional branches predict as untaken. As implemented
19694;;; below, pseudo conditional traps violate that rule. We should use
19695;;; .pushsection/.popsection to place all of the `int 5's in a special
19696;;; section loaded at the end of the text segment and branch forward
19697;;; there on bounds-failure, and then jump back immediately (in case
19698;;; the system chooses to ignore bounds violations, or to report
19699;;; violations and continue execution).
19700
19701(define_expand "conditional_trap"
19702 [(trap_if (match_operator 0 "comparison_operator"
19703 [(match_dup 2) (const_int 0)])
19704 (match_operand 1 "const_int_operand" ""))]
19705 ""
9e3e266c
GM
19706{
19707 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
a1b8572c 19708 ix86_expand_compare (GET_CODE (operands[0]),
df4ae160 19709 NULL, NULL),
9e3e266c
GM
19710 operands[1]));
19711 DONE;
0f40f9f7 19712})
9e3e266c 19713
0f40f9f7 19714(define_insn "*conditional_trap_1"
9e3e266c 19715 [(trap_if (match_operator 0 "comparison_operator"
42fabf21 19716 [(reg FLAGS_REG) (const_int 0)])
9e3e266c
GM
19717 (match_operand 1 "const_int_operand" ""))]
19718 ""
9e3e266c
GM
19719{
19720 operands[2] = gen_label_rtx ();
0f40f9f7 19721 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
4977bab6 19722 (*targetm.asm_out.internal_label) (asm_out_file, "L",
9e3e266c
GM
19723 CODE_LABEL_NUMBER (operands[2]));
19724 RET;
0f40f9f7 19725})
915119a5
BS
19726
19727 ;; Pentium III SIMD instructions.
19728
19729;; Moves for SSE/MMX regs.
19730
19731(define_insn "movv4sf_internal"
fdc4b40b
JH
19732 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19733 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
915119a5 19734 "TARGET_SSE"
fdc4b40b
JH
19735 "@
19736 xorps\t%0, %0
19737 movaps\t{%1, %0|%0, %1}
19738 movaps\t{%1, %0|%0, %1}"
3d34cd91
JH
19739 [(set_attr "type" "ssemov")
19740 (set_attr "mode" "V4SF")])
915119a5 19741
4977bab6
ZW
19742(define_split
19743 [(set (match_operand:V4SF 0 "register_operand" "")
19744 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
7cacf53e 19745 "TARGET_SSE && reload_completed"
4977bab6
ZW
19746 [(set (match_dup 0)
19747 (vec_merge:V4SF
19748 (vec_duplicate:V4SF (match_dup 1))
19749 (match_dup 2)
19750 (const_int 1)))]
19751{
19752 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19753 operands[2] = CONST0_RTX (V4SFmode);
19754})
19755
915119a5 19756(define_insn "movv4si_internal"
fdc4b40b
JH
19757 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19758 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
915119a5 19759 "TARGET_SSE"
4977bab6 19760{
fdc4b40b
JH
19761 switch (which_alternative)
19762 {
19763 case 0:
19764 if (get_attr_mode (insn) == MODE_V4SF)
19765 return "xorps\t%0, %0";
19766 else
19767 return "pxor\t%0, %0";
19768 case 1:
19769 case 2:
19770 if (get_attr_mode (insn) == MODE_V4SF)
19771 return "movaps\t{%1, %0|%0, %1}";
19772 else
19773 return "movdqa\t{%1, %0|%0, %1}";
19774 default:
19775 abort ();
19776 }
4977bab6 19777}
3d34cd91 19778 [(set_attr "type" "ssemov")
4977bab6 19779 (set (attr "mode")
fdc4b40b 19780 (cond [(eq_attr "alternative" "0,1")
4977bab6
ZW
19781 (if_then_else
19782 (ne (symbol_ref "optimize_size")
19783 (const_int 0))
19784 (const_string "V4SF")
19785 (const_string "TI"))
fdc4b40b 19786 (eq_attr "alternative" "2")
4977bab6
ZW
19787 (if_then_else
19788 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19789 (const_int 0))
19790 (ne (symbol_ref "optimize_size")
19791 (const_int 0)))
19792 (const_string "V4SF")
19793 (const_string "TI"))]
19794 (const_string "TI")))])
915119a5 19795
1877be45 19796(define_insn "movv2di_internal"
fdc4b40b
JH
19797 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19798 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
84289c76 19799 "TARGET_SSE"
4977bab6 19800{
fdc4b40b
JH
19801 switch (which_alternative)
19802 {
19803 case 0:
19804 if (get_attr_mode (insn) == MODE_V4SF)
19805 return "xorps\t%0, %0";
19806 else
19807 return "pxor\t%0, %0";
19808 case 1:
19809 case 2:
19810 if (get_attr_mode (insn) == MODE_V4SF)
19811 return "movaps\t{%1, %0|%0, %1}";
19812 else
19813 return "movdqa\t{%1, %0|%0, %1}";
19814 default:
19815 abort ();
19816 }
4977bab6 19817}
1877be45 19818 [(set_attr "type" "ssemov")
4977bab6 19819 (set (attr "mode")
fdc4b40b 19820 (cond [(eq_attr "alternative" "0,1")
4977bab6
ZW
19821 (if_then_else
19822 (ne (symbol_ref "optimize_size")
19823 (const_int 0))
19824 (const_string "V4SF")
19825 (const_string "TI"))
fdc4b40b 19826 (eq_attr "alternative" "2")
4977bab6
ZW
19827 (if_then_else
19828 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19829 (const_int 0))
19830 (ne (symbol_ref "optimize_size")
19831 (const_int 0)))
19832 (const_string "V4SF")
19833 (const_string "TI"))]
19834 (const_string "TI")))])
19835
19836(define_split
19837 [(set (match_operand:V2DF 0 "register_operand" "")
19838 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
7cacf53e 19839 "TARGET_SSE2 && reload_completed"
4977bab6
ZW
19840 [(set (match_dup 0)
19841 (vec_merge:V2DF
19842 (vec_duplicate:V2DF (match_dup 1))
19843 (match_dup 2)
19844 (const_int 1)))]
19845{
19846 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19847 operands[2] = CONST0_RTX (V2DFmode);
19848})
1877be45 19849
915119a5 19850(define_insn "movv8qi_internal"
9e9fb0ce
JB
19851 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19852 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
7f0e57bd
JH
19853 "TARGET_MMX
19854 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
fdc4b40b
JH
19855 "@
19856 pxor\t%0, %0
19857 movq\t{%1, %0|%0, %1}
9e9fb0ce
JB
19858 movq\t{%1, %0|%0, %1}
19859 movdq2q\t{%1, %0|%0, %1}
19860 movq2dq\t{%1, %0|%0, %1}
19861 movq\t{%1, %0|%0, %1}
fdc4b40b 19862 movq\t{%1, %0|%0, %1}"
9e9fb0ce 19863 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
3d34cd91 19864 (set_attr "mode" "DI")])
915119a5
BS
19865
19866(define_insn "movv4hi_internal"
9e9fb0ce
JB
19867 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19868 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
7f0e57bd
JH
19869 "TARGET_MMX
19870 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
fdc4b40b
JH
19871 "@
19872 pxor\t%0, %0
19873 movq\t{%1, %0|%0, %1}
9e9fb0ce
JB
19874 movq\t{%1, %0|%0, %1}
19875 movdq2q\t{%1, %0|%0, %1}
19876 movq2dq\t{%1, %0|%0, %1}
19877 movq\t{%1, %0|%0, %1}
fdc4b40b 19878 movq\t{%1, %0|%0, %1}"
9e9fb0ce 19879 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
3d34cd91 19880 (set_attr "mode" "DI")])
915119a5 19881
9e9fb0ce
JB
19882(define_insn "*movv2si_internal"
19883 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19884 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
7f0e57bd
JH
19885 "TARGET_MMX
19886 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
fdc4b40b
JH
19887 "@
19888 pxor\t%0, %0
19889 movq\t{%1, %0|%0, %1}
9e9fb0ce
JB
19890 movq\t{%1, %0|%0, %1}
19891 movdq2q\t{%1, %0|%0, %1}
19892 movq2dq\t{%1, %0|%0, %1}
19893 movq\t{%1, %0|%0, %1}
fdc4b40b 19894 movq\t{%1, %0|%0, %1}"
9e9fb0ce 19895 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
3d34cd91 19896 (set_attr "mode" "DI")])
915119a5 19897
47f339cf 19898(define_insn "movv2sf_internal"
9e9fb0ce
JB
19899 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
19900 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
7f0e57bd
JH
19901 "TARGET_3DNOW
19902 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
fdc4b40b
JH
19903 "@
19904 pxor\t%0, %0
19905 movq\t{%1, %0|%0, %1}
9e9fb0ce
JB
19906 movq\t{%1, %0|%0, %1}
19907 movdq2q\t{%1, %0|%0, %1}
19908 movq2dq\t{%1, %0|%0, %1}
19909 movlps\t{%1, %0|%0, %1}
19910 movlps\t{%1, %0|%0, %1}"
19911 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19912 (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
47f339cf 19913
915119a5 19914(define_expand "movti"
7f0e57bd
JH
19915 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19916 (match_operand:TI 1 "nonimmediate_operand" ""))]
44cf5b6a 19917 "TARGET_SSE || TARGET_64BIT"
915119a5 19918{
44cf5b6a 19919 if (TARGET_64BIT)
e37af218
RH
19920 ix86_expand_move (TImode, operands);
19921 else
19922 ix86_expand_vector_move (TImode, operands);
19923 DONE;
0f40f9f7 19924})
915119a5 19925
f8a1ebc6
JH
19926(define_expand "movtf"
19927 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19928 (match_operand:TF 1 "nonimmediate_operand" ""))]
19929 "TARGET_64BIT"
19930{
19931 if (TARGET_64BIT)
19932 ix86_expand_move (TFmode, operands);
19933 else
19934 ix86_expand_vector_move (TFmode, operands);
19935 DONE;
19936})
19937
fbe5eb6d 19938(define_insn "movv2df_internal"
fdc4b40b
JH
19939 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19940 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
7f0e57bd
JH
19941 "TARGET_SSE2
19942 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4977bab6 19943{
fdc4b40b
JH
19944 switch (which_alternative)
19945 {
19946 case 0:
19947 if (get_attr_mode (insn) == MODE_V4SF)
19948 return "xorps\t%0, %0";
19949 else
19950 return "xorpd\t%0, %0";
19951 case 1:
19952 case 2:
19953 if (get_attr_mode (insn) == MODE_V4SF)
19954 return "movaps\t{%1, %0|%0, %1}";
19955 else
19956 return "movapd\t{%1, %0|%0, %1}";
19957 default:
19958 abort ();
19959 }
4977bab6 19960}
3d34cd91 19961 [(set_attr "type" "ssemov")
4977bab6 19962 (set (attr "mode")
fdc4b40b 19963 (cond [(eq_attr "alternative" "0,1")
4977bab6
ZW
19964 (if_then_else
19965 (ne (symbol_ref "optimize_size")
19966 (const_int 0))
19967 (const_string "V4SF")
19968 (const_string "V2DF"))
fdc4b40b 19969 (eq_attr "alternative" "2")
4977bab6
ZW
19970 (if_then_else
19971 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19972 (const_int 0))
19973 (ne (symbol_ref "optimize_size")
19974 (const_int 0)))
19975 (const_string "V4SF")
19976 (const_string "V2DF"))]
19977 (const_string "V2DF")))])
fbe5eb6d
BS
19978
19979(define_insn "movv8hi_internal"
fdc4b40b
JH
19980 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19981 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
7f0e57bd
JH
19982 "TARGET_SSE2
19983 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4977bab6 19984{
fdc4b40b
JH
19985 switch (which_alternative)
19986 {
19987 case 0:
19988 if (get_attr_mode (insn) == MODE_V4SF)
19989 return "xorps\t%0, %0";
19990 else
19991 return "pxor\t%0, %0";
19992 case 1:
19993 case 2:
19994 if (get_attr_mode (insn) == MODE_V4SF)
19995 return "movaps\t{%1, %0|%0, %1}";
19996 else
19997 return "movdqa\t{%1, %0|%0, %1}";
19998 default:
19999 abort ();
20000 }
4977bab6 20001}
3d34cd91 20002 [(set_attr "type" "ssemov")
4977bab6 20003 (set (attr "mode")
fdc4b40b 20004 (cond [(eq_attr "alternative" "0,1")
4977bab6
ZW
20005 (if_then_else
20006 (ne (symbol_ref "optimize_size")
20007 (const_int 0))
20008 (const_string "V4SF")
20009 (const_string "TI"))
fdc4b40b 20010 (eq_attr "alternative" "2")
4977bab6
ZW
20011 (if_then_else
20012 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20013 (const_int 0))
20014 (ne (symbol_ref "optimize_size")
20015 (const_int 0)))
20016 (const_string "V4SF")
20017 (const_string "TI"))]
20018 (const_string "TI")))])
fbe5eb6d
BS
20019
20020(define_insn "movv16qi_internal"
fdc4b40b 20021 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
3e25b3a8 20022 (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
7f0e57bd
JH
20023 "TARGET_SSE2
20024 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4977bab6 20025{
fdc4b40b
JH
20026 switch (which_alternative)
20027 {
20028 case 0:
20029 if (get_attr_mode (insn) == MODE_V4SF)
20030 return "xorps\t%0, %0";
20031 else
20032 return "pxor\t%0, %0";
20033 case 1:
20034 case 2:
20035 if (get_attr_mode (insn) == MODE_V4SF)
20036 return "movaps\t{%1, %0|%0, %1}";
20037 else
20038 return "movdqa\t{%1, %0|%0, %1}";
20039 default:
20040 abort ();
20041 }
4977bab6 20042}
3d34cd91 20043 [(set_attr "type" "ssemov")
4977bab6 20044 (set (attr "mode")
fdc4b40b 20045 (cond [(eq_attr "alternative" "0,1")
4977bab6
ZW
20046 (if_then_else
20047 (ne (symbol_ref "optimize_size")
20048 (const_int 0))
20049 (const_string "V4SF")
20050 (const_string "TI"))
fdc4b40b 20051 (eq_attr "alternative" "2")
4977bab6
ZW
20052 (if_then_else
20053 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20054 (const_int 0))
20055 (ne (symbol_ref "optimize_size")
20056 (const_int 0)))
20057 (const_string "V4SF")
20058 (const_string "TI"))]
20059 (const_string "TI")))])
fbe5eb6d
BS
20060
20061(define_expand "movv2df"
7f0e57bd
JH
20062 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20063 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
fbe5eb6d
BS
20064 "TARGET_SSE2"
20065{
20066 ix86_expand_vector_move (V2DFmode, operands);
20067 DONE;
20068})
20069
20070(define_expand "movv8hi"
7f0e57bd
JH
20071 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20072 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
fbe5eb6d
BS
20073 "TARGET_SSE2"
20074{
20075 ix86_expand_vector_move (V8HImode, operands);
20076 DONE;
20077})
20078
20079(define_expand "movv16qi"
7f0e57bd
JH
20080 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20081 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
fbe5eb6d
BS
20082 "TARGET_SSE2"
20083{
20084 ix86_expand_vector_move (V16QImode, operands);
20085 DONE;
20086})
20087
915119a5 20088(define_expand "movv4sf"
7f0e57bd
JH
20089 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20090 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
915119a5 20091 "TARGET_SSE"
915119a5 20092{
e37af218
RH
20093 ix86_expand_vector_move (V4SFmode, operands);
20094 DONE;
0f40f9f7 20095})
915119a5
BS
20096
20097(define_expand "movv4si"
7f0e57bd
JH
20098 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20099 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
1877be45 20100 "TARGET_SSE"
915119a5 20101{
e37af218
RH
20102 ix86_expand_vector_move (V4SImode, operands);
20103 DONE;
0f40f9f7 20104})
915119a5 20105
1877be45 20106(define_expand "movv2di"
7f0e57bd
JH
20107 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20108 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
1877be45
JH
20109 "TARGET_SSE"
20110{
20111 ix86_expand_vector_move (V2DImode, operands);
20112 DONE;
20113})
20114
915119a5 20115(define_expand "movv2si"
7f0e57bd
JH
20116 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20117 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
915119a5 20118 "TARGET_MMX"
915119a5 20119{
e37af218
RH
20120 ix86_expand_vector_move (V2SImode, operands);
20121 DONE;
0f40f9f7 20122})
915119a5
BS
20123
20124(define_expand "movv4hi"
7f0e57bd
JH
20125 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20126 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
915119a5 20127 "TARGET_MMX"
915119a5 20128{
e37af218
RH
20129 ix86_expand_vector_move (V4HImode, operands);
20130 DONE;
0f40f9f7 20131})
915119a5
BS
20132
20133(define_expand "movv8qi"
7f0e57bd
JH
20134 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20135 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
915119a5 20136 "TARGET_MMX"
915119a5 20137{
e37af218
RH
20138 ix86_expand_vector_move (V8QImode, operands);
20139 DONE;
0f40f9f7 20140})
915119a5 20141
47f339cf 20142(define_expand "movv2sf"
7f0e57bd
JH
20143 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20144 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
47f339cf 20145 "TARGET_3DNOW"
47f339cf 20146{
e37af218
RH
20147 ix86_expand_vector_move (V2SFmode, operands);
20148 DONE;
20149})
47f339cf 20150
7f0e57bd 20151(define_insn "*pushti"
915119a5 20152 [(set (match_operand:TI 0 "push_operand" "=<")
7f0e57bd 20153 (match_operand:TI 1 "register_operand" "x"))]
915119a5 20154 "TARGET_SSE"
7f0e57bd 20155 "#")
915119a5 20156
7f0e57bd 20157(define_insn "*pushv2df"
fbe5eb6d 20158 [(set (match_operand:V2DF 0 "push_operand" "=<")
7f0e57bd
JH
20159 (match_operand:V2DF 1 "register_operand" "x"))]
20160 "TARGET_SSE"
20161 "#")
fbe5eb6d 20162
7f0e57bd 20163(define_insn "*pushv2di"
a00782ed 20164 [(set (match_operand:V2DI 0 "push_operand" "=<")
7f0e57bd 20165 (match_operand:V2DI 1 "register_operand" "x"))]
a00782ed 20166 "TARGET_SSE2"
7f0e57bd 20167 "#")
a00782ed 20168
7f0e57bd 20169(define_insn "*pushv8hi"
fbe5eb6d 20170 [(set (match_operand:V8HI 0 "push_operand" "=<")
7f0e57bd 20171 (match_operand:V8HI 1 "register_operand" "x"))]
fbe5eb6d 20172 "TARGET_SSE2"
7f0e57bd 20173 "#")
fbe5eb6d 20174
7f0e57bd 20175(define_insn "*pushv16qi"
fbe5eb6d 20176 [(set (match_operand:V16QI 0 "push_operand" "=<")
7f0e57bd 20177 (match_operand:V16QI 1 "register_operand" "x"))]
fbe5eb6d 20178 "TARGET_SSE2"
7f0e57bd 20179 "#")
fbe5eb6d 20180
7f0e57bd 20181(define_insn "*pushv4sf"
915119a5 20182 [(set (match_operand:V4SF 0 "push_operand" "=<")
7f0e57bd 20183 (match_operand:V4SF 1 "register_operand" "x"))]
915119a5 20184 "TARGET_SSE"
7f0e57bd 20185 "#")
915119a5 20186
7f0e57bd 20187(define_insn "*pushv4si"
915119a5 20188 [(set (match_operand:V4SI 0 "push_operand" "=<")
7f0e57bd
JH
20189 (match_operand:V4SI 1 "register_operand" "x"))]
20190 "TARGET_SSE2"
20191 "#")
915119a5 20192
7f0e57bd 20193(define_insn "*pushv2si"
915119a5 20194 [(set (match_operand:V2SI 0 "push_operand" "=<")
7f0e57bd 20195 (match_operand:V2SI 1 "register_operand" "y"))]
915119a5 20196 "TARGET_MMX"
7f0e57bd 20197 "#")
915119a5 20198
7f0e57bd 20199(define_insn "*pushv4hi"
915119a5 20200 [(set (match_operand:V4HI 0 "push_operand" "=<")
7f0e57bd 20201 (match_operand:V4HI 1 "register_operand" "y"))]
915119a5 20202 "TARGET_MMX"
7f0e57bd 20203 "#")
915119a5 20204
7f0e57bd 20205(define_insn "*pushv8qi"
915119a5 20206 [(set (match_operand:V8QI 0 "push_operand" "=<")
7f0e57bd 20207 (match_operand:V8QI 1 "register_operand" "y"))]
915119a5 20208 "TARGET_MMX"
7f0e57bd 20209 "#")
915119a5 20210
7f0e57bd 20211(define_insn "*pushv2sf"
47f339cf 20212 [(set (match_operand:V2SF 0 "push_operand" "=<")
7f0e57bd 20213 (match_operand:V2SF 1 "register_operand" "y"))]
47f339cf 20214 "TARGET_3DNOW"
7f0e57bd
JH
20215 "#")
20216
20217(define_split
20218 [(set (match_operand 0 "push_operand" "")
20219 (match_operand 1 "register_operand" ""))]
20220 "!TARGET_64BIT && reload_completed
20221 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
8bc527af 20222 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
7f0e57bd
JH
20223 (set (match_dup 2) (match_dup 1))]
20224 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20225 stack_pointer_rtx);
09f26fb5 20226 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
7f0e57bd
JH
20227
20228(define_split
20229 [(set (match_operand 0 "push_operand" "")
20230 (match_operand 1 "register_operand" ""))]
20231 "TARGET_64BIT && reload_completed
20232 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
8bc527af 20233 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
7f0e57bd
JH
20234 (set (match_dup 2) (match_dup 1))]
20235 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20236 stack_pointer_rtx);
09f26fb5 20237 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
7f0e57bd 20238
47f339cf 20239
915119a5 20240(define_insn "movti_internal"
e37af218 20241 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
fdc4b40b 20242 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
7f0e57bd
JH
20243 "TARGET_SSE && !TARGET_64BIT
20244 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4977bab6
ZW
20245{
20246 switch (which_alternative)
20247 {
20248 case 0:
20249 if (get_attr_mode (insn) == MODE_V4SF)
20250 return "xorps\t%0, %0";
20251 else
20252 return "pxor\t%0, %0";
20253 case 1:
20254 case 2:
20255 if (get_attr_mode (insn) == MODE_V4SF)
20256 return "movaps\t{%1, %0|%0, %1}";
20257 else
20258 return "movdqa\t{%1, %0|%0, %1}";
20259 default:
20260 abort ();
20261 }
20262}
3d34cd91 20263 [(set_attr "type" "ssemov,ssemov,ssemov")
4977bab6
ZW
20264 (set (attr "mode")
20265 (cond [(eq_attr "alternative" "0,1")
20266 (if_then_else
20267 (ne (symbol_ref "optimize_size")
20268 (const_int 0))
20269 (const_string "V4SF")
20270 (const_string "TI"))
20271 (eq_attr "alternative" "2")
20272 (if_then_else
20273 (ne (symbol_ref "optimize_size")
20274 (const_int 0))
20275 (const_string "V4SF")
20276 (const_string "TI"))]
20277 (const_string "TI")))])
915119a5 20278
44cf5b6a 20279(define_insn "*movti_rex64"
4977bab6 20280 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
f0f0d98e 20281 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
44cf5b6a
JH
20282 "TARGET_64BIT
20283 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4977bab6
ZW
20284{
20285 switch (which_alternative)
20286 {
20287 case 0:
20288 case 1:
20289 return "#";
20290 case 2:
20291 if (get_attr_mode (insn) == MODE_V4SF)
20292 return "xorps\t%0, %0";
20293 else
20294 return "pxor\t%0, %0";
20295 case 3:
20296 case 4:
20297 if (get_attr_mode (insn) == MODE_V4SF)
20298 return "movaps\t{%1, %0|%0, %1}";
20299 else
20300 return "movdqa\t{%1, %0|%0, %1}";
20301 default:
20302 abort ();
20303 }
20304}
3d34cd91 20305 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
4977bab6
ZW
20306 (set (attr "mode")
20307 (cond [(eq_attr "alternative" "2,3")
20308 (if_then_else
20309 (ne (symbol_ref "optimize_size")
20310 (const_int 0))
20311 (const_string "V4SF")
20312 (const_string "TI"))
20313 (eq_attr "alternative" "4")
20314 (if_then_else
20315 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20316 (const_int 0))
20317 (ne (symbol_ref "optimize_size")
20318 (const_int 0)))
20319 (const_string "V4SF")
20320 (const_string "TI"))]
20321 (const_string "DI")))])
44cf5b6a 20322
f8a1ebc6
JH
20323(define_insn "*movtf_rex64"
20324 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20325 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20326 "TARGET_64BIT
20327 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20328{
20329 switch (which_alternative)
20330 {
20331 case 0:
20332 case 1:
20333 return "#";
20334 case 2:
20335 if (get_attr_mode (insn) == MODE_V4SF)
20336 return "xorps\t%0, %0";
20337 else
20338 return "pxor\t%0, %0";
20339 case 3:
20340 case 4:
20341 if (get_attr_mode (insn) == MODE_V4SF)
20342 return "movaps\t{%1, %0|%0, %1}";
20343 else
20344 return "movdqa\t{%1, %0|%0, %1}";
20345 default:
20346 abort ();
20347 }
20348}
20349 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20350 (set (attr "mode")
20351 (cond [(eq_attr "alternative" "2,3")
20352 (if_then_else
20353 (ne (symbol_ref "optimize_size")
20354 (const_int 0))
20355 (const_string "V4SF")
20356 (const_string "TI"))
20357 (eq_attr "alternative" "4")
20358 (if_then_else
20359 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20360 (const_int 0))
20361 (ne (symbol_ref "optimize_size")
20362 (const_int 0)))
20363 (const_string "V4SF")
20364 (const_string "TI"))]
20365 (const_string "DI")))])
20366
44cf5b6a
JH
20367(define_split
20368 [(set (match_operand:TI 0 "nonimmediate_operand" "")
20369 (match_operand:TI 1 "general_operand" ""))]
4fe8523b
JH
20370 "reload_completed && !SSE_REG_P (operands[0])
20371 && !SSE_REG_P (operands[1])"
44cf5b6a
JH
20372 [(const_int 0)]
20373 "ix86_split_long_move (operands); DONE;")
20374
f8a1ebc6
JH
20375(define_split
20376 [(set (match_operand:TF 0 "nonimmediate_operand" "")
20377 (match_operand:TF 1 "general_operand" ""))]
20378 "reload_completed && !SSE_REG_P (operands[0])
20379 && !SSE_REG_P (operands[1])"
20380 [(const_int 0)]
20381 "ix86_split_long_move (operands); DONE;")
20382
915119a5
BS
20383;; These two patterns are useful for specifying exactly whether to use
20384;; movaps or movups
ee4336ea
RH
20385(define_expand "sse_movaps"
20386 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20387 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20388 UNSPEC_MOVA))]
20389 "TARGET_SSE"
20390{
20391 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20392 {
20393 rtx tmp = gen_reg_rtx (V4SFmode);
20394 emit_insn (gen_sse_movaps (tmp, operands[1]));
20395 emit_move_insn (operands[0], tmp);
20396 DONE;
20397 }
20398})
20399
20400(define_insn "*sse_movaps_1"
915119a5 20401 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
8ee41eaf
RH
20402 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20403 UNSPEC_MOVA))]
7f0e57bd
JH
20404 "TARGET_SSE
20405 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20406 "movaps\t{%1, %0|%0, %1}"
3d34cd91
JH
20407 [(set_attr "type" "ssemov,ssemov")
20408 (set_attr "mode" "V4SF")])
915119a5 20409
ee4336ea
RH
20410(define_expand "sse_movups"
20411 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20412 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20413 UNSPEC_MOVU))]
20414 "TARGET_SSE"
20415{
20416 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20417 {
20418 rtx tmp = gen_reg_rtx (V4SFmode);
20419 emit_insn (gen_sse_movups (tmp, operands[1]));
20420 emit_move_insn (operands[0], tmp);
20421 DONE;
20422 }
20423})
20424
20425(define_insn "*sse_movups_1"
915119a5 20426 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
8ee41eaf
RH
20427 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20428 UNSPEC_MOVU))]
7f0e57bd
JH
20429 "TARGET_SSE
20430 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20431 "movups\t{%1, %0|%0, %1}"
3d34cd91
JH
20432 [(set_attr "type" "ssecvt,ssecvt")
20433 (set_attr "mode" "V4SF")])
915119a5 20434
915119a5
BS
20435;; SSE Strange Moves.
20436
20437(define_insn "sse_movmskps"
20438 [(set (match_operand:SI 0 "register_operand" "=r")
8ee41eaf
RH
20439 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20440 UNSPEC_MOVMSK))]
915119a5 20441 "TARGET_SSE"
0f40f9f7 20442 "movmskps\t{%1, %0|%0, %1}"
3d34cd91
JH
20443 [(set_attr "type" "ssecvt")
20444 (set_attr "mode" "V4SF")])
915119a5
BS
20445
20446(define_insn "mmx_pmovmskb"
20447 [(set (match_operand:SI 0 "register_operand" "=r")
8ee41eaf
RH
20448 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20449 UNSPEC_MOVMSK))]
47f339cf 20450 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 20451 "pmovmskb\t{%1, %0|%0, %1}"
3d34cd91
JH
20452 [(set_attr "type" "ssecvt")
20453 (set_attr "mode" "V4SF")])
20454
915119a5
BS
20455
20456(define_insn "mmx_maskmovq"
20457 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20458 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
8ee41eaf
RH
20459 (match_operand:V8QI 2 "register_operand" "y")]
20460 UNSPEC_MASKMOV))]
e95d6b23
JH
20461 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20462 ;; @@@ check ordering of operands in intel/nonintel syntax
20463 "maskmovq\t{%2, %1|%1, %2}"
3d34cd91
JH
20464 [(set_attr "type" "mmxcvt")
20465 (set_attr "mode" "DI")])
e95d6b23
JH
20466
20467(define_insn "mmx_maskmovq_rex"
20468 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20469 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
8ee41eaf
RH
20470 (match_operand:V8QI 2 "register_operand" "y")]
20471 UNSPEC_MASKMOV))]
e95d6b23 20472 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
915119a5 20473 ;; @@@ check ordering of operands in intel/nonintel syntax
0f40f9f7 20474 "maskmovq\t{%2, %1|%1, %2}"
3d34cd91
JH
20475 [(set_attr "type" "mmxcvt")
20476 (set_attr "mode" "DI")])
915119a5
BS
20477
20478(define_insn "sse_movntv4sf"
20479 [(set (match_operand:V4SF 0 "memory_operand" "=m")
8ee41eaf
RH
20480 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20481 UNSPEC_MOVNT))]
915119a5 20482 "TARGET_SSE"
0f40f9f7 20483 "movntps\t{%1, %0|%0, %1}"
3d34cd91
JH
20484 [(set_attr "type" "ssemov")
20485 (set_attr "mode" "V4SF")])
915119a5
BS
20486
20487(define_insn "sse_movntdi"
20488 [(set (match_operand:DI 0 "memory_operand" "=m")
8ee41eaf
RH
20489 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20490 UNSPEC_MOVNT))]
47f339cf 20491 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 20492 "movntq\t{%1, %0|%0, %1}"
3d34cd91
JH
20493 [(set_attr "type" "mmxmov")
20494 (set_attr "mode" "DI")])
915119a5
BS
20495
20496(define_insn "sse_movhlps"
20497 [(set (match_operand:V4SF 0 "register_operand" "=x")
20498 (vec_merge:V4SF
20499 (match_operand:V4SF 1 "register_operand" "0")
20500 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20501 (parallel [(const_int 2)
20502 (const_int 3)
20503 (const_int 0)
20504 (const_int 1)]))
20505 (const_int 3)))]
20506 "TARGET_SSE"
0f40f9f7 20507 "movhlps\t{%2, %0|%0, %2}"
3d34cd91
JH
20508 [(set_attr "type" "ssecvt")
20509 (set_attr "mode" "V4SF")])
915119a5
BS
20510
20511(define_insn "sse_movlhps"
20512 [(set (match_operand:V4SF 0 "register_operand" "=x")
20513 (vec_merge:V4SF
20514 (match_operand:V4SF 1 "register_operand" "0")
20515 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20516 (parallel [(const_int 2)
20517 (const_int 3)
20518 (const_int 0)
20519 (const_int 1)]))
20520 (const_int 12)))]
20521 "TARGET_SSE"
0f40f9f7 20522 "movlhps\t{%2, %0|%0, %2}"
3d34cd91
JH
20523 [(set_attr "type" "ssecvt")
20524 (set_attr "mode" "V4SF")])
915119a5
BS
20525
20526(define_insn "sse_movhps"
20527 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20528 (vec_merge:V4SF
20529 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20530 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20531 (const_int 12)))]
e37af218
RH
20532 "TARGET_SSE
20533 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
0f40f9f7 20534 "movhps\t{%2, %0|%0, %2}"
3d34cd91
JH
20535 [(set_attr "type" "ssecvt")
20536 (set_attr "mode" "V4SF")])
915119a5
BS
20537
20538(define_insn "sse_movlps"
20539 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20540 (vec_merge:V4SF
20541 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20542 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20543 (const_int 3)))]
e37af218
RH
20544 "TARGET_SSE
20545 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
0f40f9f7 20546 "movlps\t{%2, %0|%0, %2}"
3d34cd91
JH
20547 [(set_attr "type" "ssecvt")
20548 (set_attr "mode" "V4SF")])
915119a5 20549
4977bab6
ZW
20550(define_expand "sse_loadss"
20551 [(match_operand:V4SF 0 "register_operand" "")
20552 (match_operand:SF 1 "memory_operand" "")]
20553 "TARGET_SSE"
20554{
20555 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20556 CONST0_RTX (V4SFmode)));
20557 DONE;
20558})
20559
20560(define_insn "sse_loadss_1"
915119a5
BS
20561 [(set (match_operand:V4SF 0 "register_operand" "=x")
20562 (vec_merge:V4SF
4977bab6
ZW
20563 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20564 (match_operand:V4SF 2 "const0_operand" "X")
915119a5
BS
20565 (const_int 1)))]
20566 "TARGET_SSE"
0f40f9f7 20567 "movss\t{%1, %0|%0, %1}"
3d34cd91
JH
20568 [(set_attr "type" "ssemov")
20569 (set_attr "mode" "SF")])
915119a5
BS
20570
20571(define_insn "sse_movss"
20572 [(set (match_operand:V4SF 0 "register_operand" "=x")
20573 (vec_merge:V4SF
20574 (match_operand:V4SF 1 "register_operand" "0")
20575 (match_operand:V4SF 2 "register_operand" "x")
4049b376 20576 (const_int 14)))]
915119a5 20577 "TARGET_SSE"
0f40f9f7 20578 "movss\t{%2, %0|%0, %2}"
3d34cd91
JH
20579 [(set_attr "type" "ssemov")
20580 (set_attr "mode" "SF")])
915119a5
BS
20581
20582(define_insn "sse_storess"
20583 [(set (match_operand:SF 0 "memory_operand" "=m")
20584 (vec_select:SF
20585 (match_operand:V4SF 1 "register_operand" "x")
20586 (parallel [(const_int 0)])))]
20587 "TARGET_SSE"
0f40f9f7 20588 "movss\t{%1, %0|%0, %1}"
3d34cd91
JH
20589 [(set_attr "type" "ssemov")
20590 (set_attr "mode" "SF")])
915119a5
BS
20591
20592(define_insn "sse_shufps"
20593 [(set (match_operand:V4SF 0 "register_operand" "=x")
20594 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20595 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
8ee41eaf
RH
20596 (match_operand:SI 3 "immediate_operand" "i")]
20597 UNSPEC_SHUFFLE))]
915119a5
BS
20598 "TARGET_SSE"
20599 ;; @@@ check operand order for intel/nonintel syntax
0f40f9f7 20600 "shufps\t{%3, %2, %0|%0, %2, %3}"
3d34cd91
JH
20601 [(set_attr "type" "ssecvt")
20602 (set_attr "mode" "V4SF")])
915119a5
BS
20603
20604
20605;; SSE arithmetic
20606
20607(define_insn "addv4sf3"
20608 [(set (match_operand:V4SF 0 "register_operand" "=x")
20609 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20610 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20611 "TARGET_SSE"
0f40f9f7 20612 "addps\t{%2, %0|%0, %2}"
3d34cd91
JH
20613 [(set_attr "type" "sseadd")
20614 (set_attr "mode" "V4SF")])
915119a5
BS
20615
20616(define_insn "vmaddv4sf3"
20617 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218
RH
20618 (vec_merge:V4SF
20619 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20620 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20621 (match_dup 1)
20622 (const_int 1)))]
915119a5 20623 "TARGET_SSE"
0f40f9f7 20624 "addss\t{%2, %0|%0, %2}"
3d34cd91
JH
20625 [(set_attr "type" "sseadd")
20626 (set_attr "mode" "SF")])
915119a5
BS
20627
20628(define_insn "subv4sf3"
20629 [(set (match_operand:V4SF 0 "register_operand" "=x")
20630 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
e37af218 20631 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
915119a5 20632 "TARGET_SSE"
0f40f9f7 20633 "subps\t{%2, %0|%0, %2}"
3d34cd91
JH
20634 [(set_attr "type" "sseadd")
20635 (set_attr "mode" "V4SF")])
915119a5
BS
20636
20637(define_insn "vmsubv4sf3"
20638 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218
RH
20639 (vec_merge:V4SF
20640 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20641 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20642 (match_dup 1)
20643 (const_int 1)))]
915119a5 20644 "TARGET_SSE"
0f40f9f7 20645 "subss\t{%2, %0|%0, %2}"
3d34cd91
JH
20646 [(set_attr "type" "sseadd")
20647 (set_attr "mode" "SF")])
5c64c900
RH
20648
20649;; ??? Should probably be done by generic code instead.
20650(define_expand "negv4sf2"
20651 [(set (match_operand:V4SF 0 "register_operand" "")
20652 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20653 (match_dup 2)))]
20654 "TARGET_SSE"
20655{
20656 rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20657 rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20658 operands[2] = force_reg (V4SFmode, vm0);
20659})
915119a5
BS
20660
20661(define_insn "mulv4sf3"
20662 [(set (match_operand:V4SF 0 "register_operand" "=x")
20663 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20664 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20665 "TARGET_SSE"
0f40f9f7 20666 "mulps\t{%2, %0|%0, %2}"
3d34cd91
JH
20667 [(set_attr "type" "ssemul")
20668 (set_attr "mode" "V4SF")])
915119a5
BS
20669
20670(define_insn "vmmulv4sf3"
20671 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218
RH
20672 (vec_merge:V4SF
20673 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20674 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20675 (match_dup 1)
20676 (const_int 1)))]
915119a5 20677 "TARGET_SSE"
0f40f9f7 20678 "mulss\t{%2, %0|%0, %2}"
3d34cd91
JH
20679 [(set_attr "type" "ssemul")
20680 (set_attr "mode" "SF")])
915119a5
BS
20681
20682(define_insn "divv4sf3"
20683 [(set (match_operand:V4SF 0 "register_operand" "=x")
20684 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20685 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20686 "TARGET_SSE"
0f40f9f7 20687 "divps\t{%2, %0|%0, %2}"
3d34cd91
JH
20688 [(set_attr "type" "ssediv")
20689 (set_attr "mode" "V4SF")])
915119a5
BS
20690
20691(define_insn "vmdivv4sf3"
20692 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218
RH
20693 (vec_merge:V4SF
20694 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20695 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20696 (match_dup 1)
20697 (const_int 1)))]
915119a5 20698 "TARGET_SSE"
0f40f9f7 20699 "divss\t{%2, %0|%0, %2}"
3d34cd91
JH
20700 [(set_attr "type" "ssediv")
20701 (set_attr "mode" "SF")])
915119a5
BS
20702
20703
20704;; SSE square root/reciprocal
20705
20706(define_insn "rcpv4sf2"
20707 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218 20708 (unspec:V4SF
8ee41eaf 20709 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
915119a5 20710 "TARGET_SSE"
0f40f9f7 20711 "rcpps\t{%1, %0|%0, %1}"
3d34cd91
JH
20712 [(set_attr "type" "sse")
20713 (set_attr "mode" "V4SF")])
915119a5
BS
20714
20715(define_insn "vmrcpv4sf2"
20716 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218 20717 (vec_merge:V4SF
8ee41eaf
RH
20718 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20719 UNSPEC_RCP)
e37af218
RH
20720 (match_operand:V4SF 2 "register_operand" "0")
20721 (const_int 1)))]
915119a5 20722 "TARGET_SSE"
0f40f9f7 20723 "rcpss\t{%1, %0|%0, %1}"
3d34cd91
JH
20724 [(set_attr "type" "sse")
20725 (set_attr "mode" "SF")])
915119a5
BS
20726
20727(define_insn "rsqrtv4sf2"
20728 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218 20729 (unspec:V4SF
8ee41eaf 20730 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
915119a5 20731 "TARGET_SSE"
0f40f9f7 20732 "rsqrtps\t{%1, %0|%0, %1}"
3d34cd91
JH
20733 [(set_attr "type" "sse")
20734 (set_attr "mode" "V4SF")])
915119a5
BS
20735
20736(define_insn "vmrsqrtv4sf2"
20737 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218 20738 (vec_merge:V4SF
8ee41eaf
RH
20739 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20740 UNSPEC_RSQRT)
e37af218
RH
20741 (match_operand:V4SF 2 "register_operand" "0")
20742 (const_int 1)))]
915119a5 20743 "TARGET_SSE"
0f40f9f7 20744 "rsqrtss\t{%1, %0|%0, %1}"
3d34cd91
JH
20745 [(set_attr "type" "sse")
20746 (set_attr "mode" "SF")])
915119a5
BS
20747
20748(define_insn "sqrtv4sf2"
20749 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218 20750 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
915119a5 20751 "TARGET_SSE"
0f40f9f7 20752 "sqrtps\t{%1, %0|%0, %1}"
3d34cd91
JH
20753 [(set_attr "type" "sse")
20754 (set_attr "mode" "V4SF")])
915119a5
BS
20755
20756(define_insn "vmsqrtv4sf2"
20757 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218
RH
20758 (vec_merge:V4SF
20759 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20760 (match_operand:V4SF 2 "register_operand" "0")
20761 (const_int 1)))]
915119a5 20762 "TARGET_SSE"
0f40f9f7 20763 "sqrtss\t{%1, %0|%0, %1}"
3d34cd91
JH
20764 [(set_attr "type" "sse")
20765 (set_attr "mode" "SF")])
915119a5 20766
915119a5
BS
20767;; SSE logical operations.
20768
1877be45
JH
20769;; SSE defines logical operations on floating point values. This brings
20770;; interesting challenge to RTL representation where logicals are only valid
20771;; on integral types. We deal with this by representing the floating point
20772;; logical as logical on arguments casted to TImode as this is what hardware
20773;; really does. Unfortunately hardware requires the type information to be
d1f87653 20774;; present and thus we must avoid subregs from being simplified and eliminated
1877be45
JH
20775;; in later compilation phases.
20776;;
20777;; We have following variants from each instruction:
20778;; sse_andsf3 - the operation taking V4SF vector operands
20779;; and doing TImode cast on them
20780;; *sse_andsf3_memory - the operation taking one memory operand casted to
d1f87653 20781;; TImode, since backend insist on eliminating casts
1877be45
JH
20782;; on memory operands
20783;; sse_andti3_sf_1 - the operation taking SF scalar operands.
1e5f1716 20784;; We cannot accept memory operand here as instruction reads
1877be45
JH
20785;; whole scalar. This is generated only post reload by GCC
20786;; scalar float operations that expands to logicals (fabs)
20787;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20788;; memory operand. Eventually combine can be able
d1f87653 20789;; to synthesize these using splitter.
1877be45
JH
20790;; sse2_anddf3, *sse2_anddf3_memory
20791;;
20792;;
915119a5
BS
20793;; These are not called andti3 etc. because we really really don't want
20794;; the compiler to widen DImode ands to TImode ands and then try to move
20795;; into DImode subregs of SSE registers, and them together, and move out
20796;; of DImode subregs again!
1877be45
JH
20797;; SSE1 single precision floating point logical operation
20798(define_expand "sse_andv4sf3"
79ae63b1
JH
20799 [(set (match_operand:V4SF 0 "register_operand" "")
20800 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20801 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
1877be45
JH
20802 "TARGET_SSE"
20803 "")
915119a5 20804
1877be45 20805(define_insn "*sse_andv4sf3"
79ae63b1
JH
20806 [(set (match_operand:V4SF 0 "register_operand" "=x")
20807 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20808 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1877be45
JH
20809 "TARGET_SSE
20810 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20811 "andps\t{%2, %0|%0, %2}"
3d34cd91 20812 [(set_attr "type" "sselog")
1877be45 20813 (set_attr "mode" "V4SF")])
c679d048 20814
1877be45 20815(define_expand "sse_nandv4sf3"
79ae63b1
JH
20816 [(set (match_operand:V4SF 0 "register_operand" "")
20817 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20818 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
c679d048 20819 "TARGET_SSE"
1877be45
JH
20820 "")
20821
20822(define_insn "*sse_nandv4sf3"
79ae63b1
JH
20823 [(set (match_operand:V4SF 0 "register_operand" "=x")
20824 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20825 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
c679d048 20826 "TARGET_SSE"
1877be45 20827 "andnps\t{%2, %0|%0, %2}"
3d34cd91
JH
20828 [(set_attr "type" "sselog")
20829 (set_attr "mode" "V4SF")])
c679d048 20830
1877be45 20831(define_expand "sse_iorv4sf3"
79ae63b1
JH
20832 [(set (match_operand:V4SF 0 "register_operand" "")
20833 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20834 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
1877be45
JH
20835 "TARGET_SSE"
20836 "")
20837
20838(define_insn "*sse_iorv4sf3"
79ae63b1
JH
20839 [(set (match_operand:V4SF 0 "register_operand" "=x")
20840 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20841 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1877be45 20842 "TARGET_SSE
558740bf 20843 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1877be45 20844 "orps\t{%2, %0|%0, %2}"
3d34cd91 20845 [(set_attr "type" "sselog")
1877be45 20846 (set_attr "mode" "V4SF")])
c679d048 20847
1877be45 20848(define_expand "sse_xorv4sf3"
79ae63b1
JH
20849 [(set (match_operand:V4SF 0 "register_operand" "")
20850 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20851 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20852 "TARGET_SSE"
1877be45 20853 "")
c679d048 20854
1877be45 20855(define_insn "*sse_xorv4sf3"
79ae63b1
JH
20856 [(set (match_operand:V4SF 0 "register_operand" "=x")
20857 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20858 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1877be45
JH
20859 "TARGET_SSE
20860 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20861 "xorps\t{%2, %0|%0, %2}"
3d34cd91
JH
20862 [(set_attr "type" "sselog")
20863 (set_attr "mode" "V4SF")])
915119a5 20864
1877be45
JH
20865;; SSE2 double precision floating point logical operation
20866
20867(define_expand "sse2_andv2df3"
79ae63b1
JH
20868 [(set (match_operand:V2DF 0 "register_operand" "")
20869 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20870 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
c679d048 20871 "TARGET_SSE2"
1877be45
JH
20872 "")
20873
20874(define_insn "*sse2_andv2df3"
79ae63b1
JH
20875 [(set (match_operand:V2DF 0 "register_operand" "=x")
20876 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20877 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
916b60b7
BS
20878 "TARGET_SSE2
20879 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1877be45 20880 "andpd\t{%2, %0|%0, %2}"
5f90a099 20881 [(set_attr "type" "sselog")
1877be45 20882 (set_attr "mode" "V2DF")])
916b60b7 20883
1877be45 20884(define_expand "sse2_nandv2df3"
79ae63b1
JH
20885 [(set (match_operand:V2DF 0 "register_operand" "")
20886 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20887 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
c679d048 20888 "TARGET_SSE2"
1877be45
JH
20889 "")
20890
20891(define_insn "*sse2_nandv2df3"
79ae63b1
JH
20892 [(set (match_operand:V2DF 0 "register_operand" "=x")
20893 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20894 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
c679d048 20895 "TARGET_SSE2"
1877be45
JH
20896 "andnpd\t{%2, %0|%0, %2}"
20897 [(set_attr "type" "sselog")
20898 (set_attr "mode" "V2DF")])
20899
20900(define_expand "sse2_iorv2df3"
79ae63b1
JH
20901 [(set (match_operand:V2DF 0 "register_operand" "")
20902 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20903 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1877be45
JH
20904 "TARGET_SSE2"
20905 "")
20906
20907(define_insn "*sse2_iorv2df3"
79ae63b1
JH
20908 [(set (match_operand:V2DF 0 "register_operand" "=x")
20909 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20910 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1877be45
JH
20911 "TARGET_SSE2
20912 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20913 "orpd\t{%2, %0|%0, %2}"
3d34cd91 20914 [(set_attr "type" "sselog")
1877be45 20915 (set_attr "mode" "V2DF")])
c679d048 20916
1877be45 20917(define_expand "sse2_xorv2df3"
79ae63b1
JH
20918 [(set (match_operand:V2DF 0 "register_operand" "")
20919 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20920 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1877be45
JH
20921 "TARGET_SSE2"
20922 "")
20923
20924(define_insn "*sse2_xorv2df3"
79ae63b1
JH
20925 [(set (match_operand:V2DF 0 "register_operand" "=x")
20926 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20927 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1877be45 20928 "TARGET_SSE2
558740bf 20929 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1877be45 20930 "xorpd\t{%2, %0|%0, %2}"
3d34cd91 20931 [(set_attr "type" "sselog")
1877be45 20932 (set_attr "mode" "V2DF")])
c679d048 20933
1877be45
JH
20934;; SSE2 integral logicals. These patterns must always come after floating
20935;; point ones since we don't want compiler to use integer opcodes on floating
20936;; point SSE values to avoid matching of subregs in the match_operand.
20937(define_insn "*sse2_andti3"
c679d048 20938 [(set (match_operand:TI 0 "register_operand" "=x")
1877be45 20939 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
c679d048 20940 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
558740bf
JH
20941 "TARGET_SSE2
20942 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1877be45 20943 "pand\t{%2, %0|%0, %2}"
3d34cd91
JH
20944 [(set_attr "type" "sselog")
20945 (set_attr "mode" "TI")])
c679d048 20946
1877be45 20947(define_insn "sse2_andv2di3"
916b60b7 20948 [(set (match_operand:V2DI 0 "register_operand" "=x")
1877be45 20949 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
916b60b7
BS
20950 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20951 "TARGET_SSE2
20952 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1877be45 20953 "pand\t{%2, %0|%0, %2}"
5f90a099
JH
20954 [(set_attr "type" "sselog")
20955 (set_attr "mode" "TI")])
916b60b7 20956
1877be45
JH
20957(define_insn "*sse2_nandti3"
20958 [(set (match_operand:TI 0 "register_operand" "=x")
20959 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20960 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
c679d048 20961 "TARGET_SSE2"
1877be45 20962 "pandn\t{%2, %0|%0, %2}"
3d34cd91 20963 [(set_attr "type" "sselog")
1877be45 20964 (set_attr "mode" "TI")])
c679d048 20965
1877be45
JH
20966(define_insn "sse2_nandv2di3"
20967 [(set (match_operand:V2DI 0 "register_operand" "=x")
10e9fecc 20968 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
1877be45
JH
20969 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20970 "TARGET_SSE2
20971 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20972 "pandn\t{%2, %0|%0, %2}"
3d34cd91 20973 [(set_attr "type" "sselog")
1877be45 20974 (set_attr "mode" "TI")])
c679d048 20975
1877be45
JH
20976(define_insn "*sse2_iorti3"
20977 [(set (match_operand:TI 0 "register_operand" "=x")
20978 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
915119a5 20979 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
1877be45
JH
20980 "TARGET_SSE2
20981 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20982 "por\t{%2, %0|%0, %2}"
3d34cd91 20983 [(set_attr "type" "sselog")
1877be45 20984 (set_attr "mode" "TI")])
915119a5 20985
1877be45
JH
20986(define_insn "sse2_iorv2di3"
20987 [(set (match_operand:V2DI 0 "register_operand" "=x")
20988 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20989 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20990 "TARGET_SSE2
558740bf 20991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1877be45 20992 "por\t{%2, %0|%0, %2}"
3d34cd91 20993 [(set_attr "type" "sselog")
1877be45 20994 (set_attr "mode" "TI")])
915119a5 20995
1877be45 20996(define_insn "*sse2_xorti3"
c679d048 20997 [(set (match_operand:TI 0 "register_operand" "=x")
558740bf 20998 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
c679d048 20999 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
558740bf
JH
21000 "TARGET_SSE2
21001 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 21002 "pxor\t{%2, %0|%0, %2}"
3d34cd91
JH
21003 [(set_attr "type" "sselog")
21004 (set_attr "mode" "TI")])
c679d048 21005
916b60b7
BS
21006(define_insn "sse2_xorv2di3"
21007 [(set (match_operand:V2DI 0 "register_operand" "=x")
21008 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21009 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21010 "TARGET_SSE2
21011 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21012 "pxor\t{%2, %0|%0, %2}"
5f90a099
JH
21013 [(set_attr "type" "sselog")
21014 (set_attr "mode" "TI")])
916b60b7 21015
915119a5
BS
21016;; Use xor, but don't show input operands so they aren't live before
21017;; this insn.
e37af218
RH
21018(define_insn "sse_clrv4sf"
21019 [(set (match_operand:V4SF 0 "register_operand" "=x")
4977bab6 21020 (match_operand:V4SF 1 "const0_operand" "X"))]
915119a5 21021 "TARGET_SSE"
4977bab6
ZW
21022{
21023 if (get_attr_mode (insn) == MODE_TI)
21024 return "pxor\t{%0, %0|%0, %0}";
21025 else
21026 return "xorps\t{%0, %0|%0, %0}";
21027}
3d34cd91 21028 [(set_attr "type" "sselog")
19cba4a0 21029 (set_attr "memory" "none")
4977bab6
ZW
21030 (set (attr "mode")
21031 (if_then_else
21032 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21033 (const_int 0))
21034 (ne (symbol_ref "TARGET_SSE2")
21035 (const_int 0)))
21036 (eq (symbol_ref "optimize_size")
21037 (const_int 0)))
21038 (const_string "TI")
21039 (const_string "V4SF")))])
915119a5 21040
48126a97
JH
21041;; Use xor, but don't show input operands so they aren't live before
21042;; this insn.
21043(define_insn "sse_clrv2df"
21044 [(set (match_operand:V2DF 0 "register_operand" "=x")
21045 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21046 "TARGET_SSE2"
21047 "xorpd\t{%0, %0|%0, %0}"
21048 [(set_attr "type" "sselog")
21049 (set_attr "memory" "none")
21050 (set_attr "mode" "V4SF")])
21051
915119a5
BS
21052;; SSE mask-generating compares
21053
21054(define_insn "maskcmpv4sf3"
21055 [(set (match_operand:V4SI 0 "register_operand" "=x")
21056 (match_operator:V4SI 3 "sse_comparison_operator"
e37af218
RH
21057 [(match_operand:V4SF 1 "register_operand" "0")
21058 (match_operand:V4SF 2 "register_operand" "x")]))]
915119a5 21059 "TARGET_SSE"
0f40f9f7 21060 "cmp%D3ps\t{%2, %0|%0, %2}"
3d34cd91
JH
21061 [(set_attr "type" "ssecmp")
21062 (set_attr "mode" "V4SF")])
915119a5
BS
21063
21064(define_insn "maskncmpv4sf3"
21065 [(set (match_operand:V4SI 0 "register_operand" "=x")
21066 (not:V4SI
21067 (match_operator:V4SI 3 "sse_comparison_operator"
e37af218
RH
21068 [(match_operand:V4SF 1 "register_operand" "0")
21069 (match_operand:V4SF 2 "register_operand" "x")])))]
915119a5 21070 "TARGET_SSE"
29628f27
BS
21071{
21072 if (GET_CODE (operands[3]) == UNORDERED)
e37af218
RH
21073 return "cmpordps\t{%2, %0|%0, %2}";
21074 else
21075 return "cmpn%D3ps\t{%2, %0|%0, %2}";
21076}
3d34cd91
JH
21077 [(set_attr "type" "ssecmp")
21078 (set_attr "mode" "V4SF")])
915119a5
BS
21079
21080(define_insn "vmmaskcmpv4sf3"
21081 [(set (match_operand:V4SI 0 "register_operand" "=x")
21082 (vec_merge:V4SI
21083 (match_operator:V4SI 3 "sse_comparison_operator"
e37af218
RH
21084 [(match_operand:V4SF 1 "register_operand" "0")
21085 (match_operand:V4SF 2 "register_operand" "x")])
d9deed68 21086 (subreg:V4SI (match_dup 1) 0)
915119a5
BS
21087 (const_int 1)))]
21088 "TARGET_SSE"
0f40f9f7 21089 "cmp%D3ss\t{%2, %0|%0, %2}"
3d34cd91
JH
21090 [(set_attr "type" "ssecmp")
21091 (set_attr "mode" "SF")])
915119a5
BS
21092
21093(define_insn "vmmaskncmpv4sf3"
21094 [(set (match_operand:V4SI 0 "register_operand" "=x")
21095 (vec_merge:V4SI
21096 (not:V4SI
21097 (match_operator:V4SI 3 "sse_comparison_operator"
e37af218
RH
21098 [(match_operand:V4SF 1 "register_operand" "0")
21099 (match_operand:V4SF 2 "register_operand" "x")]))
915119a5
BS
21100 (subreg:V4SI (match_dup 1) 0)
21101 (const_int 1)))]
21102 "TARGET_SSE"
29628f27
BS
21103{
21104 if (GET_CODE (operands[3]) == UNORDERED)
e37af218
RH
21105 return "cmpordss\t{%2, %0|%0, %2}";
21106 else
21107 return "cmpn%D3ss\t{%2, %0|%0, %2}";
21108}
3d34cd91
JH
21109 [(set_attr "type" "ssecmp")
21110 (set_attr "mode" "SF")])
915119a5
BS
21111
21112(define_insn "sse_comi"
8bc527af 21113 [(set (reg:CCFP FLAGS_REG)
1194ca05
JH
21114 (compare:CCFP (vec_select:SF
21115 (match_operand:V4SF 0 "register_operand" "x")
21116 (parallel [(const_int 0)]))
21117 (vec_select:SF
21118 (match_operand:V4SF 1 "register_operand" "x")
21119 (parallel [(const_int 0)]))))]
915119a5 21120 "TARGET_SSE"
21e1b5f1 21121 "comiss\t{%1, %0|%0, %1}"
26771da7 21122 [(set_attr "type" "ssecomi")
3d34cd91 21123 (set_attr "mode" "SF")])
915119a5
BS
21124
21125(define_insn "sse_ucomi"
8bc527af 21126 [(set (reg:CCFPU FLAGS_REG)
1194ca05
JH
21127 (compare:CCFPU (vec_select:SF
21128 (match_operand:V4SF 0 "register_operand" "x")
21129 (parallel [(const_int 0)]))
21130 (vec_select:SF
21131 (match_operand:V4SF 1 "register_operand" "x")
21132 (parallel [(const_int 0)]))))]
915119a5 21133 "TARGET_SSE"
21e1b5f1 21134 "ucomiss\t{%1, %0|%0, %1}"
26771da7 21135 [(set_attr "type" "ssecomi")
3d34cd91 21136 (set_attr "mode" "SF")])
915119a5
BS
21137
21138
21139;; SSE unpack
21140
21141(define_insn "sse_unpckhps"
21142 [(set (match_operand:V4SF 0 "register_operand" "=x")
21143 (vec_merge:V4SF
21144 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21145 (parallel [(const_int 2)
21146 (const_int 0)
21147 (const_int 3)
21148 (const_int 1)]))
21e1b5f1 21149 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
915119a5
BS
21150 (parallel [(const_int 0)
21151 (const_int 2)
21152 (const_int 1)
21153 (const_int 3)]))
21154 (const_int 5)))]
21155 "TARGET_SSE"
0f40f9f7 21156 "unpckhps\t{%2, %0|%0, %2}"
3d34cd91
JH
21157 [(set_attr "type" "ssecvt")
21158 (set_attr "mode" "V4SF")])
915119a5
BS
21159
21160(define_insn "sse_unpcklps"
21161 [(set (match_operand:V4SF 0 "register_operand" "=x")
21162 (vec_merge:V4SF
21163 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21164 (parallel [(const_int 0)
21165 (const_int 2)
21166 (const_int 1)
21167 (const_int 3)]))
21e1b5f1 21168 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
915119a5
BS
21169 (parallel [(const_int 2)
21170 (const_int 0)
21171 (const_int 3)
21172 (const_int 1)]))
21173 (const_int 5)))]
21174 "TARGET_SSE"
0f40f9f7 21175 "unpcklps\t{%2, %0|%0, %2}"
3d34cd91
JH
21176 [(set_attr "type" "ssecvt")
21177 (set_attr "mode" "V4SF")])
915119a5
BS
21178
21179
21180;; SSE min/max
21181
21182(define_insn "smaxv4sf3"
21183 [(set (match_operand:V4SF 0 "register_operand" "=x")
21184 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21185 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21186 "TARGET_SSE"
0f40f9f7 21187 "maxps\t{%2, %0|%0, %2}"
3d34cd91
JH
21188 [(set_attr "type" "sse")
21189 (set_attr "mode" "V4SF")])
915119a5
BS
21190
21191(define_insn "vmsmaxv4sf3"
21192 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218
RH
21193 (vec_merge:V4SF
21194 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21195 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21196 (match_dup 1)
21197 (const_int 1)))]
915119a5 21198 "TARGET_SSE"
0f40f9f7 21199 "maxss\t{%2, %0|%0, %2}"
3d34cd91
JH
21200 [(set_attr "type" "sse")
21201 (set_attr "mode" "SF")])
915119a5
BS
21202
21203(define_insn "sminv4sf3"
21204 [(set (match_operand:V4SF 0 "register_operand" "=x")
21205 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21206 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21207 "TARGET_SSE"
0f40f9f7 21208 "minps\t{%2, %0|%0, %2}"
3d34cd91
JH
21209 [(set_attr "type" "sse")
21210 (set_attr "mode" "V4SF")])
915119a5
BS
21211
21212(define_insn "vmsminv4sf3"
21213 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218
RH
21214 (vec_merge:V4SF
21215 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21216 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21217 (match_dup 1)
21218 (const_int 1)))]
915119a5 21219 "TARGET_SSE"
0f40f9f7 21220 "minss\t{%2, %0|%0, %2}"
3d34cd91
JH
21221 [(set_attr "type" "sse")
21222 (set_attr "mode" "SF")])
915119a5 21223
915119a5
BS
21224;; SSE <-> integer/MMX conversions
21225
21226(define_insn "cvtpi2ps"
21227 [(set (match_operand:V4SF 0 "register_operand" "=x")
e37af218
RH
21228 (vec_merge:V4SF
21229 (match_operand:V4SF 1 "register_operand" "0")
21230 (vec_duplicate:V4SF
21231 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21232 (const_int 12)))]
915119a5 21233 "TARGET_SSE"
0f40f9f7 21234 "cvtpi2ps\t{%2, %0|%0, %2}"
3d34cd91
JH
21235 [(set_attr "type" "ssecvt")
21236 (set_attr "mode" "V4SF")])
915119a5
BS
21237
21238(define_insn "cvtps2pi"
21239 [(set (match_operand:V2SI 0 "register_operand" "=y")
e37af218
RH
21240 (vec_select:V2SI
21241 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21242 (parallel [(const_int 0) (const_int 1)])))]
915119a5 21243 "TARGET_SSE"
0f40f9f7 21244 "cvtps2pi\t{%1, %0|%0, %1}"
3d34cd91
JH
21245 [(set_attr "type" "ssecvt")
21246 (set_attr "mode" "V4SF")])
915119a5
BS
21247
21248(define_insn "cvttps2pi"
21249 [(set (match_operand:V2SI 0 "register_operand" "=y")
e37af218 21250 (vec_select:V2SI
8ee41eaf
RH
21251 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21252 UNSPEC_FIX)
e37af218 21253 (parallel [(const_int 0) (const_int 1)])))]
915119a5 21254 "TARGET_SSE"
0f40f9f7 21255 "cvttps2pi\t{%1, %0|%0, %1}"
3d34cd91
JH
21256 [(set_attr "type" "ssecvt")
21257 (set_attr "mode" "SF")])
915119a5
BS
21258
21259(define_insn "cvtsi2ss"
f56e86bd 21260 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
e37af218 21261 (vec_merge:V4SF
f56e86bd 21262 (match_operand:V4SF 1 "register_operand" "0,0")
e37af218 21263 (vec_duplicate:V4SF
f56e86bd 21264 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
e37af218 21265 (const_int 14)))]
915119a5 21266 "TARGET_SSE"
0f40f9f7 21267 "cvtsi2ss\t{%2, %0|%0, %2}"
f56e86bd
JH
21268 [(set_attr "type" "sseicvt")
21269 (set_attr "athlon_decode" "vector,double")
3d34cd91 21270 (set_attr "mode" "SF")])
915119a5 21271
4977bab6 21272(define_insn "cvtsi2ssq"
f56e86bd 21273 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
4977bab6 21274 (vec_merge:V4SF
f56e86bd 21275 (match_operand:V4SF 1 "register_operand" "0,0")
4977bab6 21276 (vec_duplicate:V4SF
f56e86bd 21277 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
4977bab6
ZW
21278 (const_int 14)))]
21279 "TARGET_SSE && TARGET_64BIT"
21280 "cvtsi2ssq\t{%2, %0|%0, %2}"
f56e86bd
JH
21281 [(set_attr "type" "sseicvt")
21282 (set_attr "athlon_decode" "vector,double")
4977bab6
ZW
21283 (set_attr "mode" "SF")])
21284
915119a5 21285(define_insn "cvtss2si"
f56e86bd 21286 [(set (match_operand:SI 0 "register_operand" "=r,r")
e37af218 21287 (vec_select:SI
f56e86bd 21288 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
e37af218 21289 (parallel [(const_int 0)])))]
915119a5 21290 "TARGET_SSE"
0f40f9f7 21291 "cvtss2si\t{%1, %0|%0, %1}"
f56e86bd
JH
21292 [(set_attr "type" "sseicvt")
21293 (set_attr "athlon_decode" "double,vector")
26f74aa3 21294 (set_attr "mode" "SI")])
915119a5 21295
453ee231
JH
21296(define_insn "cvtss2siq"
21297 [(set (match_operand:DI 0 "register_operand" "=r,r")
21298 (vec_select:DI
21299 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21300 (parallel [(const_int 0)])))]
21301 "TARGET_SSE"
21302 "cvtss2siq\t{%1, %0|%0, %1}"
21303 [(set_attr "type" "sseicvt")
21304 (set_attr "athlon_decode" "double,vector")
26f74aa3 21305 (set_attr "mode" "DI")])
453ee231 21306
915119a5 21307(define_insn "cvttss2si"
f56e86bd 21308 [(set (match_operand:SI 0 "register_operand" "=r,r")
e37af218 21309 (vec_select:SI
f56e86bd 21310 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
8ee41eaf 21311 UNSPEC_FIX)
e37af218 21312 (parallel [(const_int 0)])))]
915119a5 21313 "TARGET_SSE"
0f40f9f7 21314 "cvttss2si\t{%1, %0|%0, %1}"
f56e86bd
JH
21315 [(set_attr "type" "sseicvt")
21316 (set_attr "mode" "SF")
21317 (set_attr "athlon_decode" "double,vector")])
915119a5 21318
453ee231
JH
21319(define_insn "cvttss2siq"
21320 [(set (match_operand:DI 0 "register_operand" "=r,r")
21321 (vec_select:DI
21322 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21323 UNSPEC_FIX)
21324 (parallel [(const_int 0)])))]
21325 "TARGET_SSE && TARGET_64BIT"
21326 "cvttss2siq\t{%1, %0|%0, %1}"
21327 [(set_attr "type" "sseicvt")
21328 (set_attr "mode" "SF")
21329 (set_attr "athlon_decode" "double,vector")])
21330
915119a5
BS
21331
21332;; MMX insns
21333
21334;; MMX arithmetic
21335
21336(define_insn "addv8qi3"
21337 [(set (match_operand:V8QI 0 "register_operand" "=y")
d50672ef 21338 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
915119a5
BS
21339 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21340 "TARGET_MMX"
0f40f9f7 21341 "paddb\t{%2, %0|%0, %2}"
3d34cd91
JH
21342 [(set_attr "type" "mmxadd")
21343 (set_attr "mode" "DI")])
915119a5
BS
21344
21345(define_insn "addv4hi3"
21346 [(set (match_operand:V4HI 0 "register_operand" "=y")
d50672ef 21347 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
915119a5
BS
21348 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21349 "TARGET_MMX"
0f40f9f7 21350 "paddw\t{%2, %0|%0, %2}"
3d34cd91
JH
21351 [(set_attr "type" "mmxadd")
21352 (set_attr "mode" "DI")])
915119a5
BS
21353
21354(define_insn "addv2si3"
21355 [(set (match_operand:V2SI 0 "register_operand" "=y")
d50672ef 21356 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
915119a5
BS
21357 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21358 "TARGET_MMX"
0f40f9f7 21359 "paddd\t{%2, %0|%0, %2}"
3d34cd91
JH
21360 [(set_attr "type" "mmxadd")
21361 (set_attr "mode" "DI")])
915119a5 21362
d50672ef
JH
21363(define_insn "mmx_adddi3"
21364 [(set (match_operand:DI 0 "register_operand" "=y")
21365 (unspec:DI
21366 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21367 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21368 UNSPEC_NOP))]
21369 "TARGET_MMX"
21370 "paddq\t{%2, %0|%0, %2}"
21371 [(set_attr "type" "mmxadd")
21372 (set_attr "mode" "DI")])
21373
915119a5
BS
21374(define_insn "ssaddv8qi3"
21375 [(set (match_operand:V8QI 0 "register_operand" "=y")
d50672ef 21376 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
915119a5
BS
21377 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21378 "TARGET_MMX"
0f40f9f7 21379 "paddsb\t{%2, %0|%0, %2}"
3d34cd91
JH
21380 [(set_attr "type" "mmxadd")
21381 (set_attr "mode" "DI")])
915119a5
BS
21382
21383(define_insn "ssaddv4hi3"
21384 [(set (match_operand:V4HI 0 "register_operand" "=y")
d50672ef 21385 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
915119a5
BS
21386 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21387 "TARGET_MMX"
0f40f9f7 21388 "paddsw\t{%2, %0|%0, %2}"
3d34cd91
JH
21389 [(set_attr "type" "mmxadd")
21390 (set_attr "mode" "DI")])
915119a5
BS
21391
21392(define_insn "usaddv8qi3"
21393 [(set (match_operand:V8QI 0 "register_operand" "=y")
d50672ef 21394 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
915119a5
BS
21395 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21396 "TARGET_MMX"
0f40f9f7 21397 "paddusb\t{%2, %0|%0, %2}"
3d34cd91
JH
21398 [(set_attr "type" "mmxadd")
21399 (set_attr "mode" "DI")])
915119a5
BS
21400
21401(define_insn "usaddv4hi3"
21402 [(set (match_operand:V4HI 0 "register_operand" "=y")
d50672ef 21403 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
915119a5
BS
21404 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21405 "TARGET_MMX"
0f40f9f7 21406 "paddusw\t{%2, %0|%0, %2}"
3d34cd91
JH
21407 [(set_attr "type" "mmxadd")
21408 (set_attr "mode" "DI")])
915119a5
BS
21409
21410(define_insn "subv8qi3"
21411 [(set (match_operand:V8QI 0 "register_operand" "=y")
21412 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21413 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21414 "TARGET_MMX"
0f40f9f7 21415 "psubb\t{%2, %0|%0, %2}"
3d34cd91
JH
21416 [(set_attr "type" "mmxadd")
21417 (set_attr "mode" "DI")])
915119a5
BS
21418
21419(define_insn "subv4hi3"
21420 [(set (match_operand:V4HI 0 "register_operand" "=y")
21421 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21422 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21423 "TARGET_MMX"
0f40f9f7 21424 "psubw\t{%2, %0|%0, %2}"
3d34cd91
JH
21425 [(set_attr "type" "mmxadd")
21426 (set_attr "mode" "DI")])
915119a5
BS
21427
21428(define_insn "subv2si3"
21429 [(set (match_operand:V2SI 0 "register_operand" "=y")
21430 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21431 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21432 "TARGET_MMX"
0f40f9f7 21433 "psubd\t{%2, %0|%0, %2}"
3d34cd91
JH
21434 [(set_attr "type" "mmxadd")
21435 (set_attr "mode" "DI")])
915119a5 21436
d50672ef
JH
21437(define_insn "mmx_subdi3"
21438 [(set (match_operand:DI 0 "register_operand" "=y")
21439 (unspec:DI
21440 [(minus:DI (match_operand:DI 1 "register_operand" "0")
21441 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21442 UNSPEC_NOP))]
21443 "TARGET_MMX"
21444 "psubq\t{%2, %0|%0, %2}"
21445 [(set_attr "type" "mmxadd")
21446 (set_attr "mode" "DI")])
21447
915119a5
BS
21448(define_insn "sssubv8qi3"
21449 [(set (match_operand:V8QI 0 "register_operand" "=y")
21450 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21451 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21452 "TARGET_MMX"
0f40f9f7 21453 "psubsb\t{%2, %0|%0, %2}"
3d34cd91
JH
21454 [(set_attr "type" "mmxadd")
21455 (set_attr "mode" "DI")])
915119a5
BS
21456
21457(define_insn "sssubv4hi3"
21458 [(set (match_operand:V4HI 0 "register_operand" "=y")
21459 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21460 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21461 "TARGET_MMX"
0f40f9f7 21462 "psubsw\t{%2, %0|%0, %2}"
3d34cd91
JH
21463 [(set_attr "type" "mmxadd")
21464 (set_attr "mode" "DI")])
915119a5
BS
21465
21466(define_insn "ussubv8qi3"
21467 [(set (match_operand:V8QI 0 "register_operand" "=y")
21468 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21469 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21470 "TARGET_MMX"
0f40f9f7 21471 "psubusb\t{%2, %0|%0, %2}"
3d34cd91
JH
21472 [(set_attr "type" "mmxadd")
21473 (set_attr "mode" "DI")])
915119a5
BS
21474
21475(define_insn "ussubv4hi3"
21476 [(set (match_operand:V4HI 0 "register_operand" "=y")
21477 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21478 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21479 "TARGET_MMX"
0f40f9f7 21480 "psubusw\t{%2, %0|%0, %2}"
3d34cd91
JH
21481 [(set_attr "type" "mmxadd")
21482 (set_attr "mode" "DI")])
915119a5
BS
21483
21484(define_insn "mulv4hi3"
21485 [(set (match_operand:V4HI 0 "register_operand" "=y")
21486 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21487 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21488 "TARGET_MMX"
0f40f9f7 21489 "pmullw\t{%2, %0|%0, %2}"
3d34cd91
JH
21490 [(set_attr "type" "mmxmul")
21491 (set_attr "mode" "DI")])
915119a5
BS
21492
21493(define_insn "smulv4hi3_highpart"
21494 [(set (match_operand:V4HI 0 "register_operand" "=y")
21495 (truncate:V4HI
21496 (lshiftrt:V4SI
e37af218
RH
21497 (mult:V4SI (sign_extend:V4SI
21498 (match_operand:V4HI 1 "register_operand" "0"))
21499 (sign_extend:V4SI
21500 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
915119a5
BS
21501 (const_int 16))))]
21502 "TARGET_MMX"
0f40f9f7 21503 "pmulhw\t{%2, %0|%0, %2}"
3d34cd91
JH
21504 [(set_attr "type" "mmxmul")
21505 (set_attr "mode" "DI")])
915119a5
BS
21506
21507(define_insn "umulv4hi3_highpart"
21508 [(set (match_operand:V4HI 0 "register_operand" "=y")
21509 (truncate:V4HI
21510 (lshiftrt:V4SI
e37af218
RH
21511 (mult:V4SI (zero_extend:V4SI
21512 (match_operand:V4HI 1 "register_operand" "0"))
21513 (zero_extend:V4SI
21514 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
915119a5 21515 (const_int 16))))]
47f339cf 21516 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 21517 "pmulhuw\t{%2, %0|%0, %2}"
3d34cd91
JH
21518 [(set_attr "type" "mmxmul")
21519 (set_attr "mode" "DI")])
915119a5
BS
21520
21521(define_insn "mmx_pmaddwd"
21522 [(set (match_operand:V2SI 0 "register_operand" "=y")
21523 (plus:V2SI
21524 (mult:V2SI
e37af218
RH
21525 (sign_extend:V2SI
21526 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21527 (parallel [(const_int 0) (const_int 2)])))
21528 (sign_extend:V2SI
21529 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21530 (parallel [(const_int 0) (const_int 2)]))))
915119a5
BS
21531 (mult:V2SI
21532 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21533 (parallel [(const_int 1)
21534 (const_int 3)])))
21535 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21536 (parallel [(const_int 1)
21537 (const_int 3)]))))))]
21538 "TARGET_MMX"
0f40f9f7 21539 "pmaddwd\t{%2, %0|%0, %2}"
3d34cd91
JH
21540 [(set_attr "type" "mmxmul")
21541 (set_attr "mode" "DI")])
915119a5
BS
21542
21543
21544;; MMX logical operations
21545;; Note we don't want to declare these as regular iordi3 insns to prevent
21546;; normal code that also wants to use the FPU from getting broken.
21547;; The UNSPECs are there to prevent the combiner from getting overly clever.
21548(define_insn "mmx_iordi3"
21549 [(set (match_operand:DI 0 "register_operand" "=y")
21550 (unspec:DI
d50672ef 21551 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
8ee41eaf
RH
21552 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21553 UNSPEC_NOP))]
915119a5 21554 "TARGET_MMX"
0f40f9f7 21555 "por\t{%2, %0|%0, %2}"
3d34cd91
JH
21556 [(set_attr "type" "mmxadd")
21557 (set_attr "mode" "DI")])
915119a5
BS
21558
21559(define_insn "mmx_xordi3"
21560 [(set (match_operand:DI 0 "register_operand" "=y")
21561 (unspec:DI
d50672ef 21562 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
8ee41eaf
RH
21563 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21564 UNSPEC_NOP))]
915119a5 21565 "TARGET_MMX"
0f40f9f7 21566 "pxor\t{%2, %0|%0, %2}"
3d34cd91
JH
21567 [(set_attr "type" "mmxadd")
21568 (set_attr "mode" "DI")
29628f27 21569 (set_attr "memory" "none")])
915119a5
BS
21570
21571;; Same as pxor, but don't show input operands so that we don't think
21572;; they are live.
21573(define_insn "mmx_clrdi"
21574 [(set (match_operand:DI 0 "register_operand" "=y")
8ee41eaf 21575 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
915119a5 21576 "TARGET_MMX"
0f40f9f7 21577 "pxor\t{%0, %0|%0, %0}"
3d34cd91
JH
21578 [(set_attr "type" "mmxadd")
21579 (set_attr "mode" "DI")
6f1a6c5b 21580 (set_attr "memory" "none")])
915119a5
BS
21581
21582(define_insn "mmx_anddi3"
21583 [(set (match_operand:DI 0 "register_operand" "=y")
21584 (unspec:DI
d50672ef 21585 [(and:DI (match_operand:DI 1 "register_operand" "%0")
8ee41eaf
RH
21586 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21587 UNSPEC_NOP))]
915119a5 21588 "TARGET_MMX"
0f40f9f7 21589 "pand\t{%2, %0|%0, %2}"
3d34cd91
JH
21590 [(set_attr "type" "mmxadd")
21591 (set_attr "mode" "DI")])
915119a5
BS
21592
21593(define_insn "mmx_nanddi3"
21594 [(set (match_operand:DI 0 "register_operand" "=y")
21595 (unspec:DI
21596 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
8ee41eaf
RH
21597 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21598 UNSPEC_NOP))]
915119a5 21599 "TARGET_MMX"
0f40f9f7 21600 "pandn\t{%2, %0|%0, %2}"
3d34cd91
JH
21601 [(set_attr "type" "mmxadd")
21602 (set_attr "mode" "DI")])
915119a5
BS
21603
21604
21605;; MMX unsigned averages/sum of absolute differences
21606
21607(define_insn "mmx_uavgv8qi3"
21608 [(set (match_operand:V8QI 0 "register_operand" "=y")
21609 (ashiftrt:V8QI
21610 (plus:V8QI (plus:V8QI
21611 (match_operand:V8QI 1 "register_operand" "0")
21612 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
69ef87e2
AH
21613 (const_vector:V8QI [(const_int 1)
21614 (const_int 1)
21615 (const_int 1)
21616 (const_int 1)
21617 (const_int 1)
21618 (const_int 1)
21619 (const_int 1)
21620 (const_int 1)]))
915119a5 21621 (const_int 1)))]
47f339cf 21622 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 21623 "pavgb\t{%2, %0|%0, %2}"
3d34cd91
JH
21624 [(set_attr "type" "mmxshft")
21625 (set_attr "mode" "DI")])
915119a5
BS
21626
21627(define_insn "mmx_uavgv4hi3"
21628 [(set (match_operand:V4HI 0 "register_operand" "=y")
21629 (ashiftrt:V4HI
21630 (plus:V4HI (plus:V4HI
21631 (match_operand:V4HI 1 "register_operand" "0")
21632 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
69ef87e2
AH
21633 (const_vector:V4HI [(const_int 1)
21634 (const_int 1)
21635 (const_int 1)
21636 (const_int 1)]))
915119a5 21637 (const_int 1)))]
47f339cf 21638 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 21639 "pavgw\t{%2, %0|%0, %2}"
3d34cd91
JH
21640 [(set_attr "type" "mmxshft")
21641 (set_attr "mode" "DI")])
915119a5
BS
21642
21643(define_insn "mmx_psadbw"
916b60b7
BS
21644 [(set (match_operand:DI 0 "register_operand" "=y")
21645 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
8ee41eaf
RH
21646 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21647 UNSPEC_PSADBW))]
47f339cf 21648 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 21649 "psadbw\t{%2, %0|%0, %2}"
3d34cd91
JH
21650 [(set_attr "type" "mmxshft")
21651 (set_attr "mode" "DI")])
915119a5
BS
21652
21653
21654;; MMX insert/extract/shuffle
21655
21656(define_insn "mmx_pinsrw"
21657 [(set (match_operand:V4HI 0 "register_operand" "=y")
21658 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21659 (vec_duplicate:V4HI
21660 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
ebe75517 21661 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
47f339cf 21662 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 21663 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
3d34cd91
JH
21664 [(set_attr "type" "mmxcvt")
21665 (set_attr "mode" "DI")])
915119a5
BS
21666
21667(define_insn "mmx_pextrw"
21668 [(set (match_operand:SI 0 "register_operand" "=r")
21669 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21670 (parallel
ebe75517 21671 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
47f339cf 21672 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 21673 "pextrw\t{%2, %1, %0|%0, %1, %2}"
3d34cd91
JH
21674 [(set_attr "type" "mmxcvt")
21675 (set_attr "mode" "DI")])
915119a5
BS
21676
21677(define_insn "mmx_pshufw"
21678 [(set (match_operand:V4HI 0 "register_operand" "=y")
717415ad 21679 (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
8ee41eaf
RH
21680 (match_operand:SI 2 "immediate_operand" "i")]
21681 UNSPEC_SHUFFLE))]
47f339cf 21682 "TARGET_SSE || TARGET_3DNOW_A"
29628f27 21683 "pshufw\t{%2, %1, %0|%0, %1, %2}"
3d34cd91
JH
21684 [(set_attr "type" "mmxcvt")
21685 (set_attr "mode" "DI")])
915119a5
BS
21686
21687
21688;; MMX mask-generating comparisons
21689
21690(define_insn "eqv8qi3"
21691 [(set (match_operand:V8QI 0 "register_operand" "=y")
21692 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21693 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21694 "TARGET_MMX"
0f40f9f7 21695 "pcmpeqb\t{%2, %0|%0, %2}"
3d34cd91
JH
21696 [(set_attr "type" "mmxcmp")
21697 (set_attr "mode" "DI")])
915119a5
BS
21698
21699(define_insn "eqv4hi3"
21700 [(set (match_operand:V4HI 0 "register_operand" "=y")
21701 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21702 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21703 "TARGET_MMX"
0f40f9f7 21704 "pcmpeqw\t{%2, %0|%0, %2}"
3d34cd91
JH
21705 [(set_attr "type" "mmxcmp")
21706 (set_attr "mode" "DI")])
915119a5
BS
21707
21708(define_insn "eqv2si3"
21709 [(set (match_operand:V2SI 0 "register_operand" "=y")
21710 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21711 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21712 "TARGET_MMX"
0f40f9f7 21713 "pcmpeqd\t{%2, %0|%0, %2}"
3d34cd91
JH
21714 [(set_attr "type" "mmxcmp")
21715 (set_attr "mode" "DI")])
915119a5
BS
21716
21717(define_insn "gtv8qi3"
21718 [(set (match_operand:V8QI 0 "register_operand" "=y")
21719 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21720 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21721 "TARGET_MMX"
0f40f9f7 21722 "pcmpgtb\t{%2, %0|%0, %2}"
3d34cd91
JH
21723 [(set_attr "type" "mmxcmp")
21724 (set_attr "mode" "DI")])
915119a5
BS
21725
21726(define_insn "gtv4hi3"
21727 [(set (match_operand:V4HI 0 "register_operand" "=y")
21728 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21729 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21730 "TARGET_MMX"
0f40f9f7 21731 "pcmpgtw\t{%2, %0|%0, %2}"
3d34cd91
JH
21732 [(set_attr "type" "mmxcmp")
21733 (set_attr "mode" "DI")])
915119a5
BS
21734
21735(define_insn "gtv2si3"
21736 [(set (match_operand:V2SI 0 "register_operand" "=y")
21737 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21738 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21739 "TARGET_MMX"
0f40f9f7 21740 "pcmpgtd\t{%2, %0|%0, %2}"
3d34cd91
JH
21741 [(set_attr "type" "mmxcmp")
21742 (set_attr "mode" "DI")])
915119a5
BS
21743
21744
21745;; MMX max/min insns
21746
21747(define_insn "umaxv8qi3"
21748 [(set (match_operand:V8QI 0 "register_operand" "=y")
21749 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21750 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
47f339cf 21751 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 21752 "pmaxub\t{%2, %0|%0, %2}"
3d34cd91
JH
21753 [(set_attr "type" "mmxadd")
21754 (set_attr "mode" "DI")])
915119a5
BS
21755
21756(define_insn "smaxv4hi3"
21757 [(set (match_operand:V4HI 0 "register_operand" "=y")
21758 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21759 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
47f339cf 21760 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 21761 "pmaxsw\t{%2, %0|%0, %2}"
3d34cd91
JH
21762 [(set_attr "type" "mmxadd")
21763 (set_attr "mode" "DI")])
915119a5
BS
21764
21765(define_insn "uminv8qi3"
21766 [(set (match_operand:V8QI 0 "register_operand" "=y")
21767 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21768 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
47f339cf 21769 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 21770 "pminub\t{%2, %0|%0, %2}"
3d34cd91
JH
21771 [(set_attr "type" "mmxadd")
21772 (set_attr "mode" "DI")])
915119a5
BS
21773
21774(define_insn "sminv4hi3"
21775 [(set (match_operand:V4HI 0 "register_operand" "=y")
21776 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21777 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
47f339cf 21778 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 21779 "pminsw\t{%2, %0|%0, %2}"
3d34cd91
JH
21780 [(set_attr "type" "mmxadd")
21781 (set_attr "mode" "DI")])
915119a5
BS
21782
21783
21784;; MMX shifts
21785
21786(define_insn "ashrv4hi3"
21787 [(set (match_operand:V4HI 0 "register_operand" "=y")
21788 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21789 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21790 "TARGET_MMX"
0f40f9f7 21791 "psraw\t{%2, %0|%0, %2}"
3d34cd91
JH
21792 [(set_attr "type" "mmxshft")
21793 (set_attr "mode" "DI")])
915119a5
BS
21794
21795(define_insn "ashrv2si3"
21796 [(set (match_operand:V2SI 0 "register_operand" "=y")
21797 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21798 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21799 "TARGET_MMX"
0f40f9f7 21800 "psrad\t{%2, %0|%0, %2}"
3d34cd91
JH
21801 [(set_attr "type" "mmxshft")
21802 (set_attr "mode" "DI")])
915119a5
BS
21803
21804(define_insn "lshrv4hi3"
21805 [(set (match_operand:V4HI 0 "register_operand" "=y")
21806 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21807 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21808 "TARGET_MMX"
0f40f9f7 21809 "psrlw\t{%2, %0|%0, %2}"
3d34cd91
JH
21810 [(set_attr "type" "mmxshft")
21811 (set_attr "mode" "DI")])
915119a5
BS
21812
21813(define_insn "lshrv2si3"
21814 [(set (match_operand:V2SI 0 "register_operand" "=y")
21815 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21816 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21817 "TARGET_MMX"
0f40f9f7 21818 "psrld\t{%2, %0|%0, %2}"
3d34cd91
JH
21819 [(set_attr "type" "mmxshft")
21820 (set_attr "mode" "DI")])
915119a5
BS
21821
21822;; See logical MMX insns.
21823(define_insn "mmx_lshrdi3"
21824 [(set (match_operand:DI 0 "register_operand" "=y")
2b71bf37
JH
21825 (unspec:DI
21826 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8ee41eaf
RH
21827 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21828 UNSPEC_NOP))]
915119a5 21829 "TARGET_MMX"
0f40f9f7 21830 "psrlq\t{%2, %0|%0, %2}"
3d34cd91
JH
21831 [(set_attr "type" "mmxshft")
21832 (set_attr "mode" "DI")])
915119a5
BS
21833
21834(define_insn "ashlv4hi3"
21835 [(set (match_operand:V4HI 0 "register_operand" "=y")
21836 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21837 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21838 "TARGET_MMX"
0f40f9f7 21839 "psllw\t{%2, %0|%0, %2}"
3d34cd91
JH
21840 [(set_attr "type" "mmxshft")
21841 (set_attr "mode" "DI")])
915119a5
BS
21842
21843(define_insn "ashlv2si3"
21844 [(set (match_operand:V2SI 0 "register_operand" "=y")
21845 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21846 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21847 "TARGET_MMX"
0f40f9f7 21848 "pslld\t{%2, %0|%0, %2}"
3d34cd91
JH
21849 [(set_attr "type" "mmxshft")
21850 (set_attr "mode" "DI")])
915119a5
BS
21851
21852;; See logical MMX insns.
21853(define_insn "mmx_ashldi3"
21854 [(set (match_operand:DI 0 "register_operand" "=y")
2b71bf37
JH
21855 (unspec:DI
21856 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
8ee41eaf
RH
21857 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21858 UNSPEC_NOP))]
915119a5 21859 "TARGET_MMX"
0f40f9f7 21860 "psllq\t{%2, %0|%0, %2}"
3d34cd91
JH
21861 [(set_attr "type" "mmxshft")
21862 (set_attr "mode" "DI")])
915119a5
BS
21863
21864
21865;; MMX pack/unpack insns.
21866
21867(define_insn "mmx_packsswb"
21868 [(set (match_operand:V8QI 0 "register_operand" "=y")
21869 (vec_concat:V8QI
21870 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21871 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21872 "TARGET_MMX"
0f40f9f7 21873 "packsswb\t{%2, %0|%0, %2}"
3d34cd91
JH
21874 [(set_attr "type" "mmxshft")
21875 (set_attr "mode" "DI")])
915119a5
BS
21876
21877(define_insn "mmx_packssdw"
21878 [(set (match_operand:V4HI 0 "register_operand" "=y")
21879 (vec_concat:V4HI
21880 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21881 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21882 "TARGET_MMX"
0f40f9f7 21883 "packssdw\t{%2, %0|%0, %2}"
3d34cd91
JH
21884 [(set_attr "type" "mmxshft")
21885 (set_attr "mode" "DI")])
915119a5
BS
21886
21887(define_insn "mmx_packuswb"
21888 [(set (match_operand:V8QI 0 "register_operand" "=y")
21889 (vec_concat:V8QI
21890 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21891 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21892 "TARGET_MMX"
0f40f9f7 21893 "packuswb\t{%2, %0|%0, %2}"
3d34cd91
JH
21894 [(set_attr "type" "mmxshft")
21895 (set_attr "mode" "DI")])
915119a5
BS
21896
21897(define_insn "mmx_punpckhbw"
21898 [(set (match_operand:V8QI 0 "register_operand" "=y")
21899 (vec_merge:V8QI
21900 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21901 (parallel [(const_int 4)
21902 (const_int 0)
21903 (const_int 5)
21904 (const_int 1)
21905 (const_int 6)
21906 (const_int 2)
21907 (const_int 7)
21908 (const_int 3)]))
21909 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21910 (parallel [(const_int 0)
21911 (const_int 4)
21912 (const_int 1)
21913 (const_int 5)
21914 (const_int 2)
21915 (const_int 6)
21916 (const_int 3)
21917 (const_int 7)]))
21918 (const_int 85)))]
21919 "TARGET_MMX"
0f40f9f7 21920 "punpckhbw\t{%2, %0|%0, %2}"
3d34cd91
JH
21921 [(set_attr "type" "mmxcvt")
21922 (set_attr "mode" "DI")])
915119a5
BS
21923
21924(define_insn "mmx_punpckhwd"
21925 [(set (match_operand:V4HI 0 "register_operand" "=y")
21926 (vec_merge:V4HI
21927 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21928 (parallel [(const_int 0)
21929 (const_int 2)
21930 (const_int 1)
21931 (const_int 3)]))
21932 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21933 (parallel [(const_int 2)
21934 (const_int 0)
21935 (const_int 3)
21936 (const_int 1)]))
21937 (const_int 5)))]
21938 "TARGET_MMX"
0f40f9f7 21939 "punpckhwd\t{%2, %0|%0, %2}"
3d34cd91
JH
21940 [(set_attr "type" "mmxcvt")
21941 (set_attr "mode" "DI")])
915119a5
BS
21942
21943(define_insn "mmx_punpckhdq"
21944 [(set (match_operand:V2SI 0 "register_operand" "=y")
21945 (vec_merge:V2SI
077084dd 21946 (match_operand:V2SI 1 "register_operand" "0")
915119a5
BS
21947 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21948 (parallel [(const_int 1)
21949 (const_int 0)]))
21950 (const_int 1)))]
21951 "TARGET_MMX"
0f40f9f7 21952 "punpckhdq\t{%2, %0|%0, %2}"
3d34cd91
JH
21953 [(set_attr "type" "mmxcvt")
21954 (set_attr "mode" "DI")])
915119a5
BS
21955
21956(define_insn "mmx_punpcklbw"
21957 [(set (match_operand:V8QI 0 "register_operand" "=y")
21958 (vec_merge:V8QI
21959 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21960 (parallel [(const_int 0)
21961 (const_int 4)
21962 (const_int 1)
21963 (const_int 5)
21964 (const_int 2)
21965 (const_int 6)
21966 (const_int 3)
21967 (const_int 7)]))
21968 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21969 (parallel [(const_int 4)
21970 (const_int 0)
21971 (const_int 5)
21972 (const_int 1)
21973 (const_int 6)
21974 (const_int 2)
21975 (const_int 7)
21976 (const_int 3)]))
21977 (const_int 85)))]
21978 "TARGET_MMX"
0f40f9f7 21979 "punpcklbw\t{%2, %0|%0, %2}"
3d34cd91
JH
21980 [(set_attr "type" "mmxcvt")
21981 (set_attr "mode" "DI")])
915119a5
BS
21982
21983(define_insn "mmx_punpcklwd"
21984 [(set (match_operand:V4HI 0 "register_operand" "=y")
21985 (vec_merge:V4HI
21986 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21987 (parallel [(const_int 2)
21988 (const_int 0)
21989 (const_int 3)
21990 (const_int 1)]))
21991 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21992 (parallel [(const_int 0)
21993 (const_int 2)
21994 (const_int 1)
21995 (const_int 3)]))
21996 (const_int 5)))]
21997 "TARGET_MMX"
0f40f9f7 21998 "punpcklwd\t{%2, %0|%0, %2}"
3d34cd91
JH
21999 [(set_attr "type" "mmxcvt")
22000 (set_attr "mode" "DI")])
915119a5
BS
22001
22002(define_insn "mmx_punpckldq"
22003 [(set (match_operand:V2SI 0 "register_operand" "=y")
22004 (vec_merge:V2SI
22005 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22006 (parallel [(const_int 1)
22007 (const_int 0)]))
077084dd 22008 (match_operand:V2SI 2 "register_operand" "y")
915119a5
BS
22009 (const_int 1)))]
22010 "TARGET_MMX"
0f40f9f7 22011 "punpckldq\t{%2, %0|%0, %2}"
3d34cd91
JH
22012 [(set_attr "type" "mmxcvt")
22013 (set_attr "mode" "DI")])
915119a5
BS
22014
22015
22016;; Miscellaneous stuff
22017
22018(define_insn "emms"
8ee41eaf 22019 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
915119a5
BS
22020 (clobber (reg:XF 8))
22021 (clobber (reg:XF 9))
22022 (clobber (reg:XF 10))
22023 (clobber (reg:XF 11))
22024 (clobber (reg:XF 12))
22025 (clobber (reg:XF 13))
22026 (clobber (reg:XF 14))
22027 (clobber (reg:XF 15))
915119a5
BS
22028 (clobber (reg:DI 29))
22029 (clobber (reg:DI 30))
22030 (clobber (reg:DI 31))
22031 (clobber (reg:DI 32))
22032 (clobber (reg:DI 33))
bd793c65
BS
22033 (clobber (reg:DI 34))
22034 (clobber (reg:DI 35))
22035 (clobber (reg:DI 36))]
915119a5
BS
22036 "TARGET_MMX"
22037 "emms"
bd793c65
BS
22038 [(set_attr "type" "mmx")
22039 (set_attr "memory" "unknown")])
915119a5
BS
22040
22041(define_insn "ldmxcsr"
8ee41eaf
RH
22042 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22043 UNSPECV_LDMXCSR)]
36210500 22044 "TARGET_SSE"
0f40f9f7 22045 "ldmxcsr\t%0"
36210500 22046 [(set_attr "type" "sse")
29628f27 22047 (set_attr "memory" "load")])
915119a5
BS
22048
22049(define_insn "stmxcsr"
22050 [(set (match_operand:SI 0 "memory_operand" "=m")
8ee41eaf 22051 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
36210500 22052 "TARGET_SSE"
0f40f9f7 22053 "stmxcsr\t%0"
36210500 22054 [(set_attr "type" "sse")
29628f27 22055 (set_attr "memory" "store")])
915119a5
BS
22056
22057(define_expand "sfence"
22058 [(set (match_dup 0)
8ee41eaf 22059 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
47f339cf 22060 "TARGET_SSE || TARGET_3DNOW_A"
915119a5
BS
22061{
22062 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22063 MEM_VOLATILE_P (operands[0]) = 1;
0f40f9f7 22064})
915119a5
BS
22065
22066(define_insn "*sfence_insn"
22067 [(set (match_operand:BLK 0 "" "")
8ee41eaf 22068 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
47f339cf 22069 "TARGET_SSE || TARGET_3DNOW_A"
915119a5 22070 "sfence"
bd793c65
BS
22071 [(set_attr "type" "sse")
22072 (set_attr "memory" "unknown")])
915119a5 22073
ad919812
JH
22074(define_expand "sse_prologue_save"
22075 [(parallel [(set (match_operand:BLK 0 "" "")
22076 (unspec:BLK [(reg:DI 21)
22077 (reg:DI 22)
22078 (reg:DI 23)
22079 (reg:DI 24)
22080 (reg:DI 25)
22081 (reg:DI 26)
22082 (reg:DI 27)
8ee41eaf 22083 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
ad919812
JH
22084 (use (match_operand:DI 1 "register_operand" ""))
22085 (use (match_operand:DI 2 "immediate_operand" ""))
22086 (use (label_ref:DI (match_operand 3 "" "")))])]
22087 "TARGET_64BIT"
22088 "")
22089
22090(define_insn "*sse_prologue_save_insn"
22091 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22092 (match_operand:DI 4 "const_int_operand" "n")))
22093 (unspec:BLK [(reg:DI 21)
22094 (reg:DI 22)
22095 (reg:DI 23)
22096 (reg:DI 24)
22097 (reg:DI 25)
22098 (reg:DI 26)
22099 (reg:DI 27)
8ee41eaf 22100 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
ad919812
JH
22101 (use (match_operand:DI 1 "register_operand" "r"))
22102 (use (match_operand:DI 2 "const_int_operand" "i"))
22103 (use (label_ref:DI (match_operand 3 "" "X")))]
22104 "TARGET_64BIT
22105 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22106 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22107 "*
22108{
22109 int i;
22110 operands[0] = gen_rtx_MEM (Pmode,
22111 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22112 output_asm_insn (\"jmp\\t%A1\", operands);
22113 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22114 {
22115 operands[4] = adjust_address (operands[0], DImode, i*16);
22116 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22117 PUT_MODE (operands[4], TImode);
22118 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22119 output_asm_insn (\"rex\", operands);
22120 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22121 }
4977bab6 22122 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
ad919812
JH
22123 CODE_LABEL_NUMBER (operands[3]));
22124 RET;
22125}
22126 "
22127 [(set_attr "type" "other")
22128 (set_attr "length_immediate" "0")
22129 (set_attr "length_address" "0")
22130 (set_attr "length" "135")
22131 (set_attr "memory" "store")
22132 (set_attr "modrm" "0")
22133 (set_attr "mode" "DI")])
47f339cf
BS
22134
22135;; 3Dnow! instructions
22136
22137(define_insn "addv2sf3"
22138 [(set (match_operand:V2SF 0 "register_operand" "=y")
22139 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22140 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22141 "TARGET_3DNOW"
22142 "pfadd\\t{%2, %0|%0, %2}"
3d34cd91
JH
22143 [(set_attr "type" "mmxadd")
22144 (set_attr "mode" "V2SF")])
47f339cf
BS
22145
22146(define_insn "subv2sf3"
22147 [(set (match_operand:V2SF 0 "register_operand" "=y")
22148 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22149 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22150 "TARGET_3DNOW"
22151 "pfsub\\t{%2, %0|%0, %2}"
3d34cd91
JH
22152 [(set_attr "type" "mmxadd")
22153 (set_attr "mode" "V2SF")])
47f339cf
BS
22154
22155(define_insn "subrv2sf3"
22156 [(set (match_operand:V2SF 0 "register_operand" "=y")
22157 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22158 (match_operand:V2SF 1 "register_operand" "0")))]
22159 "TARGET_3DNOW"
22160 "pfsubr\\t{%2, %0|%0, %2}"
3d34cd91
JH
22161 [(set_attr "type" "mmxadd")
22162 (set_attr "mode" "V2SF")])
47f339cf
BS
22163
22164(define_insn "gtv2sf3"
22165 [(set (match_operand:V2SI 0 "register_operand" "=y")
22166 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22167 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22168 "TARGET_3DNOW"
22169 "pfcmpgt\\t{%2, %0|%0, %2}"
3d34cd91
JH
22170 [(set_attr "type" "mmxcmp")
22171 (set_attr "mode" "V2SF")])
47f339cf
BS
22172
22173(define_insn "gev2sf3"
22174 [(set (match_operand:V2SI 0 "register_operand" "=y")
22175 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22176 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22177 "TARGET_3DNOW"
22178 "pfcmpge\\t{%2, %0|%0, %2}"
3d34cd91
JH
22179 [(set_attr "type" "mmxcmp")
22180 (set_attr "mode" "V2SF")])
47f339cf
BS
22181
22182(define_insn "eqv2sf3"
22183 [(set (match_operand:V2SI 0 "register_operand" "=y")
22184 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22185 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22186 "TARGET_3DNOW"
22187 "pfcmpeq\\t{%2, %0|%0, %2}"
3d34cd91
JH
22188 [(set_attr "type" "mmxcmp")
22189 (set_attr "mode" "V2SF")])
47f339cf
BS
22190
22191(define_insn "pfmaxv2sf3"
22192 [(set (match_operand:V2SF 0 "register_operand" "=y")
22193 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22194 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22195 "TARGET_3DNOW"
22196 "pfmax\\t{%2, %0|%0, %2}"
3d34cd91
JH
22197 [(set_attr "type" "mmxadd")
22198 (set_attr "mode" "V2SF")])
47f339cf
BS
22199
22200(define_insn "pfminv2sf3"
22201 [(set (match_operand:V2SF 0 "register_operand" "=y")
22202 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22203 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22204 "TARGET_3DNOW"
22205 "pfmin\\t{%2, %0|%0, %2}"
3d34cd91
JH
22206 [(set_attr "type" "mmxadd")
22207 (set_attr "mode" "V2SF")])
47f339cf
BS
22208
22209(define_insn "mulv2sf3"
22210 [(set (match_operand:V2SF 0 "register_operand" "=y")
22211 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22212 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22213 "TARGET_3DNOW"
22214 "pfmul\\t{%2, %0|%0, %2}"
3d34cd91
JH
22215 [(set_attr "type" "mmxmul")
22216 (set_attr "mode" "V2SF")])
47f339cf
BS
22217
22218(define_insn "femms"
8ee41eaf 22219 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
47f339cf
BS
22220 (clobber (reg:XF 8))
22221 (clobber (reg:XF 9))
22222 (clobber (reg:XF 10))
22223 (clobber (reg:XF 11))
22224 (clobber (reg:XF 12))
22225 (clobber (reg:XF 13))
22226 (clobber (reg:XF 14))
22227 (clobber (reg:XF 15))
22228 (clobber (reg:DI 29))
22229 (clobber (reg:DI 30))
22230 (clobber (reg:DI 31))
22231 (clobber (reg:DI 32))
22232 (clobber (reg:DI 33))
22233 (clobber (reg:DI 34))
22234 (clobber (reg:DI 35))
22235 (clobber (reg:DI 36))]
22236 "TARGET_3DNOW"
22237 "femms"
d82283d5
GS
22238 [(set_attr "type" "mmx")
22239 (set_attr "memory" "none")])
47f339cf 22240
47f339cf
BS
22241(define_insn "pf2id"
22242 [(set (match_operand:V2SI 0 "register_operand" "=y")
22243 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22244 "TARGET_3DNOW"
22245 "pf2id\\t{%1, %0|%0, %1}"
3d34cd91
JH
22246 [(set_attr "type" "mmxcvt")
22247 (set_attr "mode" "V2SF")])
47f339cf
BS
22248
22249(define_insn "pf2iw"
22250 [(set (match_operand:V2SI 0 "register_operand" "=y")
22251 (sign_extend:V2SI
22252 (ss_truncate:V2HI
22253 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22254 "TARGET_3DNOW_A"
22255 "pf2iw\\t{%1, %0|%0, %1}"
3d34cd91
JH
22256 [(set_attr "type" "mmxcvt")
22257 (set_attr "mode" "V2SF")])
47f339cf
BS
22258
22259(define_insn "pfacc"
22260 [(set (match_operand:V2SF 0 "register_operand" "=y")
22261 (vec_concat:V2SF
22262 (plus:SF
22263 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22264 (parallel [(const_int 0)]))
22265 (vec_select:SF (match_dup 1)
22266 (parallel [(const_int 1)])))
22267 (plus:SF
22268 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22269 (parallel [(const_int 0)]))
22270 (vec_select:SF (match_dup 2)
22271 (parallel [(const_int 1)])))))]
22272 "TARGET_3DNOW"
22273 "pfacc\\t{%2, %0|%0, %2}"
3d34cd91
JH
22274 [(set_attr "type" "mmxadd")
22275 (set_attr "mode" "V2SF")])
47f339cf
BS
22276
22277(define_insn "pfnacc"
22278 [(set (match_operand:V2SF 0 "register_operand" "=y")
22279 (vec_concat:V2SF
22280 (minus:SF
22281 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22282 (parallel [(const_int 0)]))
22283 (vec_select:SF (match_dup 1)
22284 (parallel [(const_int 1)])))
22285 (minus:SF
22286 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22287 (parallel [(const_int 0)]))
22288 (vec_select:SF (match_dup 2)
22289 (parallel [(const_int 1)])))))]
22290 "TARGET_3DNOW_A"
22291 "pfnacc\\t{%2, %0|%0, %2}"
3d34cd91
JH
22292 [(set_attr "type" "mmxadd")
22293 (set_attr "mode" "V2SF")])
47f339cf
BS
22294
22295(define_insn "pfpnacc"
22296 [(set (match_operand:V2SF 0 "register_operand" "=y")
22297 (vec_concat:V2SF
22298 (minus:SF
22299 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22300 (parallel [(const_int 0)]))
22301 (vec_select:SF (match_dup 1)
22302 (parallel [(const_int 1)])))
22303 (plus:SF
22304 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22305 (parallel [(const_int 0)]))
22306 (vec_select:SF (match_dup 2)
22307 (parallel [(const_int 1)])))))]
22308 "TARGET_3DNOW_A"
22309 "pfpnacc\\t{%2, %0|%0, %2}"
3d34cd91
JH
22310 [(set_attr "type" "mmxadd")
22311 (set_attr "mode" "V2SF")])
47f339cf
BS
22312
22313(define_insn "pi2fw"
22314 [(set (match_operand:V2SF 0 "register_operand" "=y")
22315 (float:V2SF
22316 (vec_concat:V2SI
22317 (sign_extend:SI
22318 (truncate:HI
22319 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22320 (parallel [(const_int 0)]))))
22321 (sign_extend:SI
22322 (truncate:HI
22323 (vec_select:SI (match_dup 1)
22324 (parallel [(const_int 1)])))))))]
22325 "TARGET_3DNOW_A"
22326 "pi2fw\\t{%1, %0|%0, %1}"
3d34cd91
JH
22327 [(set_attr "type" "mmxcvt")
22328 (set_attr "mode" "V2SF")])
47f339cf
BS
22329
22330(define_insn "floatv2si2"
22331 [(set (match_operand:V2SF 0 "register_operand" "=y")
22332 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22333 "TARGET_3DNOW"
22334 "pi2fd\\t{%1, %0|%0, %1}"
3d34cd91
JH
22335 [(set_attr "type" "mmxcvt")
22336 (set_attr "mode" "V2SF")])
47f339cf
BS
22337
22338;; This insn is identical to pavgb in operation, but the opcode is
22339;; different. To avoid accidentally matching pavgb, use an unspec.
22340
22341(define_insn "pavgusb"
22342 [(set (match_operand:V8QI 0 "register_operand" "=y")
22343 (unspec:V8QI
22344 [(match_operand:V8QI 1 "register_operand" "0")
8ee41eaf
RH
22345 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22346 UNSPEC_PAVGUSB))]
47f339cf
BS
22347 "TARGET_3DNOW"
22348 "pavgusb\\t{%2, %0|%0, %2}"
3d34cd91
JH
22349 [(set_attr "type" "mmxshft")
22350 (set_attr "mode" "TI")])
47f339cf 22351
d1f87653 22352;; 3DNow reciprocal and sqrt
47f339cf
BS
22353
22354(define_insn "pfrcpv2sf2"
22355 [(set (match_operand:V2SF 0 "register_operand" "=y")
8ee41eaf
RH
22356 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22357 UNSPEC_PFRCP))]
47f339cf
BS
22358 "TARGET_3DNOW"
22359 "pfrcp\\t{%1, %0|%0, %1}"
3d34cd91
JH
22360 [(set_attr "type" "mmx")
22361 (set_attr "mode" "TI")])
47f339cf
BS
22362
22363(define_insn "pfrcpit1v2sf3"
22364 [(set (match_operand:V2SF 0 "register_operand" "=y")
22365 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
8ee41eaf
RH
22366 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22367 UNSPEC_PFRCPIT1))]
47f339cf
BS
22368 "TARGET_3DNOW"
22369 "pfrcpit1\\t{%2, %0|%0, %2}"
3d34cd91
JH
22370 [(set_attr "type" "mmx")
22371 (set_attr "mode" "TI")])
47f339cf
BS
22372
22373(define_insn "pfrcpit2v2sf3"
22374 [(set (match_operand:V2SF 0 "register_operand" "=y")
22375 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
8ee41eaf
RH
22376 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22377 UNSPEC_PFRCPIT2))]
47f339cf
BS
22378 "TARGET_3DNOW"
22379 "pfrcpit2\\t{%2, %0|%0, %2}"
3d34cd91
JH
22380 [(set_attr "type" "mmx")
22381 (set_attr "mode" "TI")])
47f339cf
BS
22382
22383(define_insn "pfrsqrtv2sf2"
22384 [(set (match_operand:V2SF 0 "register_operand" "=y")
8ee41eaf
RH
22385 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22386 UNSPEC_PFRSQRT))]
47f339cf 22387 "TARGET_3DNOW"
3d34cd91
JH
22388 "pfrsqrt\\t{%1, %0|%0, %1}"
22389 [(set_attr "type" "mmx")
22390 (set_attr "mode" "TI")])
47f339cf
BS
22391
22392(define_insn "pfrsqit1v2sf3"
22393 [(set (match_operand:V2SF 0 "register_operand" "=y")
22394 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
8ee41eaf
RH
22395 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22396 UNSPEC_PFRSQIT1))]
47f339cf
BS
22397 "TARGET_3DNOW"
22398 "pfrsqit1\\t{%2, %0|%0, %2}"
3d34cd91
JH
22399 [(set_attr "type" "mmx")
22400 (set_attr "mode" "TI")])
47f339cf
BS
22401
22402(define_insn "pmulhrwv4hi3"
22403 [(set (match_operand:V4HI 0 "register_operand" "=y")
22404 (truncate:V4HI
22405 (lshiftrt:V4SI
22406 (plus:V4SI
22407 (mult:V4SI
22408 (sign_extend:V4SI
22409 (match_operand:V4HI 1 "register_operand" "0"))
22410 (sign_extend:V4SI
22411 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
69ef87e2
AH
22412 (const_vector:V4SI [(const_int 32768)
22413 (const_int 32768)
22414 (const_int 32768)
22415 (const_int 32768)]))
22416 (const_int 16))))]
47f339cf
BS
22417 "TARGET_3DNOW"
22418 "pmulhrw\\t{%2, %0|%0, %2}"
3d34cd91
JH
22419 [(set_attr "type" "mmxmul")
22420 (set_attr "mode" "TI")])
47f339cf
BS
22421
22422(define_insn "pswapdv2si2"
22423 [(set (match_operand:V2SI 0 "register_operand" "=y")
22424 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22425 (parallel [(const_int 1) (const_int 0)])))]
22426 "TARGET_3DNOW_A"
22427 "pswapd\\t{%1, %0|%0, %1}"
3d34cd91
JH
22428 [(set_attr "type" "mmxcvt")
22429 (set_attr "mode" "TI")])
47f339cf
BS
22430
22431(define_insn "pswapdv2sf2"
22432 [(set (match_operand:V2SF 0 "register_operand" "=y")
22433 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22434 (parallel [(const_int 1) (const_int 0)])))]
22435 "TARGET_3DNOW_A"
22436 "pswapd\\t{%1, %0|%0, %1}"
3d34cd91
JH
22437 [(set_attr "type" "mmxcvt")
22438 (set_attr "mode" "TI")])
e37af218
RH
22439
22440(define_expand "prefetch"
052c96b1 22441 [(prefetch (match_operand 0 "address_operand" "")
e37af218
RH
22442 (match_operand:SI 1 "const_int_operand" "")
22443 (match_operand:SI 2 "const_int_operand" ""))]
22444 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22445{
22446 int rw = INTVAL (operands[1]);
22447 int locality = INTVAL (operands[2]);
7d378549 22448
e37af218
RH
22449 if (rw != 0 && rw != 1)
22450 abort ();
22451 if (locality < 0 || locality > 3)
22452 abort ();
052c96b1
JH
22453 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22454 abort ();
e37af218
RH
22455
22456 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22457 suported by SSE counterpart or the SSE prefetch is not available
22458 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22459 of locality. */
22460 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
7d378549 22461 operands[2] = GEN_INT (3);
e37af218 22462 else
7d378549 22463 operands[1] = const0_rtx;
e37af218
RH
22464})
22465
22466(define_insn "*prefetch_sse"
e8d52ba0 22467 [(prefetch (match_operand:SI 0 "address_operand" "p")
e37af218
RH
22468 (const_int 0)
22469 (match_operand:SI 1 "const_int_operand" ""))]
052c96b1
JH
22470 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22471{
22472 static const char * const patterns[4] = {
22473 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22474 };
22475
22476 int locality = INTVAL (operands[1]);
22477 if (locality < 0 || locality > 3)
22478 abort ();
22479
22480 return patterns[locality];
22481}
22482 [(set_attr "type" "sse")
22483 (set_attr "memory" "none")])
22484
22485(define_insn "*prefetch_sse_rex"
22486 [(prefetch (match_operand:DI 0 "address_operand" "p")
22487 (const_int 0)
22488 (match_operand:SI 1 "const_int_operand" ""))]
22489 "TARGET_PREFETCH_SSE && TARGET_64BIT"
e37af218
RH
22490{
22491 static const char * const patterns[4] = {
22492 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22493 };
22494
22495 int locality = INTVAL (operands[1]);
22496 if (locality < 0 || locality > 3)
22497 abort ();
22498
22499 return patterns[locality];
22500}
3d34cd91
JH
22501 [(set_attr "type" "sse")
22502 (set_attr "memory" "none")])
e37af218
RH
22503
22504(define_insn "*prefetch_3dnow"
22505 [(prefetch (match_operand:SI 0 "address_operand" "p")
22506 (match_operand:SI 1 "const_int_operand" "n")
7d378549 22507 (const_int 3))]
052c96b1
JH
22508 "TARGET_3DNOW && !TARGET_64BIT"
22509{
22510 if (INTVAL (operands[1]) == 0)
22511 return "prefetch\t%a0";
22512 else
22513 return "prefetchw\t%a0";
22514}
22515 [(set_attr "type" "mmx")
22516 (set_attr "memory" "none")])
22517
22518(define_insn "*prefetch_3dnow_rex"
22519 [(prefetch (match_operand:DI 0 "address_operand" "p")
22520 (match_operand:SI 1 "const_int_operand" "n")
22521 (const_int 3))]
22522 "TARGET_3DNOW && TARGET_64BIT"
e37af218
RH
22523{
22524 if (INTVAL (operands[1]) == 0)
22525 return "prefetch\t%a0";
22526 else
22527 return "prefetchw\t%a0";
22528}
3d34cd91
JH
22529 [(set_attr "type" "mmx")
22530 (set_attr "memory" "none")])
fbe5eb6d
BS
22531
22532;; SSE2 support
22533
22534(define_insn "addv2df3"
22535 [(set (match_operand:V2DF 0 "register_operand" "=x")
22536 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22537 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22538 "TARGET_SSE2"
22539 "addpd\t{%2, %0|%0, %2}"
3d34cd91
JH
22540 [(set_attr "type" "sseadd")
22541 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22542
22543(define_insn "vmaddv2df3"
22544 [(set (match_operand:V2DF 0 "register_operand" "=x")
22545 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22546 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22547 (match_dup 1)
22548 (const_int 1)))]
22549 "TARGET_SSE2"
22550 "addsd\t{%2, %0|%0, %2}"
3d34cd91
JH
22551 [(set_attr "type" "sseadd")
22552 (set_attr "mode" "DF")])
fbe5eb6d
BS
22553
22554(define_insn "subv2df3"
22555 [(set (match_operand:V2DF 0 "register_operand" "=x")
22556 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22557 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22558 "TARGET_SSE2"
22559 "subpd\t{%2, %0|%0, %2}"
3d34cd91
JH
22560 [(set_attr "type" "sseadd")
22561 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22562
22563(define_insn "vmsubv2df3"
22564 [(set (match_operand:V2DF 0 "register_operand" "=x")
22565 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22566 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22567 (match_dup 1)
22568 (const_int 1)))]
22569 "TARGET_SSE2"
22570 "subsd\t{%2, %0|%0, %2}"
3d34cd91
JH
22571 [(set_attr "type" "sseadd")
22572 (set_attr "mode" "DF")])
fbe5eb6d
BS
22573
22574(define_insn "mulv2df3"
22575 [(set (match_operand:V2DF 0 "register_operand" "=x")
22576 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22577 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22578 "TARGET_SSE2"
22579 "mulpd\t{%2, %0|%0, %2}"
3d34cd91
JH
22580 [(set_attr "type" "ssemul")
22581 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22582
22583(define_insn "vmmulv2df3"
22584 [(set (match_operand:V2DF 0 "register_operand" "=x")
22585 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22586 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22587 (match_dup 1)
22588 (const_int 1)))]
22589 "TARGET_SSE2"
22590 "mulsd\t{%2, %0|%0, %2}"
3d34cd91
JH
22591 [(set_attr "type" "ssemul")
22592 (set_attr "mode" "DF")])
fbe5eb6d
BS
22593
22594(define_insn "divv2df3"
22595 [(set (match_operand:V2DF 0 "register_operand" "=x")
22596 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22597 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22598 "TARGET_SSE2"
22599 "divpd\t{%2, %0|%0, %2}"
3d34cd91
JH
22600 [(set_attr "type" "ssediv")
22601 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22602
22603(define_insn "vmdivv2df3"
22604 [(set (match_operand:V2DF 0 "register_operand" "=x")
22605 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22606 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22607 (match_dup 1)
22608 (const_int 1)))]
22609 "TARGET_SSE2"
22610 "divsd\t{%2, %0|%0, %2}"
3d34cd91
JH
22611 [(set_attr "type" "ssediv")
22612 (set_attr "mode" "DF")])
fbe5eb6d
BS
22613
22614;; SSE min/max
22615
22616(define_insn "smaxv2df3"
22617 [(set (match_operand:V2DF 0 "register_operand" "=x")
22618 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22619 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22620 "TARGET_SSE2"
22621 "maxpd\t{%2, %0|%0, %2}"
3d34cd91
JH
22622 [(set_attr "type" "sseadd")
22623 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22624
22625(define_insn "vmsmaxv2df3"
22626 [(set (match_operand:V2DF 0 "register_operand" "=x")
22627 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22628 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22629 (match_dup 1)
22630 (const_int 1)))]
22631 "TARGET_SSE2"
22632 "maxsd\t{%2, %0|%0, %2}"
3d34cd91
JH
22633 [(set_attr "type" "sseadd")
22634 (set_attr "mode" "DF")])
fbe5eb6d
BS
22635
22636(define_insn "sminv2df3"
22637 [(set (match_operand:V2DF 0 "register_operand" "=x")
22638 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22639 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22640 "TARGET_SSE2"
22641 "minpd\t{%2, %0|%0, %2}"
3d34cd91
JH
22642 [(set_attr "type" "sseadd")
22643 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22644
22645(define_insn "vmsminv2df3"
22646 [(set (match_operand:V2DF 0 "register_operand" "=x")
22647 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22648 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22649 (match_dup 1)
22650 (const_int 1)))]
22651 "TARGET_SSE2"
22652 "minsd\t{%2, %0|%0, %2}"
3d34cd91
JH
22653 [(set_attr "type" "sseadd")
22654 (set_attr "mode" "DF")])
fbe5eb6d
BS
22655;; SSE2 square root. There doesn't appear to be an extension for the
22656;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22657
22658(define_insn "sqrtv2df2"
22659 [(set (match_operand:V2DF 0 "register_operand" "=x")
22660 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22661 "TARGET_SSE2"
22662 "sqrtpd\t{%1, %0|%0, %1}"
3d34cd91
JH
22663 [(set_attr "type" "sse")
22664 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22665
22666(define_insn "vmsqrtv2df2"
22667 [(set (match_operand:V2DF 0 "register_operand" "=x")
22668 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22669 (match_operand:V2DF 2 "register_operand" "0")
22670 (const_int 1)))]
22671 "TARGET_SSE2"
22672 "sqrtsd\t{%1, %0|%0, %1}"
3d34cd91
JH
22673 [(set_attr "type" "sse")
22674 (set_attr "mode" "SF")])
fbe5eb6d
BS
22675
22676;; SSE mask-generating compares
22677
22678(define_insn "maskcmpv2df3"
22679 [(set (match_operand:V2DI 0 "register_operand" "=x")
22680 (match_operator:V2DI 3 "sse_comparison_operator"
22681 [(match_operand:V2DF 1 "register_operand" "0")
22682 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22683 "TARGET_SSE2"
22684 "cmp%D3pd\t{%2, %0|%0, %2}"
3d34cd91
JH
22685 [(set_attr "type" "ssecmp")
22686 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22687
22688(define_insn "maskncmpv2df3"
22689 [(set (match_operand:V2DI 0 "register_operand" "=x")
22690 (not:V2DI
22691 (match_operator:V2DI 3 "sse_comparison_operator"
22692 [(match_operand:V2DF 1 "register_operand" "0")
22693 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22694 "TARGET_SSE2"
1194ca05
JH
22695{
22696 if (GET_CODE (operands[3]) == UNORDERED)
22697 return "cmpordps\t{%2, %0|%0, %2}";
22698 else
22699 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22700}
3d34cd91
JH
22701 [(set_attr "type" "ssecmp")
22702 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22703
22704(define_insn "vmmaskcmpv2df3"
22705 [(set (match_operand:V2DI 0 "register_operand" "=x")
22706 (vec_merge:V2DI
22707 (match_operator:V2DI 3 "sse_comparison_operator"
22708 [(match_operand:V2DF 1 "register_operand" "0")
22709 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
d9deed68 22710 (subreg:V2DI (match_dup 1) 0)
fbe5eb6d
BS
22711 (const_int 1)))]
22712 "TARGET_SSE2"
22713 "cmp%D3sd\t{%2, %0|%0, %2}"
3d34cd91
JH
22714 [(set_attr "type" "ssecmp")
22715 (set_attr "mode" "DF")])
fbe5eb6d
BS
22716
22717(define_insn "vmmaskncmpv2df3"
22718 [(set (match_operand:V2DI 0 "register_operand" "=x")
22719 (vec_merge:V2DI
22720 (not:V2DI
22721 (match_operator:V2DI 3 "sse_comparison_operator"
22722 [(match_operand:V2DF 1 "register_operand" "0")
22723 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22724 (subreg:V2DI (match_dup 1) 0)
22725 (const_int 1)))]
22726 "TARGET_SSE2"
1194ca05
JH
22727{
22728 if (GET_CODE (operands[3]) == UNORDERED)
22729 return "cmpordsd\t{%2, %0|%0, %2}";
22730 else
22731 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22732}
3d34cd91
JH
22733 [(set_attr "type" "ssecmp")
22734 (set_attr "mode" "DF")])
fbe5eb6d
BS
22735
22736(define_insn "sse2_comi"
8bc527af 22737 [(set (reg:CCFP FLAGS_REG)
1194ca05
JH
22738 (compare:CCFP (vec_select:DF
22739 (match_operand:V2DF 0 "register_operand" "x")
22740 (parallel [(const_int 0)]))
22741 (vec_select:DF
22742 (match_operand:V2DF 1 "register_operand" "x")
22743 (parallel [(const_int 0)]))))]
fbe5eb6d
BS
22744 "TARGET_SSE2"
22745 "comisd\t{%1, %0|%0, %1}"
26771da7 22746 [(set_attr "type" "ssecomi")
3d34cd91 22747 (set_attr "mode" "DF")])
fbe5eb6d
BS
22748
22749(define_insn "sse2_ucomi"
8bc527af 22750 [(set (reg:CCFPU FLAGS_REG)
1194ca05
JH
22751 (compare:CCFPU (vec_select:DF
22752 (match_operand:V2DF 0 "register_operand" "x")
22753 (parallel [(const_int 0)]))
22754 (vec_select:DF
22755 (match_operand:V2DF 1 "register_operand" "x")
22756 (parallel [(const_int 0)]))))]
fbe5eb6d
BS
22757 "TARGET_SSE2"
22758 "ucomisd\t{%1, %0|%0, %1}"
26771da7 22759 [(set_attr "type" "ssecomi")
3d34cd91 22760 (set_attr "mode" "DF")])
fbe5eb6d
BS
22761
22762;; SSE Strange Moves.
22763
22764(define_insn "sse2_movmskpd"
22765 [(set (match_operand:SI 0 "register_operand" "=r")
8ee41eaf
RH
22766 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22767 UNSPEC_MOVMSK))]
fbe5eb6d
BS
22768 "TARGET_SSE2"
22769 "movmskpd\t{%1, %0|%0, %1}"
3d34cd91
JH
22770 [(set_attr "type" "ssecvt")
22771 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22772
22773(define_insn "sse2_pmovmskb"
22774 [(set (match_operand:SI 0 "register_operand" "=r")
8ee41eaf
RH
22775 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22776 UNSPEC_MOVMSK))]
fbe5eb6d
BS
22777 "TARGET_SSE2"
22778 "pmovmskb\t{%1, %0|%0, %1}"
3d34cd91
JH
22779 [(set_attr "type" "ssecvt")
22780 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22781
22782(define_insn "sse2_maskmovdqu"
22783 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22784 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
8ee41eaf
RH
22785 (match_operand:V16QI 2 "register_operand" "x")]
22786 UNSPEC_MASKMOV))]
fbe5eb6d
BS
22787 "TARGET_SSE2"
22788 ;; @@@ check ordering of operands in intel/nonintel syntax
22789 "maskmovdqu\t{%2, %1|%1, %2}"
3d34cd91
JH
22790 [(set_attr "type" "ssecvt")
22791 (set_attr "mode" "TI")])
fbe5eb6d 22792
f8ca7923
JH
22793(define_insn "sse2_maskmovdqu_rex64"
22794 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22795 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22796 (match_operand:V16QI 2 "register_operand" "x")]
22797 UNSPEC_MASKMOV))]
22798 "TARGET_SSE2"
22799 ;; @@@ check ordering of operands in intel/nonintel syntax
22800 "maskmovdqu\t{%2, %1|%1, %2}"
22801 [(set_attr "type" "ssecvt")
22802 (set_attr "mode" "TI")])
22803
fbe5eb6d
BS
22804(define_insn "sse2_movntv2df"
22805 [(set (match_operand:V2DF 0 "memory_operand" "=m")
8ee41eaf
RH
22806 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22807 UNSPEC_MOVNT))]
fbe5eb6d
BS
22808 "TARGET_SSE2"
22809 "movntpd\t{%1, %0|%0, %1}"
3d34cd91
JH
22810 [(set_attr "type" "ssecvt")
22811 (set_attr "mode" "V2DF")])
fbe5eb6d 22812
916b60b7
BS
22813(define_insn "sse2_movntv2di"
22814 [(set (match_operand:V2DI 0 "memory_operand" "=m")
8ee41eaf
RH
22815 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22816 UNSPEC_MOVNT))]
fbe5eb6d
BS
22817 "TARGET_SSE2"
22818 "movntdq\t{%1, %0|%0, %1}"
3d34cd91
JH
22819 [(set_attr "type" "ssecvt")
22820 (set_attr "mode" "TI")])
fbe5eb6d
BS
22821
22822(define_insn "sse2_movntsi"
22823 [(set (match_operand:SI 0 "memory_operand" "=m")
8ee41eaf
RH
22824 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22825 UNSPEC_MOVNT))]
fbe5eb6d
BS
22826 "TARGET_SSE2"
22827 "movnti\t{%1, %0|%0, %1}"
3d34cd91
JH
22828 [(set_attr "type" "ssecvt")
22829 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22830
22831;; SSE <-> integer/MMX conversions
22832
22833;; Conversions between SI and SF
22834
22835(define_insn "cvtdq2ps"
22836 [(set (match_operand:V4SF 0 "register_operand" "=x")
22837 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22838 "TARGET_SSE2"
22839 "cvtdq2ps\t{%1, %0|%0, %1}"
3d34cd91
JH
22840 [(set_attr "type" "ssecvt")
22841 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22842
22843(define_insn "cvtps2dq"
22844 [(set (match_operand:V4SI 0 "register_operand" "=x")
22845 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22846 "TARGET_SSE2"
22847 "cvtps2dq\t{%1, %0|%0, %1}"
3d34cd91
JH
22848 [(set_attr "type" "ssecvt")
22849 (set_attr "mode" "TI")])
fbe5eb6d
BS
22850
22851(define_insn "cvttps2dq"
22852 [(set (match_operand:V4SI 0 "register_operand" "=x")
8ee41eaf
RH
22853 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22854 UNSPEC_FIX))]
fbe5eb6d
BS
22855 "TARGET_SSE2"
22856 "cvttps2dq\t{%1, %0|%0, %1}"
3d34cd91
JH
22857 [(set_attr "type" "ssecvt")
22858 (set_attr "mode" "TI")])
fbe5eb6d
BS
22859
22860;; Conversions between SI and DF
22861
22862(define_insn "cvtdq2pd"
22863 [(set (match_operand:V2DF 0 "register_operand" "=x")
22864 (float:V2DF (vec_select:V2SI
916b60b7 22865 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
fbe5eb6d
BS
22866 (parallel
22867 [(const_int 0)
22868 (const_int 1)]))))]
22869 "TARGET_SSE2"
22870 "cvtdq2pd\t{%1, %0|%0, %1}"
3d34cd91
JH
22871 [(set_attr "type" "ssecvt")
22872 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
22873
22874(define_insn "cvtpd2dq"
22875 [(set (match_operand:V4SI 0 "register_operand" "=x")
22876 (vec_concat:V4SI
22877 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22878 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22879 "TARGET_SSE2"
22880 "cvtpd2dq\t{%1, %0|%0, %1}"
3d34cd91
JH
22881 [(set_attr "type" "ssecvt")
22882 (set_attr "mode" "TI")])
fbe5eb6d
BS
22883
22884(define_insn "cvttpd2dq"
22885 [(set (match_operand:V4SI 0 "register_operand" "=x")
22886 (vec_concat:V4SI
8ee41eaf
RH
22887 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22888 UNSPEC_FIX)
fbe5eb6d
BS
22889 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22890 "TARGET_SSE2"
22891 "cvttpd2dq\t{%1, %0|%0, %1}"
3d34cd91
JH
22892 [(set_attr "type" "ssecvt")
22893 (set_attr "mode" "TI")])
fbe5eb6d
BS
22894
22895(define_insn "cvtpd2pi"
22896 [(set (match_operand:V2SI 0 "register_operand" "=y")
22897 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22898 "TARGET_SSE2"
22899 "cvtpd2pi\t{%1, %0|%0, %1}"
3d34cd91
JH
22900 [(set_attr "type" "ssecvt")
22901 (set_attr "mode" "TI")])
fbe5eb6d
BS
22902
22903(define_insn "cvttpd2pi"
22904 [(set (match_operand:V2SI 0 "register_operand" "=y")
8ee41eaf
RH
22905 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22906 UNSPEC_FIX))]
fbe5eb6d
BS
22907 "TARGET_SSE2"
22908 "cvttpd2pi\t{%1, %0|%0, %1}"
3d34cd91
JH
22909 [(set_attr "type" "ssecvt")
22910 (set_attr "mode" "TI")])
fbe5eb6d
BS
22911
22912(define_insn "cvtpi2pd"
22913 [(set (match_operand:V2DF 0 "register_operand" "=x")
22914 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22915 "TARGET_SSE2"
22916 "cvtpi2pd\t{%1, %0|%0, %1}"
3d34cd91
JH
22917 [(set_attr "type" "ssecvt")
22918 (set_attr "mode" "TI")])
fbe5eb6d
BS
22919
22920;; Conversions between SI and DF
22921
22922(define_insn "cvtsd2si"
26f74aa3
JH
22923 [(set (match_operand:SI 0 "register_operand" "=r,r")
22924 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
fbe5eb6d
BS
22925 (parallel [(const_int 0)]))))]
22926 "TARGET_SSE2"
22927 "cvtsd2si\t{%1, %0|%0, %1}"
f56e86bd 22928 [(set_attr "type" "sseicvt")
26f74aa3 22929 (set_attr "athlon_decode" "double,vector")
3d34cd91 22930 (set_attr "mode" "SI")])
fbe5eb6d 22931
453ee231 22932(define_insn "cvtsd2siq"
019238b7 22933 [(set (match_operand:DI 0 "register_operand" "=r,r")
26f74aa3 22934 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
453ee231
JH
22935 (parallel [(const_int 0)]))))]
22936 "TARGET_SSE2 && TARGET_64BIT"
22937 "cvtsd2siq\t{%1, %0|%0, %1}"
22938 [(set_attr "type" "sseicvt")
26f74aa3
JH
22939 (set_attr "athlon_decode" "double,vector")
22940 (set_attr "mode" "DI")])
453ee231 22941
fbe5eb6d 22942(define_insn "cvttsd2si"
f56e86bd
JH
22943 [(set (match_operand:SI 0 "register_operand" "=r,r")
22944 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
8ee41eaf 22945 (parallel [(const_int 0)]))] UNSPEC_FIX))]
fbe5eb6d
BS
22946 "TARGET_SSE2"
22947 "cvttsd2si\t{%1, %0|%0, %1}"
f56e86bd
JH
22948 [(set_attr "type" "sseicvt")
22949 (set_attr "mode" "SI")
22950 (set_attr "athlon_decode" "double,vector")])
fbe5eb6d 22951
453ee231
JH
22952(define_insn "cvttsd2siq"
22953 [(set (match_operand:DI 0 "register_operand" "=r,r")
22954 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22955 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22956 "TARGET_SSE2 && TARGET_64BIT"
22957 "cvttsd2siq\t{%1, %0|%0, %1}"
22958 [(set_attr "type" "sseicvt")
22959 (set_attr "mode" "DI")
22960 (set_attr "athlon_decode" "double,vector")])
22961
fbe5eb6d 22962(define_insn "cvtsi2sd"
f56e86bd
JH
22963 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22964 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
fbe5eb6d
BS
22965 (vec_duplicate:V2DF
22966 (float:DF
f56e86bd 22967 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
fbe5eb6d
BS
22968 (const_int 2)))]
22969 "TARGET_SSE2"
680dd104 22970 "cvtsi2sd\t{%2, %0|%0, %2}"
f56e86bd
JH
22971 [(set_attr "type" "sseicvt")
22972 (set_attr "mode" "DF")
22973 (set_attr "athlon_decode" "double,direct")])
fbe5eb6d 22974
453ee231
JH
22975(define_insn "cvtsi2sdq"
22976 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22977 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22978 (vec_duplicate:V2DF
22979 (float:DF
22980 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22981 (const_int 2)))]
22982 "TARGET_SSE2 && TARGET_64BIT"
22983 "cvtsi2sdq\t{%2, %0|%0, %2}"
22984 [(set_attr "type" "sseicvt")
22985 (set_attr "mode" "DF")
22986 (set_attr "athlon_decode" "double,direct")])
22987
fbe5eb6d
BS
22988;; Conversions between SF and DF
22989
22990(define_insn "cvtsd2ss"
f56e86bd
JH
22991 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22992 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
fbe5eb6d
BS
22993 (vec_duplicate:V4SF
22994 (float_truncate:V2SF
f56e86bd 22995 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
fbe5eb6d
BS
22996 (const_int 14)))]
22997 "TARGET_SSE2"
22998 "cvtsd2ss\t{%2, %0|%0, %2}"
3d34cd91 22999 [(set_attr "type" "ssecvt")
f56e86bd 23000 (set_attr "athlon_decode" "vector,double")
3d34cd91 23001 (set_attr "mode" "SF")])
fbe5eb6d
BS
23002
23003(define_insn "cvtss2sd"
23004 [(set (match_operand:V2DF 0 "register_operand" "=x")
23005 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23006 (float_extend:V2DF
23007 (vec_select:V2SF
4977bab6 23008 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
fbe5eb6d
BS
23009 (parallel [(const_int 0)
23010 (const_int 1)])))
23011 (const_int 2)))]
23012 "TARGET_SSE2"
23013 "cvtss2sd\t{%2, %0|%0, %2}"
3d34cd91
JH
23014 [(set_attr "type" "ssecvt")
23015 (set_attr "mode" "DF")])
fbe5eb6d
BS
23016
23017(define_insn "cvtpd2ps"
23018 [(set (match_operand:V4SF 0 "register_operand" "=x")
23019 (subreg:V4SF
23020 (vec_concat:V4SI
23021 (subreg:V2SI (float_truncate:V2SF
23022 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23023 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23024 "TARGET_SSE2"
23025 "cvtpd2ps\t{%1, %0|%0, %1}"
3d34cd91
JH
23026 [(set_attr "type" "ssecvt")
23027 (set_attr "mode" "V4SF")])
fbe5eb6d
BS
23028
23029(define_insn "cvtps2pd"
23030 [(set (match_operand:V2DF 0 "register_operand" "=x")
23031 (float_extend:V2DF
23032 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23033 (parallel [(const_int 0)
23034 (const_int 1)]))))]
23035 "TARGET_SSE2"
23036 "cvtps2pd\t{%1, %0|%0, %1}"
3d34cd91
JH
23037 [(set_attr "type" "ssecvt")
23038 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
23039
23040;; SSE2 variants of MMX insns
23041
23042;; MMX arithmetic
23043
23044(define_insn "addv16qi3"
23045 [(set (match_operand:V16QI 0 "register_operand" "=x")
d50672ef 23046 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
fbe5eb6d
BS
23047 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23048 "TARGET_SSE2"
23049 "paddb\t{%2, %0|%0, %2}"
3d34cd91
JH
23050 [(set_attr "type" "sseiadd")
23051 (set_attr "mode" "TI")])
fbe5eb6d
BS
23052
23053(define_insn "addv8hi3"
23054 [(set (match_operand:V8HI 0 "register_operand" "=x")
d50672ef 23055 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
fbe5eb6d
BS
23056 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23057 "TARGET_SSE2"
23058 "paddw\t{%2, %0|%0, %2}"
3d34cd91
JH
23059 [(set_attr "type" "sseiadd")
23060 (set_attr "mode" "TI")])
fbe5eb6d
BS
23061
23062(define_insn "addv4si3"
23063 [(set (match_operand:V4SI 0 "register_operand" "=x")
d50672ef 23064 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
fbe5eb6d
BS
23065 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23066 "TARGET_SSE2"
23067 "paddd\t{%2, %0|%0, %2}"
3d34cd91
JH
23068 [(set_attr "type" "sseiadd")
23069 (set_attr "mode" "TI")])
fbe5eb6d
BS
23070
23071(define_insn "addv2di3"
23072 [(set (match_operand:V2DI 0 "register_operand" "=x")
d50672ef 23073 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
fbe5eb6d
BS
23074 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23075 "TARGET_SSE2"
23076 "paddq\t{%2, %0|%0, %2}"
3d34cd91
JH
23077 [(set_attr "type" "sseiadd")
23078 (set_attr "mode" "TI")])
fbe5eb6d
BS
23079
23080(define_insn "ssaddv16qi3"
23081 [(set (match_operand:V16QI 0 "register_operand" "=x")
d50672ef 23082 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
fbe5eb6d
BS
23083 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23084 "TARGET_SSE2"
23085 "paddsb\t{%2, %0|%0, %2}"
3d34cd91
JH
23086 [(set_attr "type" "sseiadd")
23087 (set_attr "mode" "TI")])
fbe5eb6d
BS
23088
23089(define_insn "ssaddv8hi3"
23090 [(set (match_operand:V8HI 0 "register_operand" "=x")
d50672ef 23091 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
fbe5eb6d
BS
23092 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23093 "TARGET_SSE2"
23094 "paddsw\t{%2, %0|%0, %2}"
3d34cd91
JH
23095 [(set_attr "type" "sseiadd")
23096 (set_attr "mode" "TI")])
fbe5eb6d
BS
23097
23098(define_insn "usaddv16qi3"
23099 [(set (match_operand:V16QI 0 "register_operand" "=x")
d50672ef 23100 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
fbe5eb6d
BS
23101 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23102 "TARGET_SSE2"
23103 "paddusb\t{%2, %0|%0, %2}"
3d34cd91
JH
23104 [(set_attr "type" "sseiadd")
23105 (set_attr "mode" "TI")])
fbe5eb6d
BS
23106
23107(define_insn "usaddv8hi3"
23108 [(set (match_operand:V8HI 0 "register_operand" "=x")
d50672ef 23109 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
fbe5eb6d
BS
23110 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23111 "TARGET_SSE2"
23112 "paddusw\t{%2, %0|%0, %2}"
3d34cd91
JH
23113 [(set_attr "type" "sseiadd")
23114 (set_attr "mode" "TI")])
fbe5eb6d
BS
23115
23116(define_insn "subv16qi3"
23117 [(set (match_operand:V16QI 0 "register_operand" "=x")
23118 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23119 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23120 "TARGET_SSE2"
23121 "psubb\t{%2, %0|%0, %2}"
3d34cd91
JH
23122 [(set_attr "type" "sseiadd")
23123 (set_attr "mode" "TI")])
fbe5eb6d
BS
23124
23125(define_insn "subv8hi3"
23126 [(set (match_operand:V8HI 0 "register_operand" "=x")
23127 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23128 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23129 "TARGET_SSE2"
23130 "psubw\t{%2, %0|%0, %2}"
3d34cd91
JH
23131 [(set_attr "type" "sseiadd")
23132 (set_attr "mode" "TI")])
fbe5eb6d
BS
23133
23134(define_insn "subv4si3"
23135 [(set (match_operand:V4SI 0 "register_operand" "=x")
23136 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23137 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23138 "TARGET_SSE2"
23139 "psubd\t{%2, %0|%0, %2}"
3d34cd91
JH
23140 [(set_attr "type" "sseiadd")
23141 (set_attr "mode" "TI")])
fbe5eb6d
BS
23142
23143(define_insn "subv2di3"
23144 [(set (match_operand:V2DI 0 "register_operand" "=x")
23145 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23146 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23147 "TARGET_SSE2"
23148 "psubq\t{%2, %0|%0, %2}"
3d34cd91
JH
23149 [(set_attr "type" "sseiadd")
23150 (set_attr "mode" "TI")])
fbe5eb6d
BS
23151
23152(define_insn "sssubv16qi3"
23153 [(set (match_operand:V16QI 0 "register_operand" "=x")
23154 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23155 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23156 "TARGET_SSE2"
23157 "psubsb\t{%2, %0|%0, %2}"
3d34cd91
JH
23158 [(set_attr "type" "sseiadd")
23159 (set_attr "mode" "TI")])
fbe5eb6d
BS
23160
23161(define_insn "sssubv8hi3"
23162 [(set (match_operand:V8HI 0 "register_operand" "=x")
23163 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23164 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23165 "TARGET_SSE2"
23166 "psubsw\t{%2, %0|%0, %2}"
3d34cd91
JH
23167 [(set_attr "type" "sseiadd")
23168 (set_attr "mode" "TI")])
fbe5eb6d
BS
23169
23170(define_insn "ussubv16qi3"
23171 [(set (match_operand:V16QI 0 "register_operand" "=x")
23172 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23173 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23174 "TARGET_SSE2"
23175 "psubusb\t{%2, %0|%0, %2}"
3d34cd91
JH
23176 [(set_attr "type" "sseiadd")
23177 (set_attr "mode" "TI")])
fbe5eb6d
BS
23178
23179(define_insn "ussubv8hi3"
23180 [(set (match_operand:V8HI 0 "register_operand" "=x")
23181 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23182 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23183 "TARGET_SSE2"
23184 "psubusw\t{%2, %0|%0, %2}"
3d34cd91
JH
23185 [(set_attr "type" "sseiadd")
23186 (set_attr "mode" "TI")])
fbe5eb6d
BS
23187
23188(define_insn "mulv8hi3"
23189 [(set (match_operand:V8HI 0 "register_operand" "=x")
23190 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23191 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23192 "TARGET_SSE2"
23193 "pmullw\t{%2, %0|%0, %2}"
3d34cd91
JH
23194 [(set_attr "type" "sseimul")
23195 (set_attr "mode" "TI")])
fbe5eb6d
BS
23196
23197(define_insn "smulv8hi3_highpart"
23198 [(set (match_operand:V8HI 0 "register_operand" "=x")
23199 (truncate:V8HI
23200 (lshiftrt:V8SI
23201 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23202 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23203 (const_int 16))))]
23204 "TARGET_SSE2"
23205 "pmulhw\t{%2, %0|%0, %2}"
3d34cd91
JH
23206 [(set_attr "type" "sseimul")
23207 (set_attr "mode" "TI")])
fbe5eb6d
BS
23208
23209(define_insn "umulv8hi3_highpart"
23210 [(set (match_operand:V8HI 0 "register_operand" "=x")
23211 (truncate:V8HI
23212 (lshiftrt:V8SI
23213 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23214 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23215 (const_int 16))))]
23216 "TARGET_SSE2"
23217 "pmulhuw\t{%2, %0|%0, %2}"
3d34cd91
JH
23218 [(set_attr "type" "sseimul")
23219 (set_attr "mode" "TI")])
fbe5eb6d 23220
fbe5eb6d
BS
23221(define_insn "sse2_umulsidi3"
23222 [(set (match_operand:DI 0 "register_operand" "=y")
916b60b7
BS
23223 (mult:DI (zero_extend:DI (vec_select:SI
23224 (match_operand:V2SI 1 "register_operand" "0")
23225 (parallel [(const_int 0)])))
23226 (zero_extend:DI (vec_select:SI
23227 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23228 (parallel [(const_int 0)])))))]
fbe5eb6d
BS
23229 "TARGET_SSE2"
23230 "pmuludq\t{%2, %0|%0, %2}"
9e9fb0ce
JB
23231 [(set_attr "type" "mmxmul")
23232 (set_attr "mode" "DI")])
fbe5eb6d
BS
23233
23234(define_insn "sse2_umulv2siv2di3"
680dd104 23235 [(set (match_operand:V2DI 0 "register_operand" "=x")
fbe5eb6d
BS
23236 (mult:V2DI (zero_extend:V2DI
23237 (vec_select:V2SI
23238 (match_operand:V4SI 1 "register_operand" "0")
23239 (parallel [(const_int 0) (const_int 2)])))
23240 (zero_extend:V2DI
23241 (vec_select:V2SI
680dd104 23242 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
fbe5eb6d
BS
23243 (parallel [(const_int 0) (const_int 2)])))))]
23244 "TARGET_SSE2"
23245 "pmuludq\t{%2, %0|%0, %2}"
3d34cd91
JH
23246 [(set_attr "type" "sseimul")
23247 (set_attr "mode" "TI")])
fbe5eb6d
BS
23248
23249(define_insn "sse2_pmaddwd"
23250 [(set (match_operand:V4SI 0 "register_operand" "=x")
23251 (plus:V4SI
23252 (mult:V4SI
23253 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23254 (parallel [(const_int 0)
23255 (const_int 2)
23256 (const_int 4)
23257 (const_int 6)])))
23258 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23259 (parallel [(const_int 0)
23260 (const_int 2)
23261 (const_int 4)
23262 (const_int 6)]))))
23263 (mult:V4SI
23264 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23265 (parallel [(const_int 1)
23266 (const_int 3)
23267 (const_int 5)
23268 (const_int 7)])))
23269 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23270 (parallel [(const_int 1)
23271 (const_int 3)
23272 (const_int 5)
23273 (const_int 7)]))))))]
23274 "TARGET_SSE2"
23275 "pmaddwd\t{%2, %0|%0, %2}"
3d34cd91
JH
23276 [(set_attr "type" "sseiadd")
23277 (set_attr "mode" "TI")])
fbe5eb6d
BS
23278
23279;; Same as pxor, but don't show input operands so that we don't think
23280;; they are live.
23281(define_insn "sse2_clrti"
23282 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23283 "TARGET_SSE2"
4977bab6
ZW
23284{
23285 if (get_attr_mode (insn) == MODE_TI)
23286 return "pxor\t%0, %0";
23287 else
23288 return "xorps\t%0, %0";
23289}
23290 [(set_attr "type" "ssemov")
19cba4a0 23291 (set_attr "memory" "none")
4977bab6
ZW
23292 (set (attr "mode")
23293 (if_then_else
23294 (ne (symbol_ref "optimize_size")
23295 (const_int 0))
23296 (const_string "V4SF")
23297 (const_string "TI")))])
fbe5eb6d
BS
23298
23299;; MMX unsigned averages/sum of absolute differences
23300
23301(define_insn "sse2_uavgv16qi3"
23302 [(set (match_operand:V16QI 0 "register_operand" "=x")
23303 (ashiftrt:V16QI
23304 (plus:V16QI (plus:V16QI
23305 (match_operand:V16QI 1 "register_operand" "0")
680dd104 23306 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
fbe5eb6d
BS
23307 (const_vector:V16QI [(const_int 1) (const_int 1)
23308 (const_int 1) (const_int 1)
23309 (const_int 1) (const_int 1)
23310 (const_int 1) (const_int 1)
23311 (const_int 1) (const_int 1)
23312 (const_int 1) (const_int 1)
23313 (const_int 1) (const_int 1)
23314 (const_int 1) (const_int 1)]))
23315 (const_int 1)))]
23316 "TARGET_SSE2"
23317 "pavgb\t{%2, %0|%0, %2}"
3d34cd91
JH
23318 [(set_attr "type" "sseiadd")
23319 (set_attr "mode" "TI")])
fbe5eb6d
BS
23320
23321(define_insn "sse2_uavgv8hi3"
23322 [(set (match_operand:V8HI 0 "register_operand" "=x")
23323 (ashiftrt:V8HI
23324 (plus:V8HI (plus:V8HI
23325 (match_operand:V8HI 1 "register_operand" "0")
680dd104 23326 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
fbe5eb6d
BS
23327 (const_vector:V8HI [(const_int 1) (const_int 1)
23328 (const_int 1) (const_int 1)
23329 (const_int 1) (const_int 1)
23330 (const_int 1) (const_int 1)]))
23331 (const_int 1)))]
23332 "TARGET_SSE2"
23333 "pavgw\t{%2, %0|%0, %2}"
3d34cd91
JH
23334 [(set_attr "type" "sseiadd")
23335 (set_attr "mode" "TI")])
fbe5eb6d
BS
23336
23337;; @@@ this isn't the right representation.
23338(define_insn "sse2_psadbw"
916b60b7
BS
23339 [(set (match_operand:V2DI 0 "register_operand" "=x")
23340 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
680dd104 23341 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
8ee41eaf 23342 UNSPEC_PSADBW))]
fbe5eb6d
BS
23343 "TARGET_SSE2"
23344 "psadbw\t{%2, %0|%0, %2}"
3d34cd91
JH
23345 [(set_attr "type" "sseiadd")
23346 (set_attr "mode" "TI")])
fbe5eb6d
BS
23347
23348
23349;; MMX insert/extract/shuffle
23350
23351(define_insn "sse2_pinsrw"
23352 [(set (match_operand:V8HI 0 "register_operand" "=x")
23353 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23354 (vec_duplicate:V8HI
d9deed68
JH
23355 (truncate:HI
23356 (match_operand:SI 2 "nonimmediate_operand" "rm")))
ebe75517 23357 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
fbe5eb6d
BS
23358 "TARGET_SSE2"
23359 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
3d34cd91
JH
23360 [(set_attr "type" "ssecvt")
23361 (set_attr "mode" "TI")])
fbe5eb6d
BS
23362
23363(define_insn "sse2_pextrw"
23364 [(set (match_operand:SI 0 "register_operand" "=r")
23365 (zero_extend:SI
23366 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23367 (parallel
ebe75517 23368 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
fbe5eb6d
BS
23369 "TARGET_SSE2"
23370 "pextrw\t{%2, %1, %0|%0, %1, %2}"
3d34cd91
JH
23371 [(set_attr "type" "ssecvt")
23372 (set_attr "mode" "TI")])
fbe5eb6d
BS
23373
23374(define_insn "sse2_pshufd"
23375 [(set (match_operand:V4SI 0 "register_operand" "=x")
717415ad 23376 (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
8ee41eaf
RH
23377 (match_operand:SI 2 "immediate_operand" "i")]
23378 UNSPEC_SHUFFLE))]
fbe5eb6d
BS
23379 "TARGET_SSE2"
23380 "pshufd\t{%2, %1, %0|%0, %1, %2}"
3d34cd91
JH
23381 [(set_attr "type" "ssecvt")
23382 (set_attr "mode" "TI")])
fbe5eb6d
BS
23383
23384(define_insn "sse2_pshuflw"
23385 [(set (match_operand:V8HI 0 "register_operand" "=x")
717415ad 23386 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
8ee41eaf
RH
23387 (match_operand:SI 2 "immediate_operand" "i")]
23388 UNSPEC_PSHUFLW))]
fbe5eb6d
BS
23389 "TARGET_SSE2"
23390 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
3d34cd91
JH
23391 [(set_attr "type" "ssecvt")
23392 (set_attr "mode" "TI")])
fbe5eb6d
BS
23393
23394(define_insn "sse2_pshufhw"
23395 [(set (match_operand:V8HI 0 "register_operand" "=x")
717415ad 23396 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
8ee41eaf
RH
23397 (match_operand:SI 2 "immediate_operand" "i")]
23398 UNSPEC_PSHUFHW))]
fbe5eb6d
BS
23399 "TARGET_SSE2"
23400 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
3d34cd91
JH
23401 [(set_attr "type" "ssecvt")
23402 (set_attr "mode" "TI")])
fbe5eb6d
BS
23403
23404;; MMX mask-generating comparisons
23405
23406(define_insn "eqv16qi3"
23407 [(set (match_operand:V16QI 0 "register_operand" "=x")
23408 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23409 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23410 "TARGET_SSE2"
23411 "pcmpeqb\t{%2, %0|%0, %2}"
3d34cd91
JH
23412 [(set_attr "type" "ssecmp")
23413 (set_attr "mode" "TI")])
fbe5eb6d
BS
23414
23415(define_insn "eqv8hi3"
23416 [(set (match_operand:V8HI 0 "register_operand" "=x")
23417 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23418 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23419 "TARGET_SSE2"
23420 "pcmpeqw\t{%2, %0|%0, %2}"
3d34cd91
JH
23421 [(set_attr "type" "ssecmp")
23422 (set_attr "mode" "TI")])
fbe5eb6d
BS
23423
23424(define_insn "eqv4si3"
23425 [(set (match_operand:V4SI 0 "register_operand" "=x")
23426 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23427 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23428 "TARGET_SSE2"
23429 "pcmpeqd\t{%2, %0|%0, %2}"
3d34cd91
JH
23430 [(set_attr "type" "ssecmp")
23431 (set_attr "mode" "TI")])
fbe5eb6d
BS
23432
23433(define_insn "gtv16qi3"
23434 [(set (match_operand:V16QI 0 "register_operand" "=x")
23435 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23436 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23437 "TARGET_SSE2"
23438 "pcmpgtb\t{%2, %0|%0, %2}"
3d34cd91
JH
23439 [(set_attr "type" "ssecmp")
23440 (set_attr "mode" "TI")])
fbe5eb6d
BS
23441
23442(define_insn "gtv8hi3"
23443 [(set (match_operand:V8HI 0 "register_operand" "=x")
23444 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23445 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23446 "TARGET_SSE2"
23447 "pcmpgtw\t{%2, %0|%0, %2}"
3d34cd91
JH
23448 [(set_attr "type" "ssecmp")
23449 (set_attr "mode" "TI")])
fbe5eb6d
BS
23450
23451(define_insn "gtv4si3"
23452 [(set (match_operand:V4SI 0 "register_operand" "=x")
23453 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23454 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23455 "TARGET_SSE2"
23456 "pcmpgtd\t{%2, %0|%0, %2}"
3d34cd91
JH
23457 [(set_attr "type" "ssecmp")
23458 (set_attr "mode" "TI")])
fbe5eb6d
BS
23459
23460
23461;; MMX max/min insns
23462
23463(define_insn "umaxv16qi3"
23464 [(set (match_operand:V16QI 0 "register_operand" "=x")
23465 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23466 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23467 "TARGET_SSE2"
23468 "pmaxub\t{%2, %0|%0, %2}"
3d34cd91
JH
23469 [(set_attr "type" "sseiadd")
23470 (set_attr "mode" "TI")])
fbe5eb6d
BS
23471
23472(define_insn "smaxv8hi3"
23473 [(set (match_operand:V8HI 0 "register_operand" "=x")
23474 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23475 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23476 "TARGET_SSE2"
23477 "pmaxsw\t{%2, %0|%0, %2}"
3d34cd91
JH
23478 [(set_attr "type" "sseiadd")
23479 (set_attr "mode" "TI")])
fbe5eb6d
BS
23480
23481(define_insn "uminv16qi3"
23482 [(set (match_operand:V16QI 0 "register_operand" "=x")
23483 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23484 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23485 "TARGET_SSE2"
23486 "pminub\t{%2, %0|%0, %2}"
3d34cd91
JH
23487 [(set_attr "type" "sseiadd")
23488 (set_attr "mode" "TI")])
fbe5eb6d
BS
23489
23490(define_insn "sminv8hi3"
23491 [(set (match_operand:V8HI 0 "register_operand" "=x")
23492 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23493 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23494 "TARGET_SSE2"
23495 "pminsw\t{%2, %0|%0, %2}"
3d34cd91
JH
23496 [(set_attr "type" "sseiadd")
23497 (set_attr "mode" "TI")])
fbe5eb6d
BS
23498
23499
23500;; MMX shifts
23501
23502(define_insn "ashrv8hi3"
23503 [(set (match_operand:V8HI 0 "register_operand" "=x")
23504 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
588f75d0 23505 (match_operand:SI 2 "nonmemory_operand" "xi")))]
fbe5eb6d
BS
23506 "TARGET_SSE2"
23507 "psraw\t{%2, %0|%0, %2}"
3d34cd91
JH
23508 [(set_attr "type" "sseishft")
23509 (set_attr "mode" "TI")])
fbe5eb6d
BS
23510
23511(define_insn "ashrv4si3"
23512 [(set (match_operand:V4SI 0 "register_operand" "=x")
23513 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
588f75d0 23514 (match_operand:SI 2 "nonmemory_operand" "xi")))]
fbe5eb6d
BS
23515 "TARGET_SSE2"
23516 "psrad\t{%2, %0|%0, %2}"
3d34cd91
JH
23517 [(set_attr "type" "sseishft")
23518 (set_attr "mode" "TI")])
fbe5eb6d
BS
23519
23520(define_insn "lshrv8hi3"
23521 [(set (match_operand:V8HI 0 "register_operand" "=x")
23522 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
588f75d0 23523 (match_operand:SI 2 "nonmemory_operand" "xi")))]
fbe5eb6d
BS
23524 "TARGET_SSE2"
23525 "psrlw\t{%2, %0|%0, %2}"
3d34cd91
JH
23526 [(set_attr "type" "sseishft")
23527 (set_attr "mode" "TI")])
fbe5eb6d
BS
23528
23529(define_insn "lshrv4si3"
23530 [(set (match_operand:V4SI 0 "register_operand" "=x")
23531 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
588f75d0 23532 (match_operand:SI 2 "nonmemory_operand" "xi")))]
fbe5eb6d
BS
23533 "TARGET_SSE2"
23534 "psrld\t{%2, %0|%0, %2}"
3d34cd91
JH
23535 [(set_attr "type" "sseishft")
23536 (set_attr "mode" "TI")])
fbe5eb6d 23537
916b60b7 23538(define_insn "lshrv2di3"
fbe5eb6d
BS
23539 [(set (match_operand:V2DI 0 "register_operand" "=x")
23540 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
588f75d0 23541 (match_operand:SI 2 "nonmemory_operand" "xi")))]
fbe5eb6d
BS
23542 "TARGET_SSE2"
23543 "psrlq\t{%2, %0|%0, %2}"
3d34cd91
JH
23544 [(set_attr "type" "sseishft")
23545 (set_attr "mode" "TI")])
fbe5eb6d
BS
23546
23547(define_insn "ashlv8hi3"
23548 [(set (match_operand:V8HI 0 "register_operand" "=x")
23549 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
588f75d0 23550 (match_operand:SI 2 "nonmemory_operand" "xi")))]
fbe5eb6d
BS
23551 "TARGET_SSE2"
23552 "psllw\t{%2, %0|%0, %2}"
3d34cd91
JH
23553 [(set_attr "type" "sseishft")
23554 (set_attr "mode" "TI")])
fbe5eb6d
BS
23555
23556(define_insn "ashlv4si3"
23557 [(set (match_operand:V4SI 0 "register_operand" "=x")
23558 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
588f75d0 23559 (match_operand:SI 2 "nonmemory_operand" "xi")))]
916b60b7
BS
23560 "TARGET_SSE2"
23561 "pslld\t{%2, %0|%0, %2}"
5f90a099
JH
23562 [(set_attr "type" "sseishft")
23563 (set_attr "mode" "TI")])
916b60b7
BS
23564
23565(define_insn "ashlv2di3"
23566 [(set (match_operand:V2DI 0 "register_operand" "=x")
23567 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
588f75d0 23568 (match_operand:SI 2 "nonmemory_operand" "xi")))]
916b60b7
BS
23569 "TARGET_SSE2"
23570 "psllq\t{%2, %0|%0, %2}"
5f90a099
JH
23571 [(set_attr "type" "sseishft")
23572 (set_attr "mode" "TI")])
916b60b7
BS
23573
23574(define_insn "ashrv8hi3_ti"
23575 [(set (match_operand:V8HI 0 "register_operand" "=x")
23576 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
588f75d0 23577 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
916b60b7
BS
23578 "TARGET_SSE2"
23579 "psraw\t{%2, %0|%0, %2}"
5f90a099
JH
23580 [(set_attr "type" "sseishft")
23581 (set_attr "mode" "TI")])
916b60b7
BS
23582
23583(define_insn "ashrv4si3_ti"
23584 [(set (match_operand:V4SI 0 "register_operand" "=x")
23585 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
588f75d0 23586 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
916b60b7
BS
23587 "TARGET_SSE2"
23588 "psrad\t{%2, %0|%0, %2}"
5f90a099
JH
23589 [(set_attr "type" "sseishft")
23590 (set_attr "mode" "TI")])
916b60b7
BS
23591
23592(define_insn "lshrv8hi3_ti"
23593 [(set (match_operand:V8HI 0 "register_operand" "=x")
23594 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
588f75d0 23595 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
916b60b7
BS
23596 "TARGET_SSE2"
23597 "psrlw\t{%2, %0|%0, %2}"
5f90a099
JH
23598 [(set_attr "type" "sseishft")
23599 (set_attr "mode" "TI")])
916b60b7
BS
23600
23601(define_insn "lshrv4si3_ti"
23602 [(set (match_operand:V4SI 0 "register_operand" "=x")
23603 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
588f75d0 23604 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
916b60b7
BS
23605 "TARGET_SSE2"
23606 "psrld\t{%2, %0|%0, %2}"
5f90a099
JH
23607 [(set_attr "type" "sseishft")
23608 (set_attr "mode" "TI")])
916b60b7
BS
23609
23610(define_insn "lshrv2di3_ti"
23611 [(set (match_operand:V2DI 0 "register_operand" "=x")
23612 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
588f75d0 23613 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
916b60b7
BS
23614 "TARGET_SSE2"
23615 "psrlq\t{%2, %0|%0, %2}"
5f90a099
JH
23616 [(set_attr "type" "sseishft")
23617 (set_attr "mode" "TI")])
916b60b7
BS
23618
23619(define_insn "ashlv8hi3_ti"
23620 [(set (match_operand:V8HI 0 "register_operand" "=x")
23621 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
588f75d0 23622 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
916b60b7
BS
23623 "TARGET_SSE2"
23624 "psllw\t{%2, %0|%0, %2}"
5f90a099
JH
23625 [(set_attr "type" "sseishft")
23626 (set_attr "mode" "TI")])
916b60b7
BS
23627
23628(define_insn "ashlv4si3_ti"
23629 [(set (match_operand:V4SI 0 "register_operand" "=x")
23630 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
588f75d0 23631 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
fbe5eb6d
BS
23632 "TARGET_SSE2"
23633 "pslld\t{%2, %0|%0, %2}"
3d34cd91
JH
23634 [(set_attr "type" "sseishft")
23635 (set_attr "mode" "TI")])
fbe5eb6d 23636
916b60b7 23637(define_insn "ashlv2di3_ti"
fbe5eb6d
BS
23638 [(set (match_operand:V2DI 0 "register_operand" "=x")
23639 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
588f75d0 23640 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
fbe5eb6d
BS
23641 "TARGET_SSE2"
23642 "psllq\t{%2, %0|%0, %2}"
3d34cd91
JH
23643 [(set_attr "type" "sseishft")
23644 (set_attr "mode" "TI")])
fbe5eb6d
BS
23645
23646;; See logical MMX insns for the reason for the unspec. Strictly speaking
23647;; we wouldn't need here it since we never generate TImode arithmetic.
23648
23649;; There has to be some kind of prize for the weirdest new instruction...
23650(define_insn "sse2_ashlti3"
23651 [(set (match_operand:TI 0 "register_operand" "=x")
23652 (unspec:TI
23653 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23654 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
8ee41eaf 23655 (const_int 8)))] UNSPEC_NOP))]
fbe5eb6d
BS
23656 "TARGET_SSE2"
23657 "pslldq\t{%2, %0|%0, %2}"
3d34cd91
JH
23658 [(set_attr "type" "sseishft")
23659 (set_attr "mode" "TI")])
fbe5eb6d
BS
23660
23661(define_insn "sse2_lshrti3"
23662 [(set (match_operand:TI 0 "register_operand" "=x")
23663 (unspec:TI
23664 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23665 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
8ee41eaf 23666 (const_int 8)))] UNSPEC_NOP))]
fbe5eb6d 23667 "TARGET_SSE2"
680dd104 23668 "psrldq\t{%2, %0|%0, %2}"
3d34cd91
JH
23669 [(set_attr "type" "sseishft")
23670 (set_attr "mode" "TI")])
fbe5eb6d
BS
23671
23672;; SSE unpack
23673
23674(define_insn "sse2_unpckhpd"
23675 [(set (match_operand:V2DF 0 "register_operand" "=x")
23676 (vec_concat:V2DF
26771da7
JH
23677 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23678 (parallel [(const_int 1)]))
23679 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
997404de 23680 (parallel [(const_int 1)]))))]
fbe5eb6d
BS
23681 "TARGET_SSE2"
23682 "unpckhpd\t{%2, %0|%0, %2}"
3d34cd91 23683 [(set_attr "type" "ssecvt")
997404de 23684 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
23685
23686(define_insn "sse2_unpcklpd"
23687 [(set (match_operand:V2DF 0 "register_operand" "=x")
23688 (vec_concat:V2DF
26771da7
JH
23689 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23690 (parallel [(const_int 0)]))
23691 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
997404de 23692 (parallel [(const_int 0)]))))]
fbe5eb6d
BS
23693 "TARGET_SSE2"
23694 "unpcklpd\t{%2, %0|%0, %2}"
3d34cd91 23695 [(set_attr "type" "ssecvt")
997404de 23696 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
23697
23698;; MMX pack/unpack insns.
23699
23700(define_insn "sse2_packsswb"
23701 [(set (match_operand:V16QI 0 "register_operand" "=x")
23702 (vec_concat:V16QI
23703 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23704 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23705 "TARGET_SSE2"
23706 "packsswb\t{%2, %0|%0, %2}"
3d34cd91
JH
23707 [(set_attr "type" "ssecvt")
23708 (set_attr "mode" "TI")])
fbe5eb6d
BS
23709
23710(define_insn "sse2_packssdw"
23711 [(set (match_operand:V8HI 0 "register_operand" "=x")
23712 (vec_concat:V8HI
23713 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23714 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23715 "TARGET_SSE2"
23716 "packssdw\t{%2, %0|%0, %2}"
3d34cd91
JH
23717 [(set_attr "type" "ssecvt")
23718 (set_attr "mode" "TI")])
fbe5eb6d
BS
23719
23720(define_insn "sse2_packuswb"
23721 [(set (match_operand:V16QI 0 "register_operand" "=x")
23722 (vec_concat:V16QI
23723 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23724 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23725 "TARGET_SSE2"
23726 "packuswb\t{%2, %0|%0, %2}"
3d34cd91
JH
23727 [(set_attr "type" "ssecvt")
23728 (set_attr "mode" "TI")])
fbe5eb6d
BS
23729
23730(define_insn "sse2_punpckhbw"
23731 [(set (match_operand:V16QI 0 "register_operand" "=x")
23732 (vec_merge:V16QI
23733 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23734 (parallel [(const_int 8) (const_int 0)
23735 (const_int 9) (const_int 1)
23736 (const_int 10) (const_int 2)
23737 (const_int 11) (const_int 3)
23738 (const_int 12) (const_int 4)
23739 (const_int 13) (const_int 5)
23740 (const_int 14) (const_int 6)
23741 (const_int 15) (const_int 7)]))
23742 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23743 (parallel [(const_int 0) (const_int 8)
23744 (const_int 1) (const_int 9)
23745 (const_int 2) (const_int 10)
23746 (const_int 3) (const_int 11)
23747 (const_int 4) (const_int 12)
23748 (const_int 5) (const_int 13)
23749 (const_int 6) (const_int 14)
23750 (const_int 7) (const_int 15)]))
23751 (const_int 21845)))]
23752 "TARGET_SSE2"
23753 "punpckhbw\t{%2, %0|%0, %2}"
3d34cd91
JH
23754 [(set_attr "type" "ssecvt")
23755 (set_attr "mode" "TI")])
fbe5eb6d
BS
23756
23757(define_insn "sse2_punpckhwd"
23758 [(set (match_operand:V8HI 0 "register_operand" "=x")
23759 (vec_merge:V8HI
23760 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23761 (parallel [(const_int 4) (const_int 0)
23762 (const_int 5) (const_int 1)
23763 (const_int 6) (const_int 2)
23764 (const_int 7) (const_int 3)]))
23765 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23766 (parallel [(const_int 0) (const_int 4)
23767 (const_int 1) (const_int 5)
23768 (const_int 2) (const_int 6)
23769 (const_int 3) (const_int 7)]))
23770 (const_int 85)))]
23771 "TARGET_SSE2"
23772 "punpckhwd\t{%2, %0|%0, %2}"
3d34cd91
JH
23773 [(set_attr "type" "ssecvt")
23774 (set_attr "mode" "TI")])
fbe5eb6d
BS
23775
23776(define_insn "sse2_punpckhdq"
23777 [(set (match_operand:V4SI 0 "register_operand" "=x")
23778 (vec_merge:V4SI
23779 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23780 (parallel [(const_int 2) (const_int 0)
23781 (const_int 3) (const_int 1)]))
23782 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23783 (parallel [(const_int 0) (const_int 2)
23784 (const_int 1) (const_int 3)]))
23785 (const_int 5)))]
23786 "TARGET_SSE2"
23787 "punpckhdq\t{%2, %0|%0, %2}"
3d34cd91
JH
23788 [(set_attr "type" "ssecvt")
23789 (set_attr "mode" "TI")])
fbe5eb6d
BS
23790
23791(define_insn "sse2_punpcklbw"
23792 [(set (match_operand:V16QI 0 "register_operand" "=x")
23793 (vec_merge:V16QI
23794 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23795 (parallel [(const_int 0) (const_int 8)
23796 (const_int 1) (const_int 9)
23797 (const_int 2) (const_int 10)
23798 (const_int 3) (const_int 11)
23799 (const_int 4) (const_int 12)
23800 (const_int 5) (const_int 13)
23801 (const_int 6) (const_int 14)
23802 (const_int 7) (const_int 15)]))
23803 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23804 (parallel [(const_int 8) (const_int 0)
23805 (const_int 9) (const_int 1)
23806 (const_int 10) (const_int 2)
23807 (const_int 11) (const_int 3)
23808 (const_int 12) (const_int 4)
23809 (const_int 13) (const_int 5)
23810 (const_int 14) (const_int 6)
23811 (const_int 15) (const_int 7)]))
23812 (const_int 21845)))]
23813 "TARGET_SSE2"
23814 "punpcklbw\t{%2, %0|%0, %2}"
3d34cd91
JH
23815 [(set_attr "type" "ssecvt")
23816 (set_attr "mode" "TI")])
fbe5eb6d
BS
23817
23818(define_insn "sse2_punpcklwd"
23819 [(set (match_operand:V8HI 0 "register_operand" "=x")
23820 (vec_merge:V8HI
23821 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23822 (parallel [(const_int 0) (const_int 4)
23823 (const_int 1) (const_int 5)
23824 (const_int 2) (const_int 6)
23825 (const_int 3) (const_int 7)]))
23826 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23827 (parallel [(const_int 4) (const_int 0)
23828 (const_int 5) (const_int 1)
23829 (const_int 6) (const_int 2)
23830 (const_int 7) (const_int 3)]))
23831 (const_int 85)))]
23832 "TARGET_SSE2"
23833 "punpcklwd\t{%2, %0|%0, %2}"
3d34cd91
JH
23834 [(set_attr "type" "ssecvt")
23835 (set_attr "mode" "TI")])
fbe5eb6d
BS
23836
23837(define_insn "sse2_punpckldq"
23838 [(set (match_operand:V4SI 0 "register_operand" "=x")
23839 (vec_merge:V4SI
23840 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23841 (parallel [(const_int 0) (const_int 2)
23842 (const_int 1) (const_int 3)]))
23843 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23844 (parallel [(const_int 2) (const_int 0)
23845 (const_int 3) (const_int 1)]))
23846 (const_int 5)))]
23847 "TARGET_SSE2"
23848 "punpckldq\t{%2, %0|%0, %2}"
3d34cd91
JH
23849 [(set_attr "type" "ssecvt")
23850 (set_attr "mode" "TI")])
fbe5eb6d 23851
f02e1358
JH
23852(define_insn "sse2_punpcklqdq"
23853 [(set (match_operand:V2DI 0 "register_operand" "=x")
23854 (vec_merge:V2DI
f02e1358
JH
23855 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23856 (parallel [(const_int 1)
23857 (const_int 0)]))
077084dd 23858 (match_operand:V2DI 1 "register_operand" "0")
f02e1358
JH
23859 (const_int 1)))]
23860 "TARGET_SSE2"
23861 "punpcklqdq\t{%2, %0|%0, %2}"
23862 [(set_attr "type" "ssecvt")
23863 (set_attr "mode" "TI")])
077084dd
JH
23864
23865(define_insn "sse2_punpckhqdq"
23866 [(set (match_operand:V2DI 0 "register_operand" "=x")
23867 (vec_merge:V2DI
23868 (match_operand:V2DI 1 "register_operand" "0")
23869 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23870 (parallel [(const_int 1)
23871 (const_int 0)]))
23872 (const_int 1)))]
23873 "TARGET_SSE2"
23874 "punpckhqdq\t{%2, %0|%0, %2}"
23875 [(set_attr "type" "ssecvt")
23876 (set_attr "mode" "TI")])
f02e1358 23877
fbe5eb6d
BS
23878;; SSE2 moves
23879
23880(define_insn "sse2_movapd"
23881 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
7f0e57bd 23882 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
8ee41eaf 23883 UNSPEC_MOVA))]
7f0e57bd
JH
23884 "TARGET_SSE2
23885 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23886 "movapd\t{%1, %0|%0, %1}"
3d34cd91
JH
23887 [(set_attr "type" "ssemov")
23888 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
23889
23890(define_insn "sse2_movupd"
23891 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
7f0e57bd 23892 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
8ee41eaf 23893 UNSPEC_MOVU))]
7f0e57bd
JH
23894 "TARGET_SSE2
23895 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23896 "movupd\t{%1, %0|%0, %1}"
3d34cd91
JH
23897 [(set_attr "type" "ssecvt")
23898 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
23899
23900(define_insn "sse2_movdqa"
f02e1358 23901 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
7f0e57bd 23902 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
f02e1358 23903 UNSPEC_MOVA))]
7f0e57bd
JH
23904 "TARGET_SSE2
23905 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23906 "movdqa\t{%1, %0|%0, %1}"
3d34cd91
JH
23907 [(set_attr "type" "ssemov")
23908 (set_attr "mode" "TI")])
fbe5eb6d
BS
23909
23910(define_insn "sse2_movdqu"
f02e1358 23911 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
7f0e57bd 23912 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
f02e1358 23913 UNSPEC_MOVU))]
7f0e57bd
JH
23914 "TARGET_SSE2
23915 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23916 "movdqu\t{%1, %0|%0, %1}"
3d34cd91
JH
23917 [(set_attr "type" "ssecvt")
23918 (set_attr "mode" "TI")])
fbe5eb6d
BS
23919
23920(define_insn "sse2_movdq2q"
f02e1358
JH
23921 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23922 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
fbe5eb6d 23923 (parallel [(const_int 0)])))]
453ee231 23924 "TARGET_SSE2 && !TARGET_64BIT"
f02e1358
JH
23925 "@
23926 movq\t{%1, %0|%0, %1}
23927 movdq2q\t{%1, %0|%0, %1}"
3d34cd91
JH
23928 [(set_attr "type" "ssecvt")
23929 (set_attr "mode" "TI")])
fbe5eb6d 23930
453ee231
JH
23931(define_insn "sse2_movdq2q_rex64"
23932 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23933 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23934 (parallel [(const_int 0)])))]
23935 "TARGET_SSE2 && TARGET_64BIT"
23936 "@
23937 movq\t{%1, %0|%0, %1}
23938 movdq2q\t{%1, %0|%0, %1}
1c4a429a 23939 movd\t{%1, %0|%0, %1}"
453ee231
JH
23940 [(set_attr "type" "ssecvt")
23941 (set_attr "mode" "TI")])
23942
fbe5eb6d 23943(define_insn "sse2_movq2dq"
f02e1358
JH
23944 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23945 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23946 (const_int 0)))]
453ee231 23947 "TARGET_SSE2 && !TARGET_64BIT"
f02e1358
JH
23948 "@
23949 movq\t{%1, %0|%0, %1}
23950 movq2dq\t{%1, %0|%0, %1}"
23951 [(set_attr "type" "ssecvt,ssemov")
23952 (set_attr "mode" "TI")])
23953
453ee231
JH
23954(define_insn "sse2_movq2dq_rex64"
23955 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23956 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23957 (const_int 0)))]
23958 "TARGET_SSE2 && TARGET_64BIT"
23959 "@
23960 movq\t{%1, %0|%0, %1}
23961 movq2dq\t{%1, %0|%0, %1}
1c4a429a 23962 movd\t{%1, %0|%0, %1}"
453ee231
JH
23963 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23964 (set_attr "mode" "TI")])
23965
f02e1358
JH
23966(define_insn "sse2_movq"
23967 [(set (match_operand:V2DI 0 "register_operand" "=x")
23968 (vec_concat:V2DI (vec_select:DI
23969 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23970 (parallel [(const_int 0)]))
23971 (const_int 0)))]
23972 "TARGET_SSE2"
23973 "movq\t{%1, %0|%0, %1}"
23974 [(set_attr "type" "ssemov")
23975 (set_attr "mode" "TI")])
23976
23977(define_insn "sse2_loadd"
23978 [(set (match_operand:V4SI 0 "register_operand" "=x")
23979 (vec_merge:V4SI
d9deed68 23980 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
f02e1358
JH
23981 (const_vector:V4SI [(const_int 0)
23982 (const_int 0)
23983 (const_int 0)
23984 (const_int 0)])
23985 (const_int 1)))]
23986 "TARGET_SSE2"
23987 "movd\t{%1, %0|%0, %1}"
23988 [(set_attr "type" "ssemov")
23989 (set_attr "mode" "TI")])
23990
23991(define_insn "sse2_stored"
23992 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23993 (vec_select:SI
23994 (match_operand:V4SI 1 "register_operand" "x")
23995 (parallel [(const_int 0)])))]
23996 "TARGET_SSE2"
23997 "movd\t{%1, %0|%0, %1}"
23998 [(set_attr "type" "ssemov")
3d34cd91 23999 (set_attr "mode" "TI")])
fbe5eb6d
BS
24000
24001(define_insn "sse2_movhpd"
24002 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24003 (vec_merge:V2DF
24004 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24005 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
4049b376 24006 (const_int 1)))]
fbe5eb6d
BS
24007 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24008 "movhpd\t{%2, %0|%0, %2}"
3d34cd91
JH
24009 [(set_attr "type" "ssecvt")
24010 (set_attr "mode" "V2DF")])
fbe5eb6d 24011
4977bab6
ZW
24012(define_expand "sse2_loadsd"
24013 [(match_operand:V2DF 0 "register_operand" "")
24014 (match_operand:DF 1 "memory_operand" "")]
24015 "TARGET_SSE2"
24016{
24017 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24018 CONST0_RTX (V2DFmode)));
24019 DONE;
24020})
24021
24022(define_insn "sse2_loadsd_1"
fbe5eb6d
BS
24023 [(set (match_operand:V2DF 0 "register_operand" "=x")
24024 (vec_merge:V2DF
4977bab6
ZW
24025 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24026 (match_operand:V2DF 2 "const0_operand" "X")
fbe5eb6d
BS
24027 (const_int 1)))]
24028 "TARGET_SSE2"
24029 "movsd\t{%1, %0|%0, %1}"
3d34cd91
JH
24030 [(set_attr "type" "ssecvt")
24031 (set_attr "mode" "DF")])
fbe5eb6d
BS
24032
24033(define_insn "sse2_movsd"
997404de 24034 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
fbe5eb6d 24035 (vec_merge:V2DF
997404de
JH
24036 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24037 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
4049b376 24038 (const_int 2)))]
997404de
JH
24039 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24040 "@movsd\t{%2, %0|%0, %2}
24041 movlpd\t{%2, %0|%0, %2}
24042 movlpd\t{%2, %0|%0, %2}"
3d34cd91 24043 [(set_attr "type" "ssecvt")
997404de 24044 (set_attr "mode" "DF,V2DF,V2DF")])
fbe5eb6d
BS
24045
24046(define_insn "sse2_storesd"
24047 [(set (match_operand:DF 0 "memory_operand" "=m")
24048 (vec_select:DF
24049 (match_operand:V2DF 1 "register_operand" "x")
24050 (parallel [(const_int 0)])))]
24051 "TARGET_SSE2"
24052 "movsd\t{%1, %0|%0, %1}"
3d34cd91
JH
24053 [(set_attr "type" "ssecvt")
24054 (set_attr "mode" "DF")])
fbe5eb6d
BS
24055
24056(define_insn "sse2_shufpd"
24057 [(set (match_operand:V2DF 0 "register_operand" "=x")
24058 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24059 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
8ee41eaf
RH
24060 (match_operand:SI 3 "immediate_operand" "i")]
24061 UNSPEC_SHUFFLE))]
fbe5eb6d
BS
24062 "TARGET_SSE2"
24063 ;; @@@ check operand order for intel/nonintel syntax
24064 "shufpd\t{%3, %2, %0|%0, %2, %3}"
3d34cd91
JH
24065 [(set_attr "type" "ssecvt")
24066 (set_attr "mode" "V2DF")])
fbe5eb6d
BS
24067
24068(define_insn "sse2_clflush"
1194ca05 24069 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
8ee41eaf 24070 UNSPECV_CLFLUSH)]
fbe5eb6d 24071 "TARGET_SSE2"
946e316c 24072 "clflush\t%a0"
3d34cd91
JH
24073 [(set_attr "type" "sse")
24074 (set_attr "memory" "unknown")])
fbe5eb6d
BS
24075
24076(define_expand "sse2_mfence"
24077 [(set (match_dup 0)
8ee41eaf 24078 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
fbe5eb6d
BS
24079 "TARGET_SSE2"
24080{
24081 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24082 MEM_VOLATILE_P (operands[0]) = 1;
24083})
24084
24085(define_insn "*mfence_insn"
24086 [(set (match_operand:BLK 0 "" "")
8ee41eaf 24087 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
fbe5eb6d
BS
24088 "TARGET_SSE2"
24089 "mfence"
24090 [(set_attr "type" "sse")
24091 (set_attr "memory" "unknown")])
24092
24093(define_expand "sse2_lfence"
24094 [(set (match_dup 0)
8ee41eaf 24095 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
fbe5eb6d
BS
24096 "TARGET_SSE2"
24097{
24098 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24099 MEM_VOLATILE_P (operands[0]) = 1;
24100})
24101
24102(define_insn "*lfence_insn"
24103 [(set (match_operand:BLK 0 "" "")
8ee41eaf 24104 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
fbe5eb6d
BS
24105 "TARGET_SSE2"
24106 "lfence"
24107 [(set_attr "type" "sse")
24108 (set_attr "memory" "unknown")])
22c7c85e 24109
9e200aaf 24110;; SSE3
22c7c85e
L
24111
24112(define_insn "mwait"
24113 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24114 (match_operand:SI 1 "register_operand" "c")]
24115 UNSPECV_MWAIT)]
9e200aaf 24116 "TARGET_SSE3"
22c7c85e
L
24117 "mwait\t%0, %1"
24118 [(set_attr "length" "3")])
24119
24120(define_insn "monitor"
24121 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24122 (match_operand:SI 1 "register_operand" "c")
24123 (match_operand:SI 2 "register_operand" "d")]
24124 UNSPECV_MONITOR)]
9e200aaf 24125 "TARGET_SSE3"
22c7c85e
L
24126 "monitor\t%0, %1, %2"
24127 [(set_attr "length" "3")])
24128
9e200aaf 24129;; SSE3 arithmetic
22c7c85e
L
24130
24131(define_insn "addsubv4sf3"
24132 [(set (match_operand:V4SF 0 "register_operand" "=x")
24133 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24134 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24135 UNSPEC_ADDSUB))]
9e200aaf 24136 "TARGET_SSE3"
22c7c85e
L
24137 "addsubps\t{%2, %0|%0, %2}"
24138 [(set_attr "type" "sseadd")
24139 (set_attr "mode" "V4SF")])
24140
24141(define_insn "addsubv2df3"
24142 [(set (match_operand:V2DF 0 "register_operand" "=x")
24143 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24144 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24145 UNSPEC_ADDSUB))]
9e200aaf 24146 "TARGET_SSE3"
22c7c85e
L
24147 "addsubpd\t{%2, %0|%0, %2}"
24148 [(set_attr "type" "sseadd")
24149 (set_attr "mode" "V2DF")])
24150
24151(define_insn "haddv4sf3"
24152 [(set (match_operand:V4SF 0 "register_operand" "=x")
24153 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24154 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24155 UNSPEC_HADD))]
9e200aaf 24156 "TARGET_SSE3"
22c7c85e
L
24157 "haddps\t{%2, %0|%0, %2}"
24158 [(set_attr "type" "sseadd")
24159 (set_attr "mode" "V4SF")])
24160
24161(define_insn "haddv2df3"
24162 [(set (match_operand:V2DF 0 "register_operand" "=x")
24163 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24164 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24165 UNSPEC_HADD))]
9e200aaf 24166 "TARGET_SSE3"
22c7c85e
L
24167 "haddpd\t{%2, %0|%0, %2}"
24168 [(set_attr "type" "sseadd")
24169 (set_attr "mode" "V2DF")])
24170
24171(define_insn "hsubv4sf3"
24172 [(set (match_operand:V4SF 0 "register_operand" "=x")
24173 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24174 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24175 UNSPEC_HSUB))]
9e200aaf 24176 "TARGET_SSE3"
22c7c85e
L
24177 "hsubps\t{%2, %0|%0, %2}"
24178 [(set_attr "type" "sseadd")
24179 (set_attr "mode" "V4SF")])
24180
24181(define_insn "hsubv2df3"
24182 [(set (match_operand:V2DF 0 "register_operand" "=x")
24183 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24184 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24185 UNSPEC_HSUB))]
9e200aaf 24186 "TARGET_SSE3"
22c7c85e
L
24187 "hsubpd\t{%2, %0|%0, %2}"
24188 [(set_attr "type" "sseadd")
24189 (set_attr "mode" "V2DF")])
24190
24191(define_insn "movshdup"
24192 [(set (match_operand:V4SF 0 "register_operand" "=x")
24193 (unspec:V4SF
24194 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
9e200aaf 24195 "TARGET_SSE3"
22c7c85e
L
24196 "movshdup\t{%1, %0|%0, %1}"
24197 [(set_attr "type" "sse")
24198 (set_attr "mode" "V4SF")])
24199
24200(define_insn "movsldup"
24201 [(set (match_operand:V4SF 0 "register_operand" "=x")
24202 (unspec:V4SF
24203 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
9e200aaf 24204 "TARGET_SSE3"
22c7c85e
L
24205 "movsldup\t{%1, %0|%0, %1}"
24206 [(set_attr "type" "sse")
24207 (set_attr "mode" "V4SF")])
24208
24209(define_insn "lddqu"
24210 [(set (match_operand:V16QI 0 "register_operand" "=x")
24211 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24212 UNSPEC_LDQQU))]
9e200aaf 24213 "TARGET_SSE3"
22c7c85e
L
24214 "lddqu\t{%1, %0|%0, %1}"
24215 [(set_attr "type" "ssecvt")
24216 (set_attr "mode" "TI")])
24217
24218(define_insn "loadddup"
24219 [(set (match_operand:V2DF 0 "register_operand" "=x")
24220 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
9e200aaf 24221 "TARGET_SSE3"
22c7c85e
L
24222 "movddup\t{%1, %0|%0, %1}"
24223 [(set_attr "type" "ssecvt")
24224 (set_attr "mode" "DF")])
24225
24226(define_insn "movddup"
24227 [(set (match_operand:V2DF 0 "register_operand" "=x")
24228 (vec_duplicate:V2DF
24229 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24230 (parallel [(const_int 0)]))))]
9e200aaf 24231 "TARGET_SSE3"
22c7c85e
L
24232 "movddup\t{%1, %0|%0, %1}"
24233 [(set_attr "type" "ssecvt")
24234 (set_attr "mode" "DF")])
This page took 6.836096 seconds and 5 git commands to generate.