]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.md
re PR target/19009 (Loading of FP constants into FP reg via SSE reg)
[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,
2cdb3148 3;; 2001, 2002, 2003, 2004, 2005
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)
ef719a44 87 (UNSPEC_FIX_NOTRUNC 31)
8ee41eaf
RH
88 (UNSPEC_MASKMOV 32)
89 (UNSPEC_MOVMSK 33)
90 (UNSPEC_MOVNT 34)
91 (UNSPEC_MOVA 38)
92 (UNSPEC_MOVU 39)
93 (UNSPEC_SHUFFLE 41)
94 (UNSPEC_RCP 42)
95 (UNSPEC_RSQRT 43)
96 (UNSPEC_SFENCE 44)
97 (UNSPEC_NOP 45) ; prevents combiner cleverness
98 (UNSPEC_PAVGUSB 49)
99 (UNSPEC_PFRCP 50)
100 (UNSPEC_PFRCPIT1 51)
101 (UNSPEC_PFRCPIT2 52)
102 (UNSPEC_PFRSQRT 53)
103 (UNSPEC_PFRSQIT1 54)
104 (UNSPEC_PSHUFLW 55)
105 (UNSPEC_PSHUFHW 56)
106 (UNSPEC_MFENCE 59)
107 (UNSPEC_LFENCE 60)
108 (UNSPEC_PSADBW 61)
22c7c85e
L
109 (UNSPEC_ADDSUB 71)
110 (UNSPEC_HADD 72)
111 (UNSPEC_HSUB 73)
112 (UNSPEC_MOVSHDUP 74)
113 (UNSPEC_MOVSLDUP 75)
114 (UNSPEC_LDQQU 76)
115 (UNSPEC_MOVDDUP 77)
1fb54135
RS
116
117 ; x87 Floating point
118 (UNSPEC_FPATAN 65)
358997e2 119 (UNSPEC_FYL2X 66)
c2fcfa4f 120 (UNSPEC_FYL2XP1 67)
9d5b9dae
RS
121 (UNSPEC_FRNDINT 68)
122 (UNSPEC_F2XM1 69)
253c7a00 123
a072d43b 124 ; x87 Double output FP
6c7cf1f0
UB
125 (UNSPEC_SINCOS_COS 80)
126 (UNSPEC_SINCOS_SIN 81)
a072d43b
UB
127 (UNSPEC_TAN_ONE 82)
128 (UNSPEC_TAN_TAN 83)
88b28a31
UB
129 (UNSPEC_XTRACT_FRACT 84)
130 (UNSPEC_XTRACT_EXP 85)
f964bd29
UB
131 (UNSPEC_FSCALE_FRACT 86)
132 (UNSPEC_FSCALE_EXP 87)
5ae27cfa
UB
133 (UNSPEC_FPREM_F 88)
134 (UNSPEC_FPREM_U 89)
135 (UNSPEC_FPREM1_F 90)
136 (UNSPEC_FPREM1_U 91)
6c7cf1f0 137
edeacc14
UB
138 ; x87 Rounding
139 (UNSPEC_FRNDINT_FLOOR 96)
140 (UNSPEC_FRNDINT_CEIL 97)
141 (UNSPEC_FRNDINT_TRUNC 98)
142 (UNSPEC_FRNDINT_MASK_PM 99)
143
253c7a00 144 ; REP instruction
9d5b9dae 145 (UNSPEC_REP 75)
2e2052b1
JH
146
147 (UNSPEC_EH_RETURN 76)
8ee41eaf
RH
148 ])
149
150(define_constants
151 [(UNSPECV_BLOCKAGE 0)
8e2cd6dd 152 (UNSPECV_STACK_PROBE 10)
8ee41eaf
RH
153 (UNSPECV_EMMS 31)
154 (UNSPECV_LDMXCSR 37)
155 (UNSPECV_STMXCSR 40)
156 (UNSPECV_FEMMS 46)
157 (UNSPECV_CLFLUSH 57)
d2c49530 158 (UNSPECV_ALIGN 68)
22c7c85e
L
159 (UNSPECV_MONITOR 69)
160 (UNSPECV_MWAIT 70)
8ee41eaf 161 ])
915119a5 162
8bc527af
SB
163;; Registers by name.
164(define_constants
165 [(BP_REG 6)
166 (SP_REG 7)
167 (FLAGS_REG 17)
168 (FPSR_REG 18)
169 (DIRFLAG_REG 19)
170 ])
171
6343a50e
ZW
172;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
173;; from i386.c.
174
1b0c37d7
ZW
175;; In C guard expressions, put expressions which may be compile-time
176;; constants first. This allows for better optimization. For
177;; example, write "TARGET_64BIT && reload_completed", not
178;; "reload_completed && TARGET_64BIT".
179
2ae0f82c 180\f
e075ae69
RH
181;; Processor type. This attribute must exactly match the processor_type
182;; enumeration in i386.h.
89c43c0a 183(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
9e555526 184 (const (symbol_ref "ix86_tune")))
2ae0f82c 185
e075ae69
RH
186;; A basic instruction type. Refinements due to arguments to be
187;; provided in other attributes.
a269a03c 188(define_attr "type"
9a5834ae
ZW
189 "other,multi,
190 alu,alu1,negnot,imov,imovx,lea,
1b245ade 191 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
9a5834ae 192 icmp,test,ibr,setcc,icmov,
4977bab6 193 push,pop,call,callv,leave,
9a5834ae 194 str,cld,
edeacc14 195 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
ef719a44 196 sselog,sselog1,sseiadd,sseishft,sseimul,
f56e86bd 197 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
9a5834ae 198 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
e075ae69
RH
199 (const_string "other"))
200
6ef67412 201;; Main data type used by the insn
9a5834ae 202(define_attr "mode"
6c4ccfd8 203 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
6ef67412
JH
204 (const_string "unknown"))
205
3d34cd91
JH
206;; The CPU unit operations uses.
207(define_attr "unit" "integer,i387,sse,mmx,unknown"
edeacc14 208 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
3d34cd91 209 (const_string "i387")
ef719a44 210 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
cb297538 211 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
3d34cd91 212 (const_string "sse")
9a5834ae 213 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
4c9c9a3d
JH
214 (const_string "mmx")
215 (eq_attr "type" "other")
216 (const_string "unknown")]
3d34cd91 217 (const_string "integer")))
6ef67412
JH
218
219;; The (bounding maximum) length of an instruction immediate.
220(define_attr "length_immediate" ""
4977bab6 221 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
6ef67412 222 (const_int 0)
3d34cd91 223 (eq_attr "unit" "i387,sse,mmx")
6ef67412 224 (const_int 0)
1b245ade
JH
225 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
226 imul,icmp,push,pop")
6ef67412
JH
227 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
228 (eq_attr "type" "imov,test")
229 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
230 (eq_attr "type" "call")
231 (if_then_else (match_operand 0 "constant_call_address_operand" "")
232 (const_int 4)
233 (const_int 0))
234 (eq_attr "type" "callv")
235 (if_then_else (match_operand 1 "constant_call_address_operand" "")
236 (const_int 4)
237 (const_int 0))
efcc7037
JH
238 ;; We don't know the size before shorten_branches. Expect
239 ;; the instruction to fit for better scheduling.
6ef67412 240 (eq_attr "type" "ibr")
efcc7037 241 (const_int 1)
6ef67412 242 ]
9a5834ae
ZW
243 (symbol_ref "/* Update immediate_length and other attributes! */
244 abort(),1")))
e075ae69 245
6ef67412
JH
246;; The (bounding maximum) length of an instruction address.
247(define_attr "length_address" ""
248 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
249 (const_int 0)
250 (and (eq_attr "type" "call")
c7375e61 251 (match_operand 0 "constant_call_address_operand" ""))
6ef67412
JH
252 (const_int 0)
253 (and (eq_attr "type" "callv")
254 (match_operand 1 "constant_call_address_operand" ""))
255 (const_int 0)
256 ]
257 (symbol_ref "ix86_attr_length_address_default (insn)")))
258
259;; Set when length prefix is used.
260(define_attr "prefix_data16" ""
3d34cd91
JH
261 (if_then_else (ior (eq_attr "mode" "HI")
262 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
6ef67412
JH
263 (const_int 1)
264 (const_int 0)))
265
266;; Set when string REP prefix is used.
3d34cd91
JH
267(define_attr "prefix_rep" ""
268 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
269 (const_int 1)
270 (const_int 0)))
6ef67412
JH
271
272;; Set when 0f opcode prefix is used.
273(define_attr "prefix_0f" ""
9a5834ae 274 (if_then_else
cb297538
JH
275 (ior (eq_attr "type" "imovx,setcc,icmov")
276 (eq_attr "unit" "sse,mmx"))
6ef67412
JH
277 (const_int 1)
278 (const_int 0)))
279
56bab446 280;; Set when REX opcode prefix is used.
4977bab6
ZW
281(define_attr "prefix_rex" ""
282 (cond [(and (eq_attr "mode" "DI")
283 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
284 (const_int 1)
285 (and (eq_attr "mode" "QI")
286 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
287 (const_int 0)))
288 (const_int 1)
289 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
290 (const_int 0))
291 (const_int 1)
292 ]
293 (const_int 0)))
294
6ef67412
JH
295;; Set when modrm byte is used.
296(define_attr "modrm" ""
4977bab6 297 (cond [(eq_attr "type" "str,cld,leave")
6ef67412 298 (const_int 0)
3d34cd91 299 (eq_attr "unit" "i387")
6ef67412 300 (const_int 0)
e075ae69
RH
301 (and (eq_attr "type" "incdec")
302 (ior (match_operand:SI 1 "register_operand" "")
303 (match_operand:HI 1 "register_operand" "")))
6ef67412 304 (const_int 0)
e075ae69
RH
305 (and (eq_attr "type" "push")
306 (not (match_operand 1 "memory_operand" "")))
6ef67412 307 (const_int 0)
e075ae69
RH
308 (and (eq_attr "type" "pop")
309 (not (match_operand 0 "memory_operand" "")))
6ef67412 310 (const_int 0)
e075ae69
RH
311 (and (eq_attr "type" "imov")
312 (and (match_operand 0 "register_operand" "")
313 (match_operand 1 "immediate_operand" "")))
6ef67412 314 (const_int 0)
c7375e61
EB
315 (and (eq_attr "type" "call")
316 (match_operand 0 "constant_call_address_operand" ""))
317 (const_int 0)
318 (and (eq_attr "type" "callv")
319 (match_operand 1 "constant_call_address_operand" ""))
320 (const_int 0)
e075ae69 321 ]
6ef67412
JH
322 (const_int 1)))
323
324;; The (bounding maximum) length of an instruction in bytes.
edeacc14
UB
325;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
326;; Later we may want to split them and compute proper length as for
327;; other insns.
6ef67412 328(define_attr "length" ""
edeacc14 329 (cond [(eq_attr "type" "other,multi,fistp,frndint")
6ef67412 330 (const_int 16)
a3033f34
EB
331 (eq_attr "type" "fcmp")
332 (const_int 4)
3d34cd91
JH
333 (eq_attr "unit" "i387")
334 (plus (const_int 2)
335 (plus (attr "prefix_data16")
336 (attr "length_address")))]
6ef67412
JH
337 (plus (plus (attr "modrm")
338 (plus (attr "prefix_0f")
4977bab6
ZW
339 (plus (attr "prefix_rex")
340 (const_int 1))))
6ef67412
JH
341 (plus (attr "prefix_rep")
342 (plus (attr "prefix_data16")
343 (plus (attr "length_immediate")
344 (attr "length_address")))))))
e075ae69
RH
345
346;; The `memory' attribute is `none' if no memory is referenced, `load' or
347;; `store' if there is a simple memory reference therein, or `unknown'
348;; if the instruction is complex.
349
350(define_attr "memory" "none,load,store,both,unknown"
7c7ef435 351 (cond [(eq_attr "type" "other,multi,str")
e075ae69 352 (const_string "unknown")
7c7ef435 353 (eq_attr "type" "lea,fcmov,fpspc,cld")
e075ae69 354 (const_string "none")
4977bab6 355 (eq_attr "type" "fistp,leave")
22fb740d 356 (const_string "both")
edeacc14
UB
357 (eq_attr "type" "frndint")
358 (const_string "load")
e075ae69
RH
359 (eq_attr "type" "push")
360 (if_then_else (match_operand 1 "memory_operand" "")
361 (const_string "both")
362 (const_string "store"))
abd2dd6d 363 (eq_attr "type" "pop")
e075ae69
RH
364 (if_then_else (match_operand 0 "memory_operand" "")
365 (const_string "both")
366 (const_string "load"))
abd2dd6d
JH
367 (eq_attr "type" "setcc")
368 (if_then_else (match_operand 0 "memory_operand" "")
369 (const_string "store")
370 (const_string "none"))
f56e86bd 371 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
e075ae69
RH
372 (if_then_else (ior (match_operand 0 "memory_operand" "")
373 (match_operand 1 "memory_operand" ""))
374 (const_string "load")
375 (const_string "none"))
376 (eq_attr "type" "ibr")
377 (if_then_else (match_operand 0 "memory_operand" "")
378 (const_string "load")
379 (const_string "none"))
380 (eq_attr "type" "call")
381 (if_then_else (match_operand 0 "constant_call_address_operand" "")
382 (const_string "none")
383 (const_string "load"))
384 (eq_attr "type" "callv")
385 (if_then_else (match_operand 1 "constant_call_address_operand" "")
386 (const_string "none")
387 (const_string "load"))
ef719a44 388 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
a269a03c 389 (match_operand 1 "memory_operand" ""))
e075ae69
RH
390 (const_string "both")
391 (and (match_operand 0 "memory_operand" "")
392 (match_operand 1 "memory_operand" ""))
393 (const_string "both")
394 (match_operand 0 "memory_operand" "")
395 (const_string "store")
396 (match_operand 1 "memory_operand" "")
397 (const_string "load")
9a5834ae 398 (and (eq_attr "type"
f527d196 399 "!alu1,negnot,ishift1,
9a5834ae
ZW
400 imov,imovx,icmp,test,
401 fmov,fcmp,fsgn,
ef719a44 402 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
9a5834ae 403 mmx,mmxmov,mmxcmp,mmxcvt")
e075ae69
RH
404 (match_operand 2 "memory_operand" ""))
405 (const_string "load")
406 (and (eq_attr "type" "icmov")
407 (match_operand 3 "memory_operand" ""))
408 (const_string "load")
409 ]
a269a03c
JC
410 (const_string "none")))
411
e075ae69
RH
412;; Indicates if an instruction has both an immediate and a displacement.
413
414(define_attr "imm_disp" "false,true,unknown"
415 (cond [(eq_attr "type" "other,multi")
416 (const_string "unknown")
1b245ade 417 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
e075ae69
RH
418 (and (match_operand 0 "memory_displacement_operand" "")
419 (match_operand 1 "immediate_operand" "")))
420 (const_string "true")
890d52e8 421 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
e075ae69
RH
422 (and (match_operand 0 "memory_displacement_operand" "")
423 (match_operand 2 "immediate_operand" "")))
424 (const_string "true")
425 ]
426 (const_string "false")))
427
428;; Indicates if an FP operation has an integer source.
429
430(define_attr "fp_int_src" "false,true"
431 (const_string "false"))
432
edeacc14
UB
433;; Defines rounding mode of an FP operation.
434
1d1df0df 435(define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
edeacc14
UB
436 (const_string "any"))
437
e075ae69
RH
438;; Describe a user's asm statement.
439(define_asm_attributes
440 [(set_attr "length" "128")
441 (set_attr "type" "multi")])
442\f
8fe75e43
RH
443;; Scheduling descriptions
444
af2728a4
JL
445(include "pentium.md")
446(include "ppro.md")
447(include "k6.md")
448(include "athlon.md")
8fe75e43
RH
449
450\f
451;; Operand and operator predicates
452
453(include "predicates.md")
454
309ada50 455\f
e075ae69 456;; Compare instructions.
886c62d1 457
e075ae69 458;; All compare insns have expanders that save the operands away without
c572e5ba 459;; actually generating RTL. The bCOND or sCOND (emitted immediately
e075ae69 460;; after the cmp) will actually emit the cmpM.
886c62d1 461
e075ae69 462(define_expand "cmpdi"
8bc527af 463 [(set (reg:CC FLAGS_REG)
b9b2c339 464 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
9b70259d 465 (match_operand:DI 1 "x86_64_general_operand" "")))]
c572e5ba 466 ""
c572e5ba 467{
b9b2c339 468 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
469 operands[0] = force_reg (DImode, operands[0]);
470 ix86_compare_op0 = operands[0];
471 ix86_compare_op1 = operands[1];
c572e5ba 472 DONE;
0f40f9f7 473})
c572e5ba 474
e075ae69 475(define_expand "cmpsi"
8bc527af 476 [(set (reg:CC FLAGS_REG)
e075ae69
RH
477 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
478 (match_operand:SI 1 "general_operand" "")))]
c572e5ba 479 ""
c572e5ba 480{
b9b2c339 481 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
482 operands[0] = force_reg (SImode, operands[0]);
483 ix86_compare_op0 = operands[0];
484 ix86_compare_op1 = operands[1];
c572e5ba 485 DONE;
0f40f9f7 486})
c572e5ba 487
e075ae69 488(define_expand "cmphi"
8bc527af 489 [(set (reg:CC FLAGS_REG)
b9b2c339 490 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
e075ae69 491 (match_operand:HI 1 "general_operand" "")))]
c572e5ba 492 ""
c572e5ba 493{
b9b2c339 494 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
495 operands[0] = force_reg (HImode, operands[0]);
496 ix86_compare_op0 = operands[0];
497 ix86_compare_op1 = operands[1];
c572e5ba 498 DONE;
0f40f9f7 499})
c572e5ba 500
e075ae69 501(define_expand "cmpqi"
8bc527af 502 [(set (reg:CC FLAGS_REG)
b9b2c339 503 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
e075ae69 504 (match_operand:QI 1 "general_operand" "")))]
d9f32422 505 "TARGET_QIMODE_MATH"
c572e5ba 506{
b9b2c339 507 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
508 operands[0] = force_reg (QImode, operands[0]);
509 ix86_compare_op0 = operands[0];
510 ix86_compare_op1 = operands[1];
c572e5ba 511 DONE;
0f40f9f7 512})
886c62d1 513
9b70259d 514(define_insn "cmpdi_ccno_1_rex64"
42fabf21 515 [(set (reg FLAGS_REG)
9b70259d
JH
516 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
517 (match_operand:DI 1 "const0_operand" "n,n")))]
518 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
519 "@
0f40f9f7
ZW
520 test{q}\t{%0, %0|%0, %0}
521 cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
522 [(set_attr "type" "test,icmp")
523 (set_attr "length_immediate" "0,1")
524 (set_attr "mode" "DI")])
525
526(define_insn "*cmpdi_minus_1_rex64"
42fabf21 527 [(set (reg FLAGS_REG)
9b70259d
JH
528 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
529 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
530 (const_int 0)))]
1b0c37d7 531 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 532 "cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
533 [(set_attr "type" "icmp")
534 (set_attr "mode" "DI")])
535
536(define_expand "cmpdi_1_rex64"
8bc527af 537 [(set (reg:CC FLAGS_REG)
9b70259d
JH
538 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
539 (match_operand:DI 1 "general_operand" "")))]
1b0c37d7 540 "TARGET_64BIT"
9b70259d
JH
541 "")
542
543(define_insn "cmpdi_1_insn_rex64"
42fabf21 544 [(set (reg FLAGS_REG)
9b70259d
JH
545 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
546 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
547 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 548 "cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
549 [(set_attr "type" "icmp")
550 (set_attr "mode" "DI")])
551
552
9076b9c1 553(define_insn "*cmpsi_ccno_1"
42fabf21 554 [(set (reg FLAGS_REG)
9076b9c1
JH
555 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
556 (match_operand:SI 1 "const0_operand" "n,n")))]
557 "ix86_match_ccmode (insn, CCNOmode)"
16189740 558 "@
0f40f9f7
ZW
559 test{l}\t{%0, %0|%0, %0}
560 cmp{l}\t{%1, %0|%0, %1}"
6ef67412
JH
561 [(set_attr "type" "test,icmp")
562 (set_attr "length_immediate" "0,1")
563 (set_attr "mode" "SI")])
16189740 564
9076b9c1 565(define_insn "*cmpsi_minus_1"
42fabf21 566 [(set (reg FLAGS_REG)
9076b9c1
JH
567 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
568 (match_operand:SI 1 "general_operand" "ri,mr"))
569 (const_int 0)))]
570 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 571 "cmp{l}\t{%1, %0|%0, %1}"
9076b9c1 572 [(set_attr "type" "icmp")
6ef67412 573 (set_attr "mode" "SI")])
886c62d1 574
9076b9c1 575(define_expand "cmpsi_1"
8bc527af 576 [(set (reg:CC FLAGS_REG)
e075ae69
RH
577 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
578 (match_operand:SI 1 "general_operand" "ri,mr")))]
9076b9c1
JH
579 ""
580 "")
581
582(define_insn "*cmpsi_1_insn"
42fabf21 583 [(set (reg FLAGS_REG)
9076b9c1
JH
584 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
585 (match_operand:SI 1 "general_operand" "ri,mr")))]
586 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
587 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 588 "cmp{l}\t{%1, %0|%0, %1}"
6ef67412
JH
589 [(set_attr "type" "icmp")
590 (set_attr "mode" "SI")])
886c62d1 591
9076b9c1 592(define_insn "*cmphi_ccno_1"
42fabf21 593 [(set (reg FLAGS_REG)
16189740
RH
594 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
595 (match_operand:HI 1 "const0_operand" "n,n")))]
596 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 597 "@
0f40f9f7
ZW
598 test{w}\t{%0, %0|%0, %0}
599 cmp{w}\t{%1, %0|%0, %1}"
6ef67412
JH
600 [(set_attr "type" "test,icmp")
601 (set_attr "length_immediate" "0,1")
602 (set_attr "mode" "HI")])
886c62d1 603
9076b9c1 604(define_insn "*cmphi_minus_1"
42fabf21 605 [(set (reg FLAGS_REG)
9076b9c1
JH
606 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
607 (match_operand:HI 1 "general_operand" "ri,mr"))
608 (const_int 0)))]
609 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 610 "cmp{w}\t{%1, %0|%0, %1}"
6ef67412
JH
611 [(set_attr "type" "icmp")
612 (set_attr "mode" "HI")])
e075ae69 613
9076b9c1 614(define_insn "*cmphi_1"
42fabf21 615 [(set (reg FLAGS_REG)
9076b9c1
JH
616 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
617 (match_operand:HI 1 "general_operand" "ri,mr")))]
618 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 620 "cmp{w}\t{%1, %0|%0, %1}"
9076b9c1
JH
621 [(set_attr "type" "icmp")
622 (set_attr "mode" "HI")])
16189740
RH
623
624(define_insn "*cmpqi_ccno_1"
42fabf21 625 [(set (reg FLAGS_REG)
9076b9c1
JH
626 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
627 (match_operand:QI 1 "const0_operand" "n,n")))]
628 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 629 "@
0f40f9f7
ZW
630 test{b}\t{%0, %0|%0, %0}
631 cmp{b}\t{$0, %0|%0, 0}"
6ef67412
JH
632 [(set_attr "type" "test,icmp")
633 (set_attr "length_immediate" "0,1")
634 (set_attr "mode" "QI")])
886c62d1 635
16189740 636(define_insn "*cmpqi_1"
42fabf21 637 [(set (reg FLAGS_REG)
9076b9c1
JH
638 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
639 (match_operand:QI 1 "general_operand" "qi,mq")))]
640 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
641 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 642 "cmp{b}\t{%1, %0|%0, %1}"
6ef67412
JH
643 [(set_attr "type" "icmp")
644 (set_attr "mode" "QI")])
e075ae69 645
9076b9c1 646(define_insn "*cmpqi_minus_1"
42fabf21 647 [(set (reg FLAGS_REG)
d70401eb
JJ
648 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
649 (match_operand:QI 1 "general_operand" "qi,mq"))
9076b9c1
JH
650 (const_int 0)))]
651 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 652 "cmp{b}\t{%1, %0|%0, %1}"
9076b9c1
JH
653 [(set_attr "type" "icmp")
654 (set_attr "mode" "QI")])
655
e075ae69 656(define_insn "*cmpqi_ext_1"
42fabf21 657 [(set (reg FLAGS_REG)
9076b9c1 658 (compare
d2836273 659 (match_operand:QI 0 "general_operand" "Qm")
e075ae69
RH
660 (subreg:QI
661 (zero_extract:SI
d2836273 662 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
663 (const_int 8)
664 (const_int 8)) 0)))]
d2836273 665 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 666 "cmp{b}\t{%h1, %0|%0, %h1}"
d2836273
JH
667 [(set_attr "type" "icmp")
668 (set_attr "mode" "QI")])
669
670(define_insn "*cmpqi_ext_1_rex64"
42fabf21 671 [(set (reg FLAGS_REG)
d2836273 672 (compare
3522082b 673 (match_operand:QI 0 "register_operand" "Q")
d2836273
JH
674 (subreg:QI
675 (zero_extract:SI
676 (match_operand 1 "ext_register_operand" "Q")
677 (const_int 8)
678 (const_int 8)) 0)))]
679 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 680 "cmp{b}\t{%h1, %0|%0, %h1}"
6ef67412
JH
681 [(set_attr "type" "icmp")
682 (set_attr "mode" "QI")])
e075ae69
RH
683
684(define_insn "*cmpqi_ext_2"
42fabf21 685 [(set (reg FLAGS_REG)
16189740 686 (compare
e075ae69
RH
687 (subreg:QI
688 (zero_extract:SI
d2836273 689 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
690 (const_int 8)
691 (const_int 8)) 0)
692 (match_operand:QI 1 "const0_operand" "n")))]
16189740 693 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 694 "test{b}\t%h0, %h0"
6ef67412
JH
695 [(set_attr "type" "test")
696 (set_attr "length_immediate" "0")
697 (set_attr "mode" "QI")])
e075ae69 698
9076b9c1 699(define_expand "cmpqi_ext_3"
8bc527af 700 [(set (reg:CC FLAGS_REG)
e075ae69
RH
701 (compare:CC
702 (subreg:QI
703 (zero_extract:SI
d2836273 704 (match_operand 0 "ext_register_operand" "")
e075ae69
RH
705 (const_int 8)
706 (const_int 8)) 0)
d2836273 707 (match_operand:QI 1 "general_operand" "")))]
e075ae69 708 ""
9076b9c1
JH
709 "")
710
711(define_insn "cmpqi_ext_3_insn"
42fabf21 712 [(set (reg FLAGS_REG)
9076b9c1
JH
713 (compare
714 (subreg:QI
715 (zero_extract:SI
d2836273 716 (match_operand 0 "ext_register_operand" "Q")
9076b9c1
JH
717 (const_int 8)
718 (const_int 8)) 0)
d2836273
JH
719 (match_operand:QI 1 "general_operand" "Qmn")))]
720 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 721 "cmp{b}\t{%1, %h0|%h0, %1}"
d2836273
JH
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
724
725(define_insn "cmpqi_ext_3_insn_rex64"
42fabf21 726 [(set (reg FLAGS_REG)
d2836273
JH
727 (compare
728 (subreg:QI
729 (zero_extract:SI
730 (match_operand 0 "ext_register_operand" "Q")
731 (const_int 8)
732 (const_int 8)) 0)
733 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
734 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 735 "cmp{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
736 [(set_attr "type" "icmp")
737 (set_attr "mode" "QI")])
e075ae69
RH
738
739(define_insn "*cmpqi_ext_4"
42fabf21 740 [(set (reg FLAGS_REG)
9076b9c1 741 (compare
e075ae69
RH
742 (subreg:QI
743 (zero_extract:SI
d2836273 744 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
745 (const_int 8)
746 (const_int 8)) 0)
747 (subreg:QI
748 (zero_extract:SI
d2836273 749 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
750 (const_int 8)
751 (const_int 8)) 0)))]
9076b9c1 752 "ix86_match_ccmode (insn, CCmode)"
0f40f9f7 753 "cmp{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
754 [(set_attr "type" "icmp")
755 (set_attr "mode" "QI")])
e075ae69
RH
756
757;; These implement float point compares.
758;; %%% See if we can get away with VOIDmode operands on the actual insns,
759;; which would allow mix and match FP modes on the compares. Which is what
760;; the old patterns did, but with many more of them.
c572e5ba 761
e075ae69 762(define_expand "cmpxf"
8bc527af 763 [(set (reg:CC FLAGS_REG)
e075ae69
RH
764 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
765 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
2b589241 766 "TARGET_80387"
2b589241
JH
767{
768 ix86_compare_op0 = operands[0];
769 ix86_compare_op1 = operands[1];
770 DONE;
0f40f9f7 771})
2b589241 772
e075ae69 773(define_expand "cmpdf"
8bc527af 774 [(set (reg:CC FLAGS_REG)
e075ae69
RH
775 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
776 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
eaa49b49 777 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4fb21e90 778{
e075ae69
RH
779 ix86_compare_op0 = operands[0];
780 ix86_compare_op1 = operands[1];
4fb21e90 781 DONE;
0f40f9f7 782})
886c62d1 783
e075ae69 784(define_expand "cmpsf"
8bc527af 785 [(set (reg:CC FLAGS_REG)
e075ae69
RH
786 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
787 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
eaa49b49 788 "TARGET_80387 || TARGET_SSE_MATH"
c572e5ba 789{
e075ae69
RH
790 ix86_compare_op0 = operands[0];
791 ix86_compare_op1 = operands[1];
c572e5ba 792 DONE;
0f40f9f7 793})
c572e5ba 794
e075ae69
RH
795;; FP compares, step 1:
796;; Set the FP condition codes.
797;;
798;; CCFPmode compare with exceptions
799;; CCFPUmode compare with no exceptions
fe4435d9 800
7c82106f
UB
801;; We may not use "#" to split and emit these, since the REG_DEAD notes
802;; used to manage the reg stack popping would not be preserved.
803
45c8c47f
UB
804(define_insn "*cmpfp_0_sf"
805 [(set (match_operand:HI 0 "register_operand" "=a")
806 (unspec:HI
807 [(compare:CCFP
808 (match_operand:SF 1 "register_operand" "f")
809 (match_operand:SF 2 "const0_operand" "X"))]
810 UNSPEC_FNSTSW))]
811 "TARGET_80387"
7c82106f 812 "* return output_fp_compare (insn, operands, 0, 0);"
45c8c47f
UB
813 [(set_attr "type" "multi")
814 (set_attr "mode" "SF")])
886c62d1 815
45c8c47f 816(define_insn "*cmpfp_0_df"
e075ae69
RH
817 [(set (match_operand:HI 0 "register_operand" "=a")
818 (unspec:HI
45c8c47f
UB
819 [(compare:CCFP
820 (match_operand:DF 1 "register_operand" "f")
821 (match_operand:DF 2 "const0_operand" "X"))]
822 UNSPEC_FNSTSW))]
823 "TARGET_80387"
7c82106f 824 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412 825 [(set_attr "type" "multi")
45c8c47f
UB
826 (set_attr "mode" "DF")])
827
828(define_insn "*cmpfp_0_xf"
829 [(set (match_operand:HI 0 "register_operand" "=a")
830 (unspec:HI
831 [(compare:CCFP
832 (match_operand:XF 1 "register_operand" "f")
833 (match_operand:XF 2 "const0_operand" "X"))]
834 UNSPEC_FNSTSW))]
835 "TARGET_80387"
7c82106f 836 "* return output_fp_compare (insn, operands, 0, 0);"
45c8c47f
UB
837 [(set_attr "type" "multi")
838 (set_attr "mode" "XF")])
c572e5ba 839
7c82106f 840(define_insn "*cmpfp_sf"
e075ae69
RH
841 [(set (match_operand:HI 0 "register_operand" "=a")
842 (unspec:HI
843 [(compare:CCFP
844 (match_operand:SF 1 "register_operand" "f")
8ee41eaf
RH
845 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
846 UNSPEC_FNSTSW))]
4fb21e90 847 "TARGET_80387"
e075ae69 848 "* return output_fp_compare (insn, operands, 0, 0);"
fdf97ad1 849 [(set_attr "type" "multi")
7c82106f 850 (set_attr "mode" "SF")])
926b3fae 851
7c82106f 852(define_insn "*cmpfp_df"
e075ae69
RH
853 [(set (match_operand:HI 0 "register_operand" "=a")
854 (unspec:HI
855 [(compare:CCFP
856 (match_operand:DF 1 "register_operand" "f")
8ee41eaf
RH
857 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
858 UNSPEC_FNSTSW))]
4fb21e90 859 "TARGET_80387"
7c82106f 860 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412
JH
861 [(set_attr "type" "multi")
862 (set_attr "mode" "DF")])
e075ae69 863
7c82106f 864(define_insn "*cmpfp_xf"
e075ae69
RH
865 [(set (match_operand:HI 0 "register_operand" "=a")
866 (unspec:HI
867 [(compare:CCFP
868 (match_operand:XF 1 "register_operand" "f")
8ee41eaf
RH
869 (match_operand:XF 2 "register_operand" "f"))]
870 UNSPEC_FNSTSW))]
2b589241 871 "TARGET_80387"
7c82106f 872 "* return output_fp_compare (insn, operands, 0, 0);"
2b589241
JH
873 [(set_attr "type" "multi")
874 (set_attr "mode" "XF")])
875
7c82106f 876(define_insn "*cmpfp_u"
e075ae69
RH
877 [(set (match_operand:HI 0 "register_operand" "=a")
878 (unspec:HI
879 [(compare:CCFPU
880 (match_operand 1 "register_operand" "f")
8ee41eaf
RH
881 (match_operand 2 "register_operand" "f"))]
882 UNSPEC_FNSTSW))]
08a7baac 883 "TARGET_80387
e075ae69
RH
884 && FLOAT_MODE_P (GET_MODE (operands[1]))
885 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7c82106f 886 "* return output_fp_compare (insn, operands, 0, 1);"
6ef67412 887 [(set_attr "type" "multi")
4977bab6
ZW
888 (set (attr "mode")
889 (cond [(match_operand:SF 1 "" "")
890 (const_string "SF")
891 (match_operand:DF 1 "" "")
892 (const_string "DF")
893 ]
894 (const_string "XF")))])
08a7baac 895
7c82106f
UB
896(define_insn "*cmpfp_si"
897 [(set (match_operand:HI 0 "register_operand" "=a")
898 (unspec:HI
899 [(compare:CCFP
900 (match_operand 1 "register_operand" "f")
901 (match_operator 3 "float_operator"
902 [(match_operand:SI 2 "memory_operand" "m")]))]
903 UNSPEC_FNSTSW))]
904 "TARGET_80387 && TARGET_USE_FIOP
905 && FLOAT_MODE_P (GET_MODE (operands[1]))
906 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
907 "* return output_fp_compare (insn, operands, 0, 0);"
908 [(set_attr "type" "multi")
909 (set_attr "fp_int_src" "true")
910 (set_attr "mode" "SI")])
e075ae69
RH
911
912;; FP compares, step 2
913;; Move the fpsw to ax.
914
5ae27cfa 915(define_insn "x86_fnstsw_1"
e075ae69 916 [(set (match_operand:HI 0 "register_operand" "=a")
8bc527af 917 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
2ae0f82c 918 "TARGET_80387"
0f40f9f7 919 "fnstsw\t%0"
e075ae69 920 [(set_attr "length" "2")
6ef67412 921 (set_attr "mode" "SI")
56bab446 922 (set_attr "unit" "i387")])
e075ae69
RH
923
924;; FP compares, step 3
925;; Get ax into flags, general case.
926
927(define_insn "x86_sahf_1"
8bc527af 928 [(set (reg:CC FLAGS_REG)
8ee41eaf 929 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
1e07edd3 930 "!TARGET_64BIT"
e075ae69
RH
931 "sahf"
932 [(set_attr "length" "1")
0b5107cf 933 (set_attr "athlon_decode" "vector")
56bab446 934 (set_attr "mode" "SI")])
e075ae69
RH
935
936;; Pentium Pro can do steps 1 through 3 in one go.
937
eaa49b49 938(define_insn "*cmpfp_i_mixed"
8bc527af 939 [(set (reg:CCFP FLAGS_REG)
0644b628
JH
940 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
941 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
eaa49b49 942 "TARGET_MIX_SSE_I387
0644b628 943 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
869d095e 944 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
0644b628 945 "* return output_fp_compare (insn, operands, 1, 0);"
26771da7 946 [(set_attr "type" "fcmp,ssecomi")
4977bab6
ZW
947 (set (attr "mode")
948 (if_then_else (match_operand:SF 1 "" "")
949 (const_string "SF")
950 (const_string "DF")))
0644b628
JH
951 (set_attr "athlon_decode" "vector")])
952
eaa49b49 953(define_insn "*cmpfp_i_sse"
8bc527af 954 [(set (reg:CCFP FLAGS_REG)
0644b628
JH
955 (compare:CCFP (match_operand 0 "register_operand" "x")
956 (match_operand 1 "nonimmediate_operand" "xm")))]
eaa49b49
RH
957 "TARGET_SSE_MATH
958 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
869d095e 959 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
0644b628 960 "* return output_fp_compare (insn, operands, 1, 0);"
26771da7 961 [(set_attr "type" "ssecomi")
4977bab6
ZW
962 (set (attr "mode")
963 (if_then_else (match_operand:SF 1 "" "")
964 (const_string "SF")
965 (const_string "DF")))
0644b628
JH
966 (set_attr "athlon_decode" "vector")])
967
eaa49b49
RH
968(define_insn "*cmpfp_i_i387"
969 [(set (reg:CCFP FLAGS_REG)
970 (compare:CCFP (match_operand 0 "register_operand" "f")
971 (match_operand 1 "register_operand" "f")))]
e075ae69 972 "TARGET_80387 && TARGET_CMOVE
eaa49b49 973 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
e075ae69
RH
974 && FLOAT_MODE_P (GET_MODE (operands[0]))
975 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
eaa49b49 976 "* return output_fp_compare (insn, operands, 1, 0);"
309ada50 977 [(set_attr "type" "fcmp")
4977bab6
ZW
978 (set (attr "mode")
979 (cond [(match_operand:SF 1 "" "")
980 (const_string "SF")
981 (match_operand:DF 1 "" "")
982 (const_string "DF")
983 ]
984 (const_string "XF")))
309ada50 985 (set_attr "athlon_decode" "vector")])
0644b628 986
eaa49b49 987(define_insn "*cmpfp_iu_mixed"
8bc527af 988 [(set (reg:CCFPU FLAGS_REG)
0644b628
JH
989 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
990 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
eaa49b49 991 "TARGET_MIX_SSE_I387
0644b628
JH
992 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
993 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
994 "* return output_fp_compare (insn, operands, 1, 1);"
26771da7 995 [(set_attr "type" "fcmp,ssecomi")
4977bab6
ZW
996 (set (attr "mode")
997 (if_then_else (match_operand:SF 1 "" "")
998 (const_string "SF")
999 (const_string "DF")))
0644b628
JH
1000 (set_attr "athlon_decode" "vector")])
1001
eaa49b49 1002(define_insn "*cmpfp_iu_sse"
8bc527af 1003 [(set (reg:CCFPU FLAGS_REG)
0644b628
JH
1004 (compare:CCFPU (match_operand 0 "register_operand" "x")
1005 (match_operand 1 "nonimmediate_operand" "xm")))]
eaa49b49
RH
1006 "TARGET_SSE_MATH
1007 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
0644b628
JH
1008 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1009 "* return output_fp_compare (insn, operands, 1, 1);"
26771da7 1010 [(set_attr "type" "ssecomi")
4977bab6
ZW
1011 (set (attr "mode")
1012 (if_then_else (match_operand:SF 1 "" "")
1013 (const_string "SF")
1014 (const_string "DF")))
0644b628 1015 (set_attr "athlon_decode" "vector")])
eaa49b49
RH
1016
1017(define_insn "*cmpfp_iu_387"
1018 [(set (reg:CCFPU FLAGS_REG)
1019 (compare:CCFPU (match_operand 0 "register_operand" "f")
1020 (match_operand 1 "register_operand" "f")))]
1021 "TARGET_80387 && TARGET_CMOVE
1022 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1023 && 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);"
1026 [(set_attr "type" "fcmp")
1027 (set (attr "mode")
1028 (cond [(match_operand:SF 1 "" "")
1029 (const_string "SF")
1030 (match_operand:DF 1 "" "")
1031 (const_string "DF")
1032 ]
1033 (const_string "XF")))
1034 (set_attr "athlon_decode" "vector")])
e075ae69
RH
1035\f
1036;; Move instructions.
2ae0f82c 1037
e075ae69 1038;; General case of fullword move.
886c62d1 1039
e075ae69
RH
1040(define_expand "movsi"
1041 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1042 (match_operand:SI 1 "general_operand" ""))]
1043 ""
1044 "ix86_expand_move (SImode, operands); DONE;")
08a7baac 1045
e075ae69
RH
1046;; Push/pop instructions. They are separate since autoinc/dec is not a
1047;; general_operand.
1048;;
1049;; %%% We don't use a post-inc memory reference because x86 is not a
1050;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1051;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1052;; targets without our curiosities, and it is just as easy to represent
1053;; this differently.
886c62d1 1054
a4414093 1055(define_insn "*pushsi2"
e075ae69 1056 [(set (match_operand:SI 0 "push_operand" "=<")
2c5a510c 1057 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
0ec259ed 1058 "!TARGET_64BIT"
0f40f9f7 1059 "push{l}\t%1"
6ef67412
JH
1060 [(set_attr "type" "push")
1061 (set_attr "mode" "SI")])
4fb21e90 1062
0ec259ed
JH
1063;; For 64BIT abi we always round up to 8 bytes.
1064(define_insn "*pushsi2_rex64"
1065 [(set (match_operand:SI 0 "push_operand" "=X")
1066 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1067 "TARGET_64BIT"
0f40f9f7 1068 "push{q}\t%q1"
0ec259ed
JH
1069 [(set_attr "type" "push")
1070 (set_attr "mode" "SI")])
1071
bdeb029c
JH
1072(define_insn "*pushsi2_prologue"
1073 [(set (match_operand:SI 0 "push_operand" "=<")
1074 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
f2042df3 1075 (clobber (mem:BLK (scratch)))]
0ec259ed 1076 "!TARGET_64BIT"
0f40f9f7 1077 "push{l}\t%1"
6ef67412
JH
1078 [(set_attr "type" "push")
1079 (set_attr "mode" "SI")])
bdeb029c
JH
1080
1081(define_insn "*popsi1_epilogue"
1082 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
1083 (mem:SI (reg:SI SP_REG)))
1084 (set (reg:SI SP_REG)
1085 (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 1086 (clobber (mem:BLK (scratch)))]
1e07edd3 1087 "!TARGET_64BIT"
0f40f9f7 1088 "pop{l}\t%0"
6ef67412
JH
1089 [(set_attr "type" "pop")
1090 (set_attr "mode" "SI")])
bdeb029c 1091
e075ae69
RH
1092(define_insn "popsi1"
1093 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
1094 (mem:SI (reg:SI SP_REG)))
1095 (set (reg:SI SP_REG)
1096 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1e07edd3 1097 "!TARGET_64BIT"
0f40f9f7 1098 "pop{l}\t%0"
6ef67412
JH
1099 [(set_attr "type" "pop")
1100 (set_attr "mode" "SI")])
c572e5ba 1101
a8bac9ab 1102(define_insn "*movsi_xor"
591702de
JH
1103 [(set (match_operand:SI 0 "register_operand" "=r")
1104 (match_operand:SI 1 "const0_operand" "i"))
8bc527af 1105 (clobber (reg:CC FLAGS_REG))]
591702de 1106 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
0f40f9f7 1107 "xor{l}\t{%0, %0|%0, %0}"
591702de 1108 [(set_attr "type" "alu1")
6ef67412
JH
1109 (set_attr "mode" "SI")
1110 (set_attr "length_immediate" "0")])
67e53009 1111
591702de
JH
1112(define_insn "*movsi_or"
1113 [(set (match_operand:SI 0 "register_operand" "=r")
1114 (match_operand:SI 1 "immediate_operand" "i"))
8bc527af 1115 (clobber (reg:CC FLAGS_REG))]
87d9741e
KH
1116 "reload_completed
1117 && operands[1] == constm1_rtx
591702de 1118 && (TARGET_PENTIUM || optimize_size)"
c572e5ba 1119{
591702de 1120 operands[1] = constm1_rtx;
0f40f9f7
ZW
1121 return "or{l}\t{%1, %0|%0, %1}";
1122}
591702de 1123 [(set_attr "type" "alu1")
6ef67412
JH
1124 (set_attr "mode" "SI")
1125 (set_attr "length_immediate" "1")])
e075ae69 1126
591702de 1127(define_insn "*movsi_1"
6c4ccfd8
RH
1128 [(set (match_operand:SI 0 "nonimmediate_operand"
1129 "=r ,m ,!*y,!rm,!*y,!*x,!rm,!*x")
1130 (match_operand:SI 1 "general_operand"
1131 "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
8f62128d
JH
1132 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1133 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1134{
1135 switch (get_attr_type (insn))
1136 {
1137 case TYPE_SSEMOV:
1d5b4e0b 1138 if (get_attr_mode (insn) == MODE_TI)
8f62128d
JH
1139 return "movdqa\t{%1, %0|%0, %1}";
1140 return "movd\t{%1, %0|%0, %1}";
1141
1142 case TYPE_MMXMOV:
1d5b4e0b 1143 if (get_attr_mode (insn) == MODE_DI)
8f62128d
JH
1144 return "movq\t{%1, %0|%0, %1}";
1145 return "movd\t{%1, %0|%0, %1}";
1146
1147 case TYPE_LEA:
1148 return "lea{l}\t{%1, %0|%0, %1}";
1149
1150 default:
1151 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1152 abort();
1153 return "mov{l}\t{%1, %0|%0, %1}";
1154 }
1155}
1156 [(set (attr "type")
9b73c90a 1157 (cond [(eq_attr "alternative" "2,3,4")
8f62128d 1158 (const_string "mmxmov")
9b73c90a 1159 (eq_attr "alternative" "5,6,7")
8f62128d
JH
1160 (const_string "ssemov")
1161 (and (ne (symbol_ref "flag_pic") (const_int 0))
1162 (match_operand:SI 1 "symbolic_operand" ""))
1163 (const_string "lea")
1164 ]
1165 (const_string "imov")))
9b73c90a 1166 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
8f62128d
JH
1167
1168(define_insn "*movsi_1_nointernunit"
6c4ccfd8
RH
1169 [(set (match_operand:SI 0 "nonimmediate_operand"
1170 "=r ,m ,!*y,!m,!*y,!*x,!m,!*x")
1171 (match_operand:SI 1 "general_operand"
1172 "rinm,rin,*y ,*y,m ,*x ,*x,m"))]
8f62128d
JH
1173 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1174 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
886c62d1 1175{
e075ae69 1176 switch (get_attr_type (insn))
886c62d1 1177 {
5f90a099 1178 case TYPE_SSEMOV:
1d5b4e0b 1179 if (get_attr_mode (insn) == MODE_TI)
0f40f9f7
ZW
1180 return "movdqa\t{%1, %0|%0, %1}";
1181 return "movd\t{%1, %0|%0, %1}";
141e454b 1182
5f90a099 1183 case TYPE_MMXMOV:
1d5b4e0b 1184 if (get_attr_mode (insn) == MODE_DI)
e5a20888 1185 return "movq\t{%1, %0|%0, %1}";
0f40f9f7 1186 return "movd\t{%1, %0|%0, %1}";
915119a5 1187
e075ae69 1188 case TYPE_LEA:
0f40f9f7 1189 return "lea{l}\t{%1, %0|%0, %1}";
915119a5 1190
e075ae69 1191 default:
57d47446 1192 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
e075ae69 1193 abort();
0f40f9f7 1194 return "mov{l}\t{%1, %0|%0, %1}";
886c62d1 1195 }
0f40f9f7 1196}
e075ae69 1197 [(set (attr "type")
9b73c90a 1198 (cond [(eq_attr "alternative" "2,3,4")
3d34cd91 1199 (const_string "mmxmov")
9b73c90a 1200 (eq_attr "alternative" "5,6,7")
3d34cd91 1201 (const_string "ssemov")
915119a5 1202 (and (ne (symbol_ref "flag_pic") (const_int 0))
e075ae69
RH
1203 (match_operand:SI 1 "symbolic_operand" ""))
1204 (const_string "lea")
1205 ]
6ef67412 1206 (const_string "imov")))
9b73c90a 1207 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
e075ae69 1208
d1f87653 1209;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
1210;; We fake an second form of instruction to force reload to load address
1211;; into register when rax is not available
1212(define_insn "*movabssi_1_rex64"
7e6dc358
JJ
1213 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1214 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1215 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 1216 "@
0f40f9f7 1217 movabs{l}\t{%1, %P0|%P0, %1}
7e6dc358 1218 mov{l}\t{%1, %a0|%a0, %1}"
0ec259ed 1219 [(set_attr "type" "imov")
7e6dc358
JJ
1220 (set_attr "modrm" "0,*")
1221 (set_attr "length_address" "8,0")
1222 (set_attr "length_immediate" "0,*")
0ec259ed
JH
1223 (set_attr "memory" "store")
1224 (set_attr "mode" "SI")])
1225
1226(define_insn "*movabssi_2_rex64"
1227 [(set (match_operand:SI 0 "register_operand" "=a,r")
1228 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 1229 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 1230 "@
0f40f9f7
ZW
1231 movabs{l}\t{%P1, %0|%0, %P1}
1232 mov{l}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
1233 [(set_attr "type" "imov")
1234 (set_attr "modrm" "0,*")
1235 (set_attr "length_address" "8,0")
1236 (set_attr "length_immediate" "0")
1237 (set_attr "memory" "load")
1238 (set_attr "mode" "SI")])
1239
e075ae69
RH
1240(define_insn "*swapsi"
1241 [(set (match_operand:SI 0 "register_operand" "+r")
1242 (match_operand:SI 1 "register_operand" "+r"))
1243 (set (match_dup 1)
1244 (match_dup 0))]
2bb7a0f5 1245 ""
0f40f9f7 1246 "xchg{l}\t%1, %0"
e075ae69 1247 [(set_attr "type" "imov")
6ef67412 1248 (set_attr "mode" "SI")
7cc6af0c
RH
1249 (set_attr "pent_pair" "np")
1250 (set_attr "athlon_decode" "vector")])
886c62d1 1251
e075ae69
RH
1252(define_expand "movhi"
1253 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1254 (match_operand:HI 1 "general_operand" ""))]
ca097615 1255 ""
e075ae69 1256 "ix86_expand_move (HImode, operands); DONE;")
2f2a49e8 1257
a4414093 1258(define_insn "*pushhi2"
e075ae69 1259 [(set (match_operand:HI 0 "push_operand" "=<,<")
2c5a510c 1260 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1e07edd3 1261 "!TARGET_64BIT"
e075ae69 1262 "@
0f40f9f7
ZW
1263 push{w}\t{|WORD PTR }%1
1264 push{w}\t%1"
6ef67412
JH
1265 [(set_attr "type" "push")
1266 (set_attr "mode" "HI")])
e075ae69 1267
b3298882
JH
1268;; For 64BIT abi we always round up to 8 bytes.
1269(define_insn "*pushhi2_rex64"
1270 [(set (match_operand:HI 0 "push_operand" "=X")
1271 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1272 "TARGET_64BIT"
0f40f9f7 1273 "push{q}\t%q1"
b3298882
JH
1274 [(set_attr "type" "push")
1275 (set_attr "mode" "QI")])
1276
e075ae69 1277(define_insn "*movhi_1"
9b73c90a
EB
1278 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1279 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
e075ae69 1280 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
886c62d1 1281{
e075ae69 1282 switch (get_attr_type (insn))
886c62d1 1283 {
e075ae69
RH
1284 case TYPE_IMOVX:
1285 /* movzwl is faster than movw on p2 due to partial word stalls,
1286 though not as fast as an aligned movl. */
0f40f9f7 1287 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
e075ae69 1288 default:
6ef67412 1289 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 1290 return "mov{l}\t{%k1, %k0|%k0, %k1}";
e075ae69 1291 else
0f40f9f7 1292 return "mov{w}\t{%1, %0|%0, %1}";
886c62d1 1293 }
0f40f9f7 1294}
e075ae69 1295 [(set (attr "type")
68f48f39
RS
1296 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1297 (const_string "imov")
1298 (and (eq_attr "alternative" "0")
0b5107cf
JH
1299 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1300 (const_int 0))
1301 (eq (symbol_ref "TARGET_HIMODE_MATH")
1302 (const_int 0))))
369e59b1 1303 (const_string "imov")
9b73c90a 1304 (and (eq_attr "alternative" "1,2")
2247f6ed 1305 (match_operand:HI 1 "aligned_operand" ""))
e075ae69
RH
1306 (const_string "imov")
1307 (and (ne (symbol_ref "TARGET_MOVX")
1308 (const_int 0))
9b73c90a 1309 (eq_attr "alternative" "0,2"))
e075ae69
RH
1310 (const_string "imovx")
1311 ]
1312 (const_string "imov")))
6ef67412 1313 (set (attr "mode")
e075ae69 1314 (cond [(eq_attr "type" "imovx")
6ef67412 1315 (const_string "SI")
9b73c90a 1316 (and (eq_attr "alternative" "1,2")
369e59b1 1317 (match_operand:HI 1 "aligned_operand" ""))
6ef67412 1318 (const_string "SI")
9b73c90a 1319 (and (eq_attr "alternative" "0")
0b5107cf
JH
1320 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1321 (const_int 0))
1322 (eq (symbol_ref "TARGET_HIMODE_MATH")
1323 (const_int 0))))
6ef67412 1324 (const_string "SI")
e075ae69 1325 ]
9b73c90a 1326 (const_string "HI")))])
e075ae69 1327
d1f87653 1328;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
1329;; We fake an second form of instruction to force reload to load address
1330;; into register when rax is not available
1331(define_insn "*movabshi_1_rex64"
7e6dc358
JJ
1332 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1333 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1334 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 1335 "@
0f40f9f7 1336 movabs{w}\t{%1, %P0|%P0, %1}
7e6dc358 1337 mov{w}\t{%1, %a0|%a0, %1}"
0ec259ed 1338 [(set_attr "type" "imov")
7e6dc358
JJ
1339 (set_attr "modrm" "0,*")
1340 (set_attr "length_address" "8,0")
1341 (set_attr "length_immediate" "0,*")
0ec259ed
JH
1342 (set_attr "memory" "store")
1343 (set_attr "mode" "HI")])
1344
1345(define_insn "*movabshi_2_rex64"
1346 [(set (match_operand:HI 0 "register_operand" "=a,r")
1347 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 1348 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 1349 "@
0f40f9f7
ZW
1350 movabs{w}\t{%P1, %0|%0, %P1}
1351 mov{w}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
1352 [(set_attr "type" "imov")
1353 (set_attr "modrm" "0,*")
1354 (set_attr "length_address" "8,0")
1355 (set_attr "length_immediate" "0")
1356 (set_attr "memory" "load")
1357 (set_attr "mode" "HI")])
1358
e075ae69
RH
1359(define_insn "*swaphi_1"
1360 [(set (match_operand:HI 0 "register_operand" "+r")
1361 (match_operand:HI 1 "register_operand" "+r"))
1362 (set (match_dup 1)
1363 (match_dup 0))]
7cc6af0c
RH
1364 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1365 "xchg{l}\t%k1, %k0"
e075ae69 1366 [(set_attr "type" "imov")
7cc6af0c 1367 (set_attr "mode" "SI")
e075ae69 1368 (set_attr "pent_pair" "np")
7cc6af0c 1369 (set_attr "athlon_decode" "vector")])
e075ae69
RH
1370
1371(define_insn "*swaphi_2"
1372 [(set (match_operand:HI 0 "register_operand" "+r")
1373 (match_operand:HI 1 "register_operand" "+r"))
1374 (set (match_dup 1)
1375 (match_dup 0))]
7cc6af0c
RH
1376 "TARGET_PARTIAL_REG_STALL"
1377 "xchg{w}\t%1, %0"
e075ae69 1378 [(set_attr "type" "imov")
7cc6af0c 1379 (set_attr "mode" "HI")
e075ae69 1380 (set_attr "pent_pair" "np")
7cc6af0c 1381 (set_attr "athlon_decode" "vector")])
886c62d1 1382
2f2a49e8 1383(define_expand "movstricthi"
e075ae69 1384 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2f2a49e8 1385 (match_operand:HI 1 "general_operand" ""))]
b9b2c339 1386 "! TARGET_PARTIAL_REG_STALL || optimize_size"
2f2a49e8
MM
1387{
1388 /* Don't generate memory->memory moves, go through a register */
e075ae69
RH
1389 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1390 operands[1] = force_reg (HImode, operands[1]);
0f40f9f7 1391})
2f2a49e8 1392
e075ae69 1393(define_insn "*movstricthi_1"
fc524c1c 1394 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
e075ae69 1395 (match_operand:HI 1 "general_operand" "rn,m"))]
b9b2c339 1396 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
e075ae69 1397 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 1398 "mov{w}\t{%1, %0|%0, %1}"
6ef67412
JH
1399 [(set_attr "type" "imov")
1400 (set_attr "mode" "HI")])
1401
1402(define_insn "*movstricthi_xor"
208b0ab1 1403 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
6ef67412 1404 (match_operand:HI 1 "const0_operand" "i"))
8bc527af 1405 (clobber (reg:CC FLAGS_REG))]
b9b2c339
JH
1406 "reload_completed
1407 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
0f40f9f7 1408 "xor{w}\t{%0, %0|%0, %0}"
6ef67412
JH
1409 [(set_attr "type" "alu1")
1410 (set_attr "mode" "HI")
1411 (set_attr "length_immediate" "0")])
886c62d1 1412
2f2a49e8 1413(define_expand "movqi"
4cbfbb1b 1414 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2f2a49e8
MM
1415 (match_operand:QI 1 "general_operand" ""))]
1416 ""
e075ae69
RH
1417 "ix86_expand_move (QImode, operands); DONE;")
1418
7dd4b4a3
JH
1419;; emit_push_insn when it calls move_by_pieces requires an insn to
1420;; "push a byte". But actually we use pushw, which has the effect
1421;; of rounding the amount pushed up to a halfword.
1422
1423(define_insn "*pushqi2"
1424 [(set (match_operand:QI 0 "push_operand" "=X,X")
1425 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1426 "!TARGET_64BIT"
1427 "@
0f40f9f7
ZW
1428 push{w}\t{|word ptr }%1
1429 push{w}\t%w1"
7dd4b4a3
JH
1430 [(set_attr "type" "push")
1431 (set_attr "mode" "HI")])
1432
b3298882
JH
1433;; For 64BIT abi we always round up to 8 bytes.
1434(define_insn "*pushqi2_rex64"
1435 [(set (match_operand:QI 0 "push_operand" "=X")
5f90a099 1436 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
b3298882 1437 "TARGET_64BIT"
0f40f9f7 1438 "push{q}\t%q1"
b3298882
JH
1439 [(set_attr "type" "push")
1440 (set_attr "mode" "QI")])
1441
0b5107cf
JH
1442;; Situation is quite tricky about when to choose full sized (SImode) move
1443;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1444;; partial register dependency machines (such as AMD Athlon), where QImode
1445;; moves issue extra dependency and for partial register stalls machines
1446;; that don't use QImode patterns (and QImode move cause stall on the next
1447;; instruction).
1448;;
1449;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1450;; register stall machines with, where we use QImode instructions, since
1451;; partial register stall can be caused there. Then we use movzx.
e075ae69 1452(define_insn "*movqi_1"
0b5107cf
JH
1453 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1454 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
e075ae69 1455 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
886c62d1 1456{
e075ae69 1457 switch (get_attr_type (insn))
b76c90cf 1458 {
e075ae69 1459 case TYPE_IMOVX:
1a06f5fe 1460 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
e075ae69 1461 abort ();
0f40f9f7 1462 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
e075ae69 1463 default:
6ef67412 1464 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 1465 return "mov{l}\t{%k1, %k0|%k0, %k1}";
b76c90cf 1466 else
0f40f9f7 1467 return "mov{b}\t{%1, %0|%0, %1}";
b76c90cf 1468 }
0f40f9f7 1469}
e075ae69 1470 [(set (attr "type")
68f48f39
RS
1471 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1472 (const_string "imov")
1473 (and (eq_attr "alternative" "3")
0b5107cf
JH
1474 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1475 (const_int 0))
1476 (eq (symbol_ref "TARGET_QIMODE_MATH")
1477 (const_int 0))))
1478 (const_string "imov")
1479 (eq_attr "alternative" "3,5")
e075ae69
RH
1480 (const_string "imovx")
1481 (and (ne (symbol_ref "TARGET_MOVX")
1482 (const_int 0))
0b5107cf 1483 (eq_attr "alternative" "2"))
e075ae69
RH
1484 (const_string "imovx")
1485 ]
1486 (const_string "imov")))
6ef67412
JH
1487 (set (attr "mode")
1488 (cond [(eq_attr "alternative" "3,4,5")
1489 (const_string "SI")
1490 (eq_attr "alternative" "6")
1491 (const_string "QI")
1492 (eq_attr "type" "imovx")
1493 (const_string "SI")
0b5107cf 1494 (and (eq_attr "type" "imov")
d49b398c 1495 (and (eq_attr "alternative" "0,1")
0b5107cf
JH
1496 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1497 (const_int 0))))
6ef67412 1498 (const_string "SI")
0b5107cf
JH
1499 ;; Avoid partial register stalls when not using QImode arithmetic
1500 (and (eq_attr "type" "imov")
d49b398c 1501 (and (eq_attr "alternative" "0,1")
0b5107cf
JH
1502 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1503 (const_int 0))
1504 (eq (symbol_ref "TARGET_QIMODE_MATH")
1505 (const_int 0)))))
6ef67412
JH
1506 (const_string "SI")
1507 ]
1508 (const_string "QI")))])
e075ae69
RH
1509
1510(define_expand "reload_outqi"
1511 [(parallel [(match_operand:QI 0 "" "=m")
1512 (match_operand:QI 1 "register_operand" "r")
1513 (match_operand:QI 2 "register_operand" "=&q")])]
1514 ""
e075ae69
RH
1515{
1516 rtx op0, op1, op2;
1517 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
886c62d1 1518
e075ae69
RH
1519 if (reg_overlap_mentioned_p (op2, op0))
1520 abort ();
1521 if (! q_regs_operand (op1, QImode))
1522 {
1523 emit_insn (gen_movqi (op2, op1));
1524 op1 = op2;
1525 }
1526 emit_insn (gen_movqi (op0, op1));
1527 DONE;
0f40f9f7 1528})
886c62d1 1529
7cc6af0c 1530(define_insn "*swapqi_1"
e075ae69
RH
1531 [(set (match_operand:QI 0 "register_operand" "+r")
1532 (match_operand:QI 1 "register_operand" "+r"))
1533 (set (match_dup 1)
1534 (match_dup 0))]
7cc6af0c
RH
1535 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1536 "xchg{l}\t%k1, %k0"
e075ae69 1537 [(set_attr "type" "imov")
7cc6af0c 1538 (set_attr "mode" "SI")
e075ae69 1539 (set_attr "pent_pair" "np")
7cc6af0c
RH
1540 (set_attr "athlon_decode" "vector")])
1541
1542(define_insn "*swapqi_2"
1543 [(set (match_operand:QI 0 "register_operand" "+q")
1544 (match_operand:QI 1 "register_operand" "+q"))
1545 (set (match_dup 1)
1546 (match_dup 0))]
1547 "TARGET_PARTIAL_REG_STALL"
1548 "xchg{b}\t%1, %0"
1549 [(set_attr "type" "imov")
6ef67412 1550 (set_attr "mode" "QI")
7cc6af0c
RH
1551 (set_attr "pent_pair" "np")
1552 (set_attr "athlon_decode" "vector")])
886c62d1 1553
2f2a49e8 1554(define_expand "movstrictqi"
4cbfbb1b 1555 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2f2a49e8 1556 (match_operand:QI 1 "general_operand" ""))]
3c298c88 1557 "! TARGET_PARTIAL_REG_STALL || optimize_size"
2f2a49e8 1558{
e03f5d43 1559 /* Don't generate memory->memory moves, go through a register. */
e075ae69
RH
1560 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1561 operands[1] = force_reg (QImode, operands[1]);
0f40f9f7 1562})
2f2a49e8 1563
e075ae69 1564(define_insn "*movstrictqi_1"
2ae0f82c 1565 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
c0f06344 1566 (match_operand:QI 1 "general_operand" "*qn,m"))]
3c298c88 1567 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
e075ae69 1568 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 1569 "mov{b}\t{%1, %0|%0, %1}"
6ef67412
JH
1570 [(set_attr "type" "imov")
1571 (set_attr "mode" "QI")])
1572
1573(define_insn "*movstrictqi_xor"
5e6d6bf0 1574 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
6ef67412 1575 (match_operand:QI 1 "const0_operand" "i"))
8bc527af 1576 (clobber (reg:CC FLAGS_REG))]
6ef67412 1577 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
0f40f9f7 1578 "xor{b}\t{%0, %0|%0, %0}"
6ef67412
JH
1579 [(set_attr "type" "alu1")
1580 (set_attr "mode" "QI")
1581 (set_attr "length_immediate" "0")])
e075ae69
RH
1582
1583(define_insn "*movsi_extv_1"
d2836273 1584 [(set (match_operand:SI 0 "register_operand" "=R")
3522082b 1585 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1586 (const_int 8)
1587 (const_int 8)))]
1588 ""
0f40f9f7 1589 "movs{bl|x}\t{%h1, %0|%0, %h1}"
6ef67412
JH
1590 [(set_attr "type" "imovx")
1591 (set_attr "mode" "SI")])
e075ae69
RH
1592
1593(define_insn "*movhi_extv_1"
d2836273 1594 [(set (match_operand:HI 0 "register_operand" "=R")
3522082b 1595 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1596 (const_int 8)
1597 (const_int 8)))]
1598 ""
0f40f9f7 1599 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
6ef67412
JH
1600 [(set_attr "type" "imovx")
1601 (set_attr "mode" "SI")])
e075ae69
RH
1602
1603(define_insn "*movqi_extv_1"
0ec259ed 1604 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
3522082b 1605 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
e075ae69
RH
1606 (const_int 8)
1607 (const_int 8)))]
0ec259ed 1608 "!TARGET_64BIT"
886c62d1 1609{
e075ae69 1610 switch (get_attr_type (insn))
886c62d1 1611 {
e075ae69 1612 case TYPE_IMOVX:
0f40f9f7 1613 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
e075ae69 1614 default:
0f40f9f7 1615 return "mov{b}\t{%h1, %0|%0, %h1}";
886c62d1 1616 }
0f40f9f7 1617}
e075ae69
RH
1618 [(set (attr "type")
1619 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1620 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1621 (ne (symbol_ref "TARGET_MOVX")
1622 (const_int 0))))
1623 (const_string "imovx")
6ef67412
JH
1624 (const_string "imov")))
1625 (set (attr "mode")
1626 (if_then_else (eq_attr "type" "imovx")
1627 (const_string "SI")
1628 (const_string "QI")))])
e075ae69 1629
0ec259ed
JH
1630(define_insn "*movqi_extv_1_rex64"
1631 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
3522082b 1632 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
0ec259ed
JH
1633 (const_int 8)
1634 (const_int 8)))]
1635 "TARGET_64BIT"
0ec259ed
JH
1636{
1637 switch (get_attr_type (insn))
1638 {
1639 case TYPE_IMOVX:
0f40f9f7 1640 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
0ec259ed 1641 default:
0f40f9f7 1642 return "mov{b}\t{%h1, %0|%0, %h1}";
0ec259ed 1643 }
0f40f9f7 1644}
0ec259ed
JH
1645 [(set (attr "type")
1646 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1647 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1648 (ne (symbol_ref "TARGET_MOVX")
1649 (const_int 0))))
1650 (const_string "imovx")
1651 (const_string "imov")))
1652 (set (attr "mode")
1653 (if_then_else (eq_attr "type" "imovx")
1654 (const_string "SI")
1655 (const_string "QI")))])
1656
d1f87653 1657;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
1658;; We fake an second form of instruction to force reload to load address
1659;; into register when rax is not available
1660(define_insn "*movabsqi_1_rex64"
7e6dc358
JJ
1661 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1662 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1663 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 1664 "@
5e2ce672 1665 movabs{b}\t{%1, %P0|%P0, %1}
7e6dc358 1666 mov{b}\t{%1, %a0|%a0, %1}"
0ec259ed 1667 [(set_attr "type" "imov")
7e6dc358
JJ
1668 (set_attr "modrm" "0,*")
1669 (set_attr "length_address" "8,0")
1670 (set_attr "length_immediate" "0,*")
0ec259ed
JH
1671 (set_attr "memory" "store")
1672 (set_attr "mode" "QI")])
1673
1674(define_insn "*movabsqi_2_rex64"
1675 [(set (match_operand:QI 0 "register_operand" "=a,r")
1676 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 1677 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 1678 "@
5e2ce672
JH
1679 movabs{b}\t{%P1, %0|%0, %P1}
1680 mov{b}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
1681 [(set_attr "type" "imov")
1682 (set_attr "modrm" "0,*")
1683 (set_attr "length_address" "8,0")
1684 (set_attr "length_immediate" "0")
1685 (set_attr "memory" "load")
1686 (set_attr "mode" "QI")])
1687
e075ae69 1688(define_insn "*movsi_extzv_1"
d2836273
JH
1689 [(set (match_operand:SI 0 "register_operand" "=R")
1690 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1691 (const_int 8)
1692 (const_int 8)))]
1693 ""
0f40f9f7 1694 "movz{bl|x}\t{%h1, %0|%0, %h1}"
6ef67412
JH
1695 [(set_attr "type" "imovx")
1696 (set_attr "mode" "SI")])
886c62d1 1697
d2836273
JH
1698(define_insn "*movqi_extzv_2"
1699 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1700 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
e075ae69
RH
1701 (const_int 8)
1702 (const_int 8)) 0))]
d2836273 1703 "!TARGET_64BIT"
f31fce3f 1704{
e075ae69 1705 switch (get_attr_type (insn))
f31fce3f 1706 {
e075ae69 1707 case TYPE_IMOVX:
0f40f9f7 1708 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
e075ae69 1709 default:
0f40f9f7 1710 return "mov{b}\t{%h1, %0|%0, %h1}";
e075ae69 1711 }
0f40f9f7 1712}
e075ae69
RH
1713 [(set (attr "type")
1714 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1715 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1716 (ne (symbol_ref "TARGET_MOVX")
1717 (const_int 0))))
1718 (const_string "imovx")
6ef67412
JH
1719 (const_string "imov")))
1720 (set (attr "mode")
1721 (if_then_else (eq_attr "type" "imovx")
1722 (const_string "SI")
1723 (const_string "QI")))])
e075ae69 1724
d2836273
JH
1725(define_insn "*movqi_extzv_2_rex64"
1726 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1727 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1728 (const_int 8)
1729 (const_int 8)) 0))]
1730 "TARGET_64BIT"
d2836273
JH
1731{
1732 switch (get_attr_type (insn))
1733 {
1734 case TYPE_IMOVX:
0f40f9f7 1735 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
d2836273 1736 default:
0f40f9f7 1737 return "mov{b}\t{%h1, %0|%0, %h1}";
d2836273 1738 }
0f40f9f7 1739}
d2836273
JH
1740 [(set (attr "type")
1741 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1742 (ne (symbol_ref "TARGET_MOVX")
1743 (const_int 0)))
1744 (const_string "imovx")
1745 (const_string "imov")))
1746 (set (attr "mode")
1747 (if_then_else (eq_attr "type" "imovx")
1748 (const_string "SI")
1749 (const_string "QI")))])
1750
7a2e09f4 1751(define_insn "movsi_insv_1"
d2836273 1752 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
e075ae69
RH
1753 (const_int 8)
1754 (const_int 8))
f47c8646 1755 (match_operand:SI 1 "general_operand" "Qmn"))]
d2836273 1756 "!TARGET_64BIT"
0f40f9f7 1757 "mov{b}\t{%b1, %h0|%h0, %b1}"
d2836273
JH
1758 [(set_attr "type" "imov")
1759 (set_attr "mode" "QI")])
1760
044b3892
L
1761(define_insn "movdi_insv_1_rex64"
1762 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
d2836273
JH
1763 (const_int 8)
1764 (const_int 8))
044b3892 1765 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
d2836273 1766 "TARGET_64BIT"
0f40f9f7 1767 "mov{b}\t{%b1, %h0|%h0, %b1}"
6ef67412
JH
1768 [(set_attr "type" "imov")
1769 (set_attr "mode" "QI")])
e075ae69
RH
1770
1771(define_insn "*movqi_insv_2"
d2836273 1772 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
e075ae69
RH
1773 (const_int 8)
1774 (const_int 8))
99f296a0
KH
1775 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1776 (const_int 8)))]
e075ae69 1777 ""
0f40f9f7 1778 "mov{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
1779 [(set_attr "type" "imov")
1780 (set_attr "mode" "QI")])
f31fce3f 1781
e075ae69 1782(define_expand "movdi"
4cbfbb1b 1783 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69
RH
1784 (match_operand:DI 1 "general_operand" ""))]
1785 ""
1786 "ix86_expand_move (DImode, operands); DONE;")
f31fce3f 1787
e075ae69
RH
1788(define_insn "*pushdi"
1789 [(set (match_operand:DI 0 "push_operand" "=<")
2c5a510c 1790 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1e07edd3 1791 "!TARGET_64BIT"
e075ae69 1792 "#")
f31fce3f 1793
6c4ccfd8 1794(define_insn "*pushdi2_rex64"
0ec259ed
JH
1795 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1796 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1797 "TARGET_64BIT"
1798 "@
0f40f9f7 1799 push{q}\t%1
0ec259ed
JH
1800 #"
1801 [(set_attr "type" "push,multi")
1802 (set_attr "mode" "DI")])
1803
1804;; Convert impossible pushes of immediate to existing instructions.
f5143c46 1805;; First try to get scratch register and go through it. In case this
0ec259ed
JH
1806;; fails, push sign extended lower part first and then overwrite
1807;; upper part by 32bit move.
1808(define_peephole2
1809 [(match_scratch:DI 2 "r")
1810 (set (match_operand:DI 0 "push_operand" "")
1811 (match_operand:DI 1 "immediate_operand" ""))]
1812 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1813 && !x86_64_immediate_operand (operands[1], DImode)"
1814 [(set (match_dup 2) (match_dup 1))
1815 (set (match_dup 0) (match_dup 2))]
1816 "")
1817
1818;; We need to define this as both peepholer and splitter for case
1819;; peephole2 pass is not run.
731edaed 1820;; "&& 1" is needed to keep it from matching the previous pattern.
0ec259ed
JH
1821(define_peephole2
1822 [(set (match_operand:DI 0 "push_operand" "")
1823 (match_operand:DI 1 "immediate_operand" ""))]
1824 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
731edaed 1825 && !x86_64_immediate_operand (operands[1], DImode) && 1"
0ec259ed
JH
1826 [(set (match_dup 0) (match_dup 1))
1827 (set (match_dup 2) (match_dup 3))]
1828 "split_di (operands + 1, 1, operands + 2, operands + 3);
1829 operands[1] = gen_lowpart (DImode, operands[2]);
1830 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1831 GEN_INT (4)));
1832 ")
1833
1834(define_split
1835 [(set (match_operand:DI 0 "push_operand" "")
1836 (match_operand:DI 1 "immediate_operand" ""))]
93330ea1 1837 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
0ec259ed
JH
1838 && !symbolic_operand (operands[1], DImode)
1839 && !x86_64_immediate_operand (operands[1], DImode)"
1840 [(set (match_dup 0) (match_dup 1))
1841 (set (match_dup 2) (match_dup 3))]
1842 "split_di (operands + 1, 1, operands + 2, operands + 3);
1843 operands[1] = gen_lowpart (DImode, operands[2]);
1844 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1845 GEN_INT (4)));
1846 ")
1847
1848(define_insn "*pushdi2_prologue_rex64"
1849 [(set (match_operand:DI 0 "push_operand" "=<")
1850 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
f2042df3 1851 (clobber (mem:BLK (scratch)))]
0ec259ed 1852 "TARGET_64BIT"
0f40f9f7 1853 "push{q}\t%1"
0ec259ed
JH
1854 [(set_attr "type" "push")
1855 (set_attr "mode" "DI")])
1856
1857(define_insn "*popdi1_epilogue_rex64"
1858 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
1859 (mem:DI (reg:DI SP_REG)))
1860 (set (reg:DI SP_REG)
1861 (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 1862 (clobber (mem:BLK (scratch)))]
0ec259ed 1863 "TARGET_64BIT"
0f40f9f7 1864 "pop{q}\t%0"
0ec259ed
JH
1865 [(set_attr "type" "pop")
1866 (set_attr "mode" "DI")])
1867
1868(define_insn "popdi1"
1869 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
8bc527af
SB
1870 (mem:DI (reg:DI SP_REG)))
1871 (set (reg:DI SP_REG)
1872 (plus:DI (reg:DI SP_REG) (const_int 8)))]
0ec259ed 1873 "TARGET_64BIT"
0f40f9f7 1874 "pop{q}\t%0"
0ec259ed
JH
1875 [(set_attr "type" "pop")
1876 (set_attr "mode" "DI")])
1877
1878(define_insn "*movdi_xor_rex64"
1879 [(set (match_operand:DI 0 "register_operand" "=r")
1880 (match_operand:DI 1 "const0_operand" "i"))
8bc527af 1881 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
1882 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1883 && reload_completed"
0f40f9f7 1884 "xor{l}\t{%k0, %k0|%k0, %k0}"
0ec259ed
JH
1885 [(set_attr "type" "alu1")
1886 (set_attr "mode" "SI")
1887 (set_attr "length_immediate" "0")])
1888
1889(define_insn "*movdi_or_rex64"
1890 [(set (match_operand:DI 0 "register_operand" "=r")
1891 (match_operand:DI 1 "const_int_operand" "i"))
8bc527af 1892 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
1893 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1894 && reload_completed
87d9741e 1895 && operands[1] == constm1_rtx"
0ec259ed
JH
1896{
1897 operands[1] = constm1_rtx;
0f40f9f7
ZW
1898 return "or{q}\t{%1, %0|%0, %1}";
1899}
0ec259ed
JH
1900 [(set_attr "type" "alu1")
1901 (set_attr "mode" "DI")
1902 (set_attr "length_immediate" "1")])
1903
e075ae69 1904(define_insn "*movdi_2"
d30c9461
RH
1905 [(set (match_operand:DI 0 "nonimmediate_operand"
1906 "=r ,o ,m*y,*y,m ,*Y,*Y,m ,*x,*x")
1907 (match_operand:DI 1 "general_operand"
1908 "riFo,riF,*y ,m ,*Y,*Y,m ,*x,*x,m "))]
1e07edd3
JH
1909 "!TARGET_64BIT
1910 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
915119a5
BS
1911 "@
1912 #
1913 #
0f40f9f7
ZW
1914 movq\t{%1, %0|%0, %1}
1915 movq\t{%1, %0|%0, %1}
1916 movq\t{%1, %0|%0, %1}
1917 movdqa\t{%1, %0|%0, %1}
d30c9461
RH
1918 movq\t{%1, %0|%0, %1}
1919 movlps\t{%1, %0|%0, %1}
1920 movaps\t{%1, %0|%0, %1}
1921 movlps\t{%1, %0|%0, %1}"
1922 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
1923 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,V2SF,V4SF,V2SF")])
dc0f0eb8 1924
e075ae69
RH
1925(define_split
1926 [(set (match_operand:DI 0 "push_operand" "")
1927 (match_operand:DI 1 "general_operand" ""))]
6c12e488
JH
1928 "!TARGET_64BIT && reload_completed
1929 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2450a057 1930 [(const_int 0)]
26e5b205 1931 "ix86_split_long_move (operands); DONE;")
f31fce3f 1932
e075ae69 1933;; %%% This multiword shite has got to go.
e075ae69 1934(define_split
c76aab11 1935 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69 1936 (match_operand:DI 1 "general_operand" ""))]
6c12e488
JH
1937 "!TARGET_64BIT && reload_completed
1938 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1939 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
26e5b205
JH
1940 [(const_int 0)]
1941 "ix86_split_long_move (operands); DONE;")
0ec259ed
JH
1942
1943(define_insn "*movdi_1_rex64"
6c4ccfd8
RH
1944 [(set (match_operand:DI 0 "nonimmediate_operand"
1945 "=r,r ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1946 (match_operand:DI 1 "general_operand"
1947 "Z ,rem,i,re,n ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1b0c37d7 1948 "TARGET_64BIT
8f62128d 1949 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1b0c37d7 1950 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0ec259ed
JH
1951{
1952 switch (get_attr_type (insn))
1953 {
9e9fb0ce
JB
1954 case TYPE_SSECVT:
1955 if (which_alternative == 11)
1956 return "movq2dq\t{%1, %0|%0, %1}";
1957 else
1958 return "movdq2q\t{%1, %0|%0, %1}";
5f90a099 1959 case TYPE_SSEMOV:
8f62128d 1960 if (get_attr_mode (insn) == MODE_TI)
0f40f9f7 1961 return "movdqa\t{%1, %0|%0, %1}";
5efb1046 1962 /* FALLTHRU */
5ccbcd8c 1963 case TYPE_MMXMOV:
8f62128d
JH
1964 /* Moves from and into integer register is done using movd opcode with
1965 REX prefix. */
1966 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1967 return "movd\t{%1, %0|%0, %1}";
0f40f9f7 1968 return "movq\t{%1, %0|%0, %1}";
0ec259ed 1969 case TYPE_MULTI:
0f40f9f7 1970 return "#";
0ec259ed 1971 case TYPE_LEA:
0f40f9f7 1972 return "lea{q}\t{%a1, %0|%0, %a1}";
0ec259ed 1973 default:
57d47446 1974 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
0ec259ed
JH
1975 abort ();
1976 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 1977 return "mov{l}\t{%k1, %k0|%k0, %k1}";
0ec259ed 1978 else if (which_alternative == 2)
0f40f9f7 1979 return "movabs{q}\t{%1, %0|%0, %1}";
0ec259ed 1980 else
0f40f9f7 1981 return "mov{q}\t{%1, %0|%0, %1}";
0ec259ed 1982 }
0f40f9f7 1983}
0ec259ed 1984 [(set (attr "type")
8f62128d 1985 (cond [(eq_attr "alternative" "5,6,7")
3d34cd91 1986 (const_string "mmxmov")
8f62128d 1987 (eq_attr "alternative" "8,9,10")
3d34cd91 1988 (const_string "ssemov")
9e9fb0ce
JB
1989 (eq_attr "alternative" "11,12")
1990 (const_string "ssecvt")
0ec259ed
JH
1991 (eq_attr "alternative" "4")
1992 (const_string "multi")
1993 (and (ne (symbol_ref "flag_pic") (const_int 0))
1994 (match_operand:DI 1 "symbolic_operand" ""))
1995 (const_string "lea")
1996 ]
1997 (const_string "imov")))
9e9fb0ce
JB
1998 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1999 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2000 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
8f62128d
JH
2001
2002(define_insn "*movdi_1_rex64_nointerunit"
6c4ccfd8
RH
2003 [(set (match_operand:DI 0 "nonimmediate_operand"
2004 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2005 (match_operand:DI 1 "general_operand"
2006 "Z,rem,i,re,n ,*y ,*y,m ,*Y ,*Y,m"))]
8f62128d
JH
2007 "TARGET_64BIT
2008 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2009 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2010{
2011 switch (get_attr_type (insn))
2012 {
2013 case TYPE_SSEMOV:
2014 if (get_attr_mode (insn) == MODE_TI)
2015 return "movdqa\t{%1, %0|%0, %1}";
5efb1046 2016 /* FALLTHRU */
8f62128d
JH
2017 case TYPE_MMXMOV:
2018 return "movq\t{%1, %0|%0, %1}";
2019 case TYPE_MULTI:
2020 return "#";
2021 case TYPE_LEA:
2022 return "lea{q}\t{%a1, %0|%0, %a1}";
2023 default:
2024 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2025 abort ();
2026 if (get_attr_mode (insn) == MODE_SI)
2027 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028 else if (which_alternative == 2)
2029 return "movabs{q}\t{%1, %0|%0, %1}";
2030 else
2031 return "mov{q}\t{%1, %0|%0, %1}";
2032 }
2033}
2034 [(set (attr "type")
2035 (cond [(eq_attr "alternative" "5,6,7")
2036 (const_string "mmxmov")
2037 (eq_attr "alternative" "8,9,10")
2038 (const_string "ssemov")
2039 (eq_attr "alternative" "4")
2040 (const_string "multi")
2041 (and (ne (symbol_ref "flag_pic") (const_int 0))
2042 (match_operand:DI 1 "symbolic_operand" ""))
2043 (const_string "lea")
2044 ]
2045 (const_string "imov")))
2046 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2047 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2048 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
0ec259ed 2049
d1f87653 2050;; Stores and loads of ax to arbitrary constant address.
0ec259ed
JH
2051;; We fake an second form of instruction to force reload to load address
2052;; into register when rax is not available
2053(define_insn "*movabsdi_1_rex64"
7e6dc358
JJ
2054 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2055 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2056 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
0ec259ed 2057 "@
0f40f9f7 2058 movabs{q}\t{%1, %P0|%P0, %1}
7e6dc358 2059 mov{q}\t{%1, %a0|%a0, %1}"
0ec259ed 2060 [(set_attr "type" "imov")
7e6dc358
JJ
2061 (set_attr "modrm" "0,*")
2062 (set_attr "length_address" "8,0")
2063 (set_attr "length_immediate" "0,*")
0ec259ed
JH
2064 (set_attr "memory" "store")
2065 (set_attr "mode" "DI")])
2066
2067(define_insn "*movabsdi_2_rex64"
2068 [(set (match_operand:DI 0 "register_operand" "=a,r")
2069 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
7e6dc358 2070 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
0ec259ed 2071 "@
0f40f9f7
ZW
2072 movabs{q}\t{%P1, %0|%0, %P1}
2073 mov{q}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
2074 [(set_attr "type" "imov")
2075 (set_attr "modrm" "0,*")
2076 (set_attr "length_address" "8,0")
2077 (set_attr "length_immediate" "0")
2078 (set_attr "memory" "load")
2079 (set_attr "mode" "DI")])
2080
2081;; Convert impossible stores of immediate to existing instructions.
f5143c46 2082;; First try to get scratch register and go through it. In case this
0ec259ed
JH
2083;; fails, move by 32bit parts.
2084(define_peephole2
2085 [(match_scratch:DI 2 "r")
2086 (set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode)"
2090 [(set (match_dup 2) (match_dup 1))
2091 (set (match_dup 0) (match_dup 2))]
2092 "")
2093
2094;; We need to define this as both peepholer and splitter for case
2095;; peephole2 pass is not run.
731edaed 2096;; "&& 1" is needed to keep it from matching the previous pattern.
0ec259ed
JH
2097(define_peephole2
2098 [(set (match_operand:DI 0 "memory_operand" "")
2099 (match_operand:DI 1 "immediate_operand" ""))]
2100 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
731edaed 2101 && !x86_64_immediate_operand (operands[1], DImode) && 1"
0ec259ed
JH
2102 [(set (match_dup 2) (match_dup 3))
2103 (set (match_dup 4) (match_dup 5))]
2104 "split_di (operands, 2, operands + 2, operands + 4);")
2105
2106(define_split
2107 [(set (match_operand:DI 0 "memory_operand" "")
2108 (match_operand:DI 1 "immediate_operand" ""))]
93330ea1 2109 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
0ec259ed
JH
2110 && !symbolic_operand (operands[1], DImode)
2111 && !x86_64_immediate_operand (operands[1], DImode)"
2112 [(set (match_dup 2) (match_dup 3))
2113 (set (match_dup 4) (match_dup 5))]
2114 "split_di (operands, 2, operands + 2, operands + 4);")
2115
2116(define_insn "*swapdi_rex64"
2117 [(set (match_operand:DI 0 "register_operand" "+r")
2118 (match_operand:DI 1 "register_operand" "+r"))
2119 (set (match_dup 1)
2120 (match_dup 0))]
2121 "TARGET_64BIT"
0f40f9f7 2122 "xchg{q}\t%1, %0"
0ec259ed 2123 [(set_attr "type" "imov")
0ec259ed 2124 (set_attr "mode" "DI")
7cc6af0c
RH
2125 (set_attr "pent_pair" "np")
2126 (set_attr "athlon_decode" "vector")])
0ec259ed 2127
ef719a44
RH
2128(define_expand "movti"
2129 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2130 (match_operand:TI 1 "nonimmediate_operand" ""))]
2131 "TARGET_SSE || TARGET_64BIT"
2132{
2133 if (TARGET_64BIT)
2134 ix86_expand_move (TImode, operands);
2135 else
2136 ix86_expand_vector_move (TImode, operands);
2137 DONE;
2138})
2139
2140(define_insn "*movti_internal"
2141 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2142 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2143 "TARGET_SSE && !TARGET_64BIT
2144 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2145{
2146 switch (which_alternative)
2147 {
2148 case 0:
2149 if (get_attr_mode (insn) == MODE_V4SF)
2150 return "xorps\t%0, %0";
2151 else
2152 return "pxor\t%0, %0";
2153 case 1:
2154 case 2:
2155 if (get_attr_mode (insn) == MODE_V4SF)
2156 return "movaps\t{%1, %0|%0, %1}";
2157 else
2158 return "movdqa\t{%1, %0|%0, %1}";
2159 default:
2160 abort ();
2161 }
2162}
2163 [(set_attr "type" "ssemov,ssemov,ssemov")
2164 (set (attr "mode")
2165 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2166 (const_string "V4SF")
2167
2168 (eq_attr "alternative" "0,1")
2169 (if_then_else
2170 (ne (symbol_ref "optimize_size")
2171 (const_int 0))
2172 (const_string "V4SF")
2173 (const_string "TI"))
2174 (eq_attr "alternative" "2")
2175 (if_then_else
2176 (ne (symbol_ref "optimize_size")
2177 (const_int 0))
2178 (const_string "V4SF")
2179 (const_string "TI"))]
2180 (const_string "TI")))])
2181
2182(define_insn "*movti_rex64"
2183 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2184 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2185 "TARGET_64BIT
2186 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2187{
2188 switch (which_alternative)
2189 {
2190 case 0:
2191 case 1:
2192 return "#";
2193 case 2:
2194 if (get_attr_mode (insn) == MODE_V4SF)
2195 return "xorps\t%0, %0";
2196 else
2197 return "pxor\t%0, %0";
2198 case 3:
2199 case 4:
2200 if (get_attr_mode (insn) == MODE_V4SF)
2201 return "movaps\t{%1, %0|%0, %1}";
2202 else
2203 return "movdqa\t{%1, %0|%0, %1}";
2204 default:
2205 abort ();
2206 }
2207}
2208 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2209 (set (attr "mode")
2210 (cond [(eq_attr "alternative" "2,3")
2211 (if_then_else
2212 (ne (symbol_ref "optimize_size")
2213 (const_int 0))
2214 (const_string "V4SF")
2215 (const_string "TI"))
2216 (eq_attr "alternative" "4")
2217 (if_then_else
2218 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2219 (const_int 0))
2220 (ne (symbol_ref "optimize_size")
2221 (const_int 0)))
2222 (const_string "V4SF")
2223 (const_string "TI"))]
2224 (const_string "DI")))])
2225
2226(define_split
2227 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2228 (match_operand:TI 1 "general_operand" ""))]
2229 "reload_completed && !SSE_REG_P (operands[0])
2230 && !SSE_REG_P (operands[1])"
2231 [(const_int 0)]
2232 "ix86_split_long_move (operands); DONE;")
2233
0be5d99f 2234(define_expand "movsf"
4cbfbb1b 2235 [(set (match_operand:SF 0 "nonimmediate_operand" "")
0be5d99f
MM
2236 (match_operand:SF 1 "general_operand" ""))]
2237 ""
e075ae69
RH
2238 "ix86_expand_move (SFmode, operands); DONE;")
2239
2240(define_insn "*pushsf"
446988df 2241 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
c6e95f34 2242 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
0ec259ed 2243 "!TARGET_64BIT"
0be5d99f 2244{
e075ae69 2245 switch (which_alternative)
0be5d99f 2246 {
e075ae69 2247 case 1:
0f40f9f7 2248 return "push{l}\t%1";
e075ae69
RH
2249
2250 default:
839a4992 2251 /* This insn should be already split before reg-stack. */
e075ae69 2252 abort ();
0bb6c81b 2253 }
0f40f9f7 2254}
446988df
JH
2255 [(set_attr "type" "multi,push,multi")
2256 (set_attr "mode" "SF,SI,SF")])
0be5d99f 2257
0ec259ed
JH
2258(define_insn "*pushsf_rex64"
2259 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2260 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2261 "TARGET_64BIT"
0ec259ed
JH
2262{
2263 switch (which_alternative)
2264 {
0ec259ed 2265 case 1:
0f40f9f7 2266 return "push{q}\t%q1";
0ec259ed 2267
0ec259ed 2268 default:
839a4992 2269 /* This insn should be already split before reg-stack. */
0ec259ed
JH
2270 abort ();
2271 }
0f40f9f7 2272}
0ec259ed
JH
2273 [(set_attr "type" "multi,push,multi")
2274 (set_attr "mode" "SF,DI,SF")])
2275
d7a29404
JH
2276(define_split
2277 [(set (match_operand:SF 0 "push_operand" "")
2278 (match_operand:SF 1 "memory_operand" ""))]
2279 "reload_completed
2280 && GET_CODE (operands[1]) == MEM
2281 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2282 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2283 [(set (match_dup 0)
2284 (match_dup 1))]
2285 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2286
2287
e075ae69
RH
2288;; %%% Kill this when call knows how to work this out.
2289(define_split
2290 [(set (match_operand:SF 0 "push_operand" "")
c3c637e3
GS
2291 (match_operand:SF 1 "any_fp_register_operand" ""))]
2292 "!TARGET_64BIT"
8bc527af
SB
2293 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2294 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
e075ae69 2295
0ec259ed
JH
2296(define_split
2297 [(set (match_operand:SF 0 "push_operand" "")
c3c637e3
GS
2298 (match_operand:SF 1 "any_fp_register_operand" ""))]
2299 "TARGET_64BIT"
8bc527af
SB
2300 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2301 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
0ec259ed 2302
e075ae69 2303(define_insn "*movsf_1"
6c4ccfd8
RH
2304 [(set (match_operand:SF 0 "nonimmediate_operand"
2305 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2306 (match_operand:SF 1 "general_operand"
2307 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
8f62128d
JH
2308 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2309 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2310 && (reload_in_progress || reload_completed
2311 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2312 || GET_CODE (operands[1]) != CONST_DOUBLE
2313 || memory_operand (operands[0], SFmode))"
2314{
2315 switch (which_alternative)
2316 {
2317 case 0:
5ea9cb6e 2318 return output_387_reg_move (insn, operands);
8f62128d
JH
2319
2320 case 1:
2321 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2322 return "fstp%z0\t%y0";
2323 else
2324 return "fst%z0\t%y0";
2325
2326 case 2:
881b2a96 2327 return standard_80387_constant_opcode (operands[1]);
8f62128d
JH
2328
2329 case 3:
2330 case 4:
2331 return "mov{l}\t{%1, %0|%0, %1}";
2332 case 5:
2333 if (get_attr_mode (insn) == MODE_TI)
2334 return "pxor\t%0, %0";
2335 else
2336 return "xorps\t%0, %0";
2337 case 6:
2338 if (get_attr_mode (insn) == MODE_V4SF)
2339 return "movaps\t{%1, %0|%0, %1}";
2340 else
2341 return "movss\t{%1, %0|%0, %1}";
2342 case 7:
2343 case 8:
2344 return "movss\t{%1, %0|%0, %1}";
2345
2346 case 9:
2347 case 10:
2348 return "movd\t{%1, %0|%0, %1}";
2349
2350 case 11:
2351 return "movq\t{%1, %0|%0, %1}";
2352
2353 default:
2354 abort();
2355 }
2356}
2357 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2358 (set (attr "mode")
2359 (cond [(eq_attr "alternative" "3,4,9,10")
2360 (const_string "SI")
2361 (eq_attr "alternative" "5")
2362 (if_then_else
2363 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2364 (const_int 0))
2365 (ne (symbol_ref "TARGET_SSE2")
2366 (const_int 0)))
2367 (eq (symbol_ref "optimize_size")
2368 (const_int 0)))
2369 (const_string "TI")
2370 (const_string "V4SF"))
2371 /* For architectures resolving dependencies on
2372 whole SSE registers use APS move to break dependency
2373 chains, otherwise use short move to avoid extra work.
2374
2375 Do the same for architectures resolving dependencies on
2376 the parts. While in DF mode it is better to always handle
2377 just register parts, the SF mode is different due to lack
2378 of instructions to load just part of the register. It is
2379 better to maintain the whole registers in single format
2380 to avoid problems on using packed logical operations. */
2381 (eq_attr "alternative" "6")
2382 (if_then_else
2383 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2384 (const_int 0))
41afe4ef 2385 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
8f62128d
JH
2386 (const_int 0)))
2387 (const_string "V4SF")
2388 (const_string "SF"))
2389 (eq_attr "alternative" "11")
2390 (const_string "DI")]
2391 (const_string "SF")))])
2392
2393(define_insn "*movsf_1_nointerunit"
6c4ccfd8
RH
2394 [(set (match_operand:SF 0 "nonimmediate_operand"
2395 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!m,!*y")
2396 (match_operand:SF 1 "general_operand"
2397 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,m ,*y,*y"))]
8f62128d
JH
2398 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2399 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
d7a29404 2400 && (reload_in_progress || reload_completed
3987b9db 2401 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
d7a29404
JH
2402 || GET_CODE (operands[1]) != CONST_DOUBLE
2403 || memory_operand (operands[0], SFmode))"
886c62d1 2404{
e075ae69 2405 switch (which_alternative)
886c62d1 2406 {
e075ae69 2407 case 0:
5ea9cb6e 2408 return output_387_reg_move (insn, operands);
886c62d1 2409
e075ae69
RH
2410 case 1:
2411 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2412 return "fstp%z0\t%y0";
886c62d1 2413 else
0f40f9f7 2414 return "fst%z0\t%y0";
886c62d1 2415
e075ae69 2416 case 2:
881b2a96 2417 return standard_80387_constant_opcode (operands[1]);
886c62d1 2418
e075ae69
RH
2419 case 3:
2420 case 4:
0f40f9f7 2421 return "mov{l}\t{%1, %0|%0, %1}";
446988df 2422 case 5:
4977bab6 2423 if (get_attr_mode (insn) == MODE_TI)
692efa8e
JJ
2424 return "pxor\t%0, %0";
2425 else
2426 return "xorps\t%0, %0";
446988df 2427 case 6:
4977bab6 2428 if (get_attr_mode (insn) == MODE_V4SF)
0f40f9f7 2429 return "movaps\t{%1, %0|%0, %1}";
2b04e52b 2430 else
0f40f9f7 2431 return "movss\t{%1, %0|%0, %1}";
2b04e52b
JH
2432 case 7:
2433 case 8:
0f40f9f7 2434 return "movss\t{%1, %0|%0, %1}";
886c62d1 2435
ac300a45
JJ
2436 case 9:
2437 case 10:
2438 return "movd\t{%1, %0|%0, %1}";
2439
e5a20888
JJ
2440 case 11:
2441 return "movq\t{%1, %0|%0, %1}";
2442
e075ae69
RH
2443 default:
2444 abort();
2445 }
0f40f9f7 2446}
3d34cd91 2447 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
4977bab6
ZW
2448 (set (attr "mode")
2449 (cond [(eq_attr "alternative" "3,4,9,10")
2450 (const_string "SI")
2451 (eq_attr "alternative" "5")
2452 (if_then_else
2453 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2454 (const_int 0))
2455 (ne (symbol_ref "TARGET_SSE2")
2456 (const_int 0)))
2457 (eq (symbol_ref "optimize_size")
2458 (const_int 0)))
2459 (const_string "TI")
2460 (const_string "V4SF"))
2461 /* For architectures resolving dependencies on
2462 whole SSE registers use APS move to break dependency
2463 chains, otherwise use short move to avoid extra work.
2464
2465 Do the same for architectures resolving dependencies on
2466 the parts. While in DF mode it is better to always handle
2467 just register parts, the SF mode is different due to lack
2468 of instructions to load just part of the register. It is
2469 better to maintain the whole registers in single format
2470 to avoid problems on using packed logical operations. */
2471 (eq_attr "alternative" "6")
2472 (if_then_else
2473 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2474 (const_int 0))
41afe4ef 2475 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
4977bab6
ZW
2476 (const_int 0)))
2477 (const_string "V4SF")
2478 (const_string "SF"))
2479 (eq_attr "alternative" "11")
2480 (const_string "DI")]
2481 (const_string "SF")))])
d7a29404 2482
a4414093 2483(define_insn "*swapsf"
6c4ccfd8
RH
2484 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2485 (match_operand:SF 1 "fp_register_operand" "+f"))
0be5d99f
MM
2486 (set (match_dup 1)
2487 (match_dup 0))]
6c4ccfd8 2488 "reload_completed || TARGET_80387"
0be5d99f
MM
2489{
2490 if (STACK_TOP_P (operands[0]))
0f40f9f7 2491 return "fxch\t%1";
0be5d99f 2492 else
0f40f9f7
ZW
2493 return "fxch\t%0";
2494}
6ef67412
JH
2495 [(set_attr "type" "fxch")
2496 (set_attr "mode" "SF")])
0be5d99f 2497
e075ae69 2498(define_expand "movdf"
4cbfbb1b 2499 [(set (match_operand:DF 0 "nonimmediate_operand" "")
e075ae69
RH
2500 (match_operand:DF 1 "general_operand" ""))]
2501 ""
2502 "ix86_expand_move (DFmode, operands); DONE;")
55953cea 2503
8fcaaa80 2504;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
d1f87653 2505;; Size of pushdf using integer instructions is 2+2*memory operand size
8fcaaa80
JH
2506;; On the average, pushdf using integers can be still shorter. Allow this
2507;; pattern for optimize_size too.
2508
0b5107cf 2509(define_insn "*pushdf_nointeger"
446988df 2510 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
c6e95f34 2511 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
0ec259ed 2512 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
0b5107cf 2513{
839a4992 2514 /* This insn should be already split before reg-stack. */
4977bab6 2515 abort ();
0f40f9f7 2516}
6ef67412 2517 [(set_attr "type" "multi")
446988df 2518 (set_attr "mode" "DF,SI,SI,DF")])
0b5107cf
JH
2519
2520(define_insn "*pushdf_integer"
446988df
JH
2521 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2522 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
0ec259ed 2523 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
f31fce3f 2524{
839a4992 2525 /* This insn should be already split before reg-stack. */
4977bab6 2526 abort ();
0f40f9f7 2527}
6ef67412 2528 [(set_attr "type" "multi")
446988df 2529 (set_attr "mode" "DF,SI,DF")])
f31fce3f 2530
e075ae69 2531;; %%% Kill this when call knows how to work this out.
f72b27a5
JH
2532(define_split
2533 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3
GS
2534 (match_operand:DF 1 "any_fp_register_operand" ""))]
2535 "!TARGET_64BIT && reload_completed"
8bc527af
SB
2536 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2537 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
f72b27a5 2538 "")
f31fce3f 2539
0ec259ed
JH
2540(define_split
2541 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3
GS
2542 (match_operand:DF 1 "any_fp_register_operand" ""))]
2543 "TARGET_64BIT && reload_completed"
8bc527af
SB
2544 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2545 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
0ec259ed
JH
2546 "")
2547
e075ae69
RH
2548(define_split
2549 [(set (match_operand:DF 0 "push_operand" "")
0be5d99f 2550 (match_operand:DF 1 "general_operand" ""))]
e075ae69 2551 "reload_completed"
2450a057 2552 [(const_int 0)]
26e5b205 2553 "ix86_split_long_move (operands); DONE;")
0be5d99f 2554
8fcaaa80
JH
2555;; Moving is usually shorter when only FP registers are used. This separate
2556;; movdf pattern avoids the use of integer registers for FP operations
2557;; when optimizing for size.
2558
2559(define_insn "*movdf_nointeger"
6c4ccfd8 2560 [(set (match_operand:DF 0 "nonimmediate_operand"
d30c9461 2561 "=f#Y,m ,f#Y,*r ,o ,Y#f*x,Y#f*x,Y#f*x ,m ")
6c4ccfd8 2562 (match_operand:DF 1 "general_operand"
d30c9461 2563 "fm#Y,f#Y,G ,*roF,F*r,C ,Y#f*x,HmY#f*x,Y#f*x"))]
8fcaaa80 2564 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
4977bab6 2565 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
d7a29404 2566 && (reload_in_progress || reload_completed
3987b9db 2567 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
d7a29404
JH
2568 || GET_CODE (operands[1]) != CONST_DOUBLE
2569 || memory_operand (operands[0], DFmode))"
8fcaaa80
JH
2570{
2571 switch (which_alternative)
2572 {
2573 case 0:
5ea9cb6e 2574 return output_387_reg_move (insn, operands);
8fcaaa80
JH
2575
2576 case 1:
2577 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2578 return "fstp%z0\t%y0";
8fcaaa80 2579 else
0f40f9f7 2580 return "fst%z0\t%y0";
8fcaaa80
JH
2581
2582 case 2:
881b2a96 2583 return standard_80387_constant_opcode (operands[1]);
8fcaaa80
JH
2584
2585 case 3:
2586 case 4:
0f40f9f7 2587 return "#";
446988df 2588 case 5:
4977bab6
ZW
2589 switch (get_attr_mode (insn))
2590 {
2591 case MODE_V4SF:
2592 return "xorps\t%0, %0";
2593 case MODE_V2DF:
2594 return "xorpd\t%0, %0";
2595 case MODE_TI:
2596 return "pxor\t%0, %0";
2597 default:
2598 abort ();
2599 }
446988df 2600 case 6:
6c4ccfd8
RH
2601 case 7:
2602 case 8:
4977bab6
ZW
2603 switch (get_attr_mode (insn))
2604 {
2605 case MODE_V4SF:
2606 return "movaps\t{%1, %0|%0, %1}";
2607 case MODE_V2DF:
2608 return "movapd\t{%1, %0|%0, %1}";
6c4ccfd8
RH
2609 case MODE_TI:
2610 return "movdqa\t{%1, %0|%0, %1}";
2611 case MODE_DI:
2612 return "movq\t{%1, %0|%0, %1}";
4977bab6
ZW
2613 case MODE_DF:
2614 return "movsd\t{%1, %0|%0, %1}";
6c4ccfd8
RH
2615 case MODE_V1DF:
2616 return "movlpd\t{%1, %0|%0, %1}";
d30c9461
RH
2617 case MODE_V2SF:
2618 return "movlps\t{%1, %0|%0, %1}";
4977bab6
ZW
2619 default:
2620 abort ();
2621 }
8fcaaa80
JH
2622
2623 default:
2624 abort();
2625 }
0f40f9f7 2626}
3d34cd91 2627 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
4977bab6 2628 (set (attr "mode")
d30c9461
RH
2629 (cond [(eq_attr "alternative" "0,1,2")
2630 (const_string "DF")
2631 (eq_attr "alternative" "3,4")
4977bab6 2632 (const_string "SI")
6c4ccfd8
RH
2633
2634 /* For SSE1, we have many fewer alternatives. */
2635 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2636 (cond [(eq_attr "alternative" "5,6")
d30c9461 2637 (const_string "V4SF")
6c4ccfd8 2638 ]
d30c9461 2639 (const_string "V2SF"))
6c4ccfd8 2640
4977bab6
ZW
2641 /* xorps is one byte shorter. */
2642 (eq_attr "alternative" "5")
2643 (cond [(ne (symbol_ref "optimize_size")
2644 (const_int 0))
2645 (const_string "V4SF")
2646 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2647 (const_int 0))
6c4ccfd8
RH
2648 (const_string "TI")
2649 ]
4977bab6 2650 (const_string "V2DF"))
6c4ccfd8 2651
4977bab6
ZW
2652 /* For architectures resolving dependencies on
2653 whole SSE registers use APD move to break dependency
2654 chains, otherwise use short move to avoid extra work.
2655
2656 movaps encodes one byte shorter. */
2657 (eq_attr "alternative" "6")
2658 (cond
6c4ccfd8
RH
2659 [(ne (symbol_ref "optimize_size")
2660 (const_int 0))
2661 (const_string "V4SF")
2662 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2663 (const_int 0))
2664 (const_string "V2DF")
2665 ]
4977bab6 2666 (const_string "DF"))
d1f87653 2667 /* For architectures resolving dependencies on register
4977bab6
ZW
2668 parts we may avoid extra work to zero out upper part
2669 of register. */
2670 (eq_attr "alternative" "7")
2671 (if_then_else
41afe4ef 2672 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
4977bab6 2673 (const_int 0))
6c4ccfd8
RH
2674 (const_string "V1DF")
2675 (const_string "DF"))
2676 ]
2677 (const_string "DF")))])
8fcaaa80
JH
2678
2679(define_insn "*movdf_integer"
6c4ccfd8 2680 [(set (match_operand:DF 0 "nonimmediate_operand"
d30c9461 2681 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y#rf*x,Y#rf*x,Y#rf*x,m")
6c4ccfd8 2682 (match_operand:DF 1 "general_operand"
d30c9461 2683 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y#rf*x,m ,Y#rf*x"))]
8fcaaa80 2684 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
4977bab6 2685 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
d7a29404 2686 && (reload_in_progress || reload_completed
3987b9db 2687 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
d7a29404
JH
2688 || GET_CODE (operands[1]) != CONST_DOUBLE
2689 || memory_operand (operands[0], DFmode))"
886c62d1 2690{
e075ae69 2691 switch (which_alternative)
886c62d1 2692 {
e075ae69 2693 case 0:
5ea9cb6e 2694 return output_387_reg_move (insn, operands);
886c62d1 2695
e075ae69
RH
2696 case 1:
2697 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2698 return "fstp%z0\t%y0";
886c62d1 2699 else
0f40f9f7 2700 return "fst%z0\t%y0";
886c62d1 2701
e075ae69 2702 case 2:
881b2a96 2703 return standard_80387_constant_opcode (operands[1]);
886c62d1 2704
e075ae69
RH
2705 case 3:
2706 case 4:
0f40f9f7 2707 return "#";
886c62d1 2708
446988df 2709 case 5:
4977bab6
ZW
2710 switch (get_attr_mode (insn))
2711 {
2712 case MODE_V4SF:
2713 return "xorps\t%0, %0";
2714 case MODE_V2DF:
2715 return "xorpd\t%0, %0";
2716 case MODE_TI:
2717 return "pxor\t%0, %0";
2718 default:
2719 abort ();
2720 }
446988df 2721 case 6:
6c4ccfd8
RH
2722 case 7:
2723 case 8:
4977bab6
ZW
2724 switch (get_attr_mode (insn))
2725 {
2726 case MODE_V4SF:
2727 return "movaps\t{%1, %0|%0, %1}";
2728 case MODE_V2DF:
2729 return "movapd\t{%1, %0|%0, %1}";
6c4ccfd8
RH
2730 case MODE_TI:
2731 return "movdqa\t{%1, %0|%0, %1}";
2732 case MODE_DI:
2733 return "movq\t{%1, %0|%0, %1}";
4977bab6
ZW
2734 case MODE_DF:
2735 return "movsd\t{%1, %0|%0, %1}";
6c4ccfd8
RH
2736 case MODE_V1DF:
2737 return "movlpd\t{%1, %0|%0, %1}";
d30c9461
RH
2738 case MODE_V2SF:
2739 return "movlps\t{%1, %0|%0, %1}";
4977bab6
ZW
2740 default:
2741 abort ();
2742 }
446988df 2743
e075ae69
RH
2744 default:
2745 abort();
2746 }
0f40f9f7 2747}
3d34cd91 2748 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
4977bab6 2749 (set (attr "mode")
d30c9461
RH
2750 (cond [(eq_attr "alternative" "0,1,2")
2751 (const_string "DF")
2752 (eq_attr "alternative" "3,4")
4977bab6 2753 (const_string "SI")
6c4ccfd8
RH
2754
2755 /* For SSE1, we have many fewer alternatives. */
2756 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2757 (cond [(eq_attr "alternative" "5,6")
d30c9461 2758 (const_string "V4SF")
6c4ccfd8 2759 ]
d30c9461 2760 (const_string "V2SF"))
6c4ccfd8 2761
4977bab6
ZW
2762 /* xorps is one byte shorter. */
2763 (eq_attr "alternative" "5")
2764 (cond [(ne (symbol_ref "optimize_size")
2765 (const_int 0))
2766 (const_string "V4SF")
2767 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2768 (const_int 0))
6c4ccfd8
RH
2769 (const_string "TI")
2770 ]
4977bab6 2771 (const_string "V2DF"))
6c4ccfd8 2772
4977bab6
ZW
2773 /* For architectures resolving dependencies on
2774 whole SSE registers use APD move to break dependency
6c4ccfd8 2775 chains, otherwise use short move to avoid extra work.
4977bab6
ZW
2776
2777 movaps encodes one byte shorter. */
2778 (eq_attr "alternative" "6")
2779 (cond
6c4ccfd8
RH
2780 [(ne (symbol_ref "optimize_size")
2781 (const_int 0))
2782 (const_string "V4SF")
2783 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2784 (const_int 0))
2785 (const_string "V2DF")
2786 ]
4977bab6 2787 (const_string "DF"))
d1f87653 2788 /* For architectures resolving dependencies on register
4977bab6
ZW
2789 parts we may avoid extra work to zero out upper part
2790 of register. */
2791 (eq_attr "alternative" "7")
2792 (if_then_else
41afe4ef 2793 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
4977bab6 2794 (const_int 0))
6c4ccfd8
RH
2795 (const_string "V1DF")
2796 (const_string "DF"))
2797 ]
2798 (const_string "DF")))])
2ae0f82c 2799
e075ae69
RH
2800(define_split
2801 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2802 (match_operand:DF 1 "general_operand" ""))]
2803 "reload_completed
2804 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
446988df 2805 && ! (ANY_FP_REG_P (operands[0]) ||
e075ae69 2806 (GET_CODE (operands[0]) == SUBREG
446988df
JH
2807 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2808 && ! (ANY_FP_REG_P (operands[1]) ||
e075ae69 2809 (GET_CODE (operands[1]) == SUBREG
446988df 2810 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
26e5b205
JH
2811 [(const_int 0)]
2812 "ix86_split_long_move (operands); DONE;")
886c62d1 2813
a4414093 2814(define_insn "*swapdf"
6c4ccfd8
RH
2815 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2816 (match_operand:DF 1 "fp_register_operand" "+f"))
0be5d99f
MM
2817 (set (match_dup 1)
2818 (match_dup 0))]
6c4ccfd8 2819 "reload_completed || TARGET_80387"
0be5d99f
MM
2820{
2821 if (STACK_TOP_P (operands[0]))
0f40f9f7 2822 return "fxch\t%1";
0be5d99f 2823 else
0f40f9f7
ZW
2824 return "fxch\t%0";
2825}
6ef67412
JH
2826 [(set_attr "type" "fxch")
2827 (set_attr "mode" "DF")])
e075ae69
RH
2828
2829(define_expand "movxf"
4cbfbb1b 2830 [(set (match_operand:XF 0 "nonimmediate_operand" "")
e075ae69 2831 (match_operand:XF 1 "general_operand" ""))]
2b589241 2832 ""
f8a1ebc6 2833 "ix86_expand_move (XFmode, operands); DONE;")
2b589241 2834
8fcaaa80 2835;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
d1f87653 2836;; Size of pushdf using integer instructions is 3+3*memory operand size
8fcaaa80
JH
2837;; Pushing using integer instructions is longer except for constants
2838;; and direct memory references.
2839;; (assuming that any given constant is pushed only once, but this ought to be
2840;; handled elsewhere).
2841
2842(define_insn "*pushxf_nointeger"
1e07edd3 2843 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2c5a510c 2844 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2b589241 2845 "optimize_size"
2b589241 2846{
839a4992 2847 /* This insn should be already split before reg-stack. */
4977bab6 2848 abort ();
0f40f9f7 2849}
2b589241
JH
2850 [(set_attr "type" "multi")
2851 (set_attr "mode" "XF,SI,SI")])
2852
8fcaaa80 2853(define_insn "*pushxf_integer"
2450a057 2854 [(set (match_operand:XF 0 "push_operand" "=<,<")
1e07edd3 2855 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2b589241 2856 "!optimize_size"
2b589241 2857{
839a4992 2858 /* This insn should be already split before reg-stack. */
4977bab6 2859 abort ();
0f40f9f7 2860}
2b589241
JH
2861 [(set_attr "type" "multi")
2862 (set_attr "mode" "XF,SI")])
2863
2450a057 2864(define_split
2b589241
JH
2865 [(set (match_operand 0 "push_operand" "")
2866 (match_operand 1 "general_operand" ""))]
2450a057 2867 "reload_completed
2b589241 2868 && (GET_MODE (operands[0]) == XFmode
2b589241 2869 || GET_MODE (operands[0]) == DFmode)
c3c637e3 2870 && !ANY_FP_REG_P (operands[1])"
2450a057 2871 [(const_int 0)]
26e5b205 2872 "ix86_split_long_move (operands); DONE;")
2450a057 2873
f72b27a5
JH
2874(define_split
2875 [(set (match_operand:XF 0 "push_operand" "")
c3c637e3 2876 (match_operand:XF 1 "any_fp_register_operand" ""))]
c3c637e3 2877 "!TARGET_64BIT"
8bc527af
SB
2878 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2879 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
f8a1ebc6 2880 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2b589241 2881
0ec259ed 2882(define_split
f8a1ebc6
JH
2883 [(set (match_operand:XF 0 "push_operand" "")
2884 (match_operand:XF 1 "any_fp_register_operand" ""))]
c3c637e3 2885 "TARGET_64BIT"
8bc527af
SB
2886 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2887 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
f8a1ebc6 2888 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
0ec259ed 2889
8fcaaa80
JH
2890;; Do not use integer registers when optimizing for size
2891(define_insn "*movxf_nointeger"
2892 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2893 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
f8a1ebc6 2894 "optimize_size
1b0c37d7 2895 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
d7a29404
JH
2896 && (reload_in_progress || reload_completed
2897 || GET_CODE (operands[1]) != CONST_DOUBLE
2898 || memory_operand (operands[0], XFmode))"
0be5d99f 2899{
8fcaaa80
JH
2900 switch (which_alternative)
2901 {
2902 case 0:
5ea9cb6e 2903 return output_387_reg_move (insn, operands);
0be5d99f 2904
8fcaaa80
JH
2905 case 1:
2906 /* There is no non-popping store to memory for XFmode. So if
2907 we need one, follow the store with a load. */
2908 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2909 return "fstp%z0\t%y0\;fld%z0\t%y0";
8fcaaa80 2910 else
0f40f9f7 2911 return "fstp%z0\t%y0";
8fcaaa80
JH
2912
2913 case 2:
881b2a96 2914 return standard_80387_constant_opcode (operands[1]);
8fcaaa80
JH
2915
2916 case 3: case 4:
0f40f9f7 2917 return "#";
8fcaaa80
JH
2918 }
2919 abort();
0f40f9f7 2920}
6ef67412
JH
2921 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2922 (set_attr "mode" "XF,XF,XF,SI,SI")])
8fcaaa80
JH
2923
2924(define_insn "*movxf_integer"
2925 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2926 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
f8a1ebc6 2927 "!optimize_size
1b0c37d7 2928 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
d7a29404
JH
2929 && (reload_in_progress || reload_completed
2930 || GET_CODE (operands[1]) != CONST_DOUBLE
2931 || memory_operand (operands[0], XFmode))"
4fb21e90 2932{
e075ae69 2933 switch (which_alternative)
4fb21e90 2934 {
e075ae69 2935 case 0:
5ea9cb6e 2936 return output_387_reg_move (insn, operands);
4fb21e90 2937
e075ae69
RH
2938 case 1:
2939 /* There is no non-popping store to memory for XFmode. So if
2940 we need one, follow the store with a load. */
2941 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2942 return "fstp%z0\t%y0\;fld%z0\t%y0";
e075ae69 2943 else
0f40f9f7 2944 return "fstp%z0\t%y0";
2f17722a 2945
e075ae69 2946 case 2:
881b2a96 2947 return standard_80387_constant_opcode (operands[1]);
467403ca
RH
2948
2949 case 3: case 4:
0f40f9f7 2950 return "#";
4fb21e90 2951 }
e075ae69 2952 abort();
0f40f9f7 2953}
6ef67412
JH
2954 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2955 (set_attr "mode" "XF,XF,XF,SI,SI")])
4fb21e90 2956
467403ca 2957(define_split
2b589241
JH
2958 [(set (match_operand 0 "nonimmediate_operand" "")
2959 (match_operand 1 "general_operand" ""))]
2450a057 2960 "reload_completed
8fcaaa80 2961 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
f8a1ebc6 2962 && GET_MODE (operands[0]) == XFmode
446988df 2963 && ! (ANY_FP_REG_P (operands[0]) ||
8fcaaa80 2964 (GET_CODE (operands[0]) == SUBREG
446988df
JH
2965 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2966 && ! (ANY_FP_REG_P (operands[1]) ||
8fcaaa80 2967 (GET_CODE (operands[1]) == SUBREG
446988df 2968 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
26e5b205
JH
2969 [(const_int 0)]
2970 "ix86_split_long_move (operands); DONE;")
467403ca 2971
d7a29404 2972(define_split
2b589241
JH
2973 [(set (match_operand 0 "register_operand" "")
2974 (match_operand 1 "memory_operand" ""))]
d7a29404
JH
2975 "reload_completed
2976 && GET_CODE (operands[1]) == MEM
f8a1ebc6 2977 && (GET_MODE (operands[0]) == XFmode
2b04e52b 2978 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
d7a29404 2979 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
b87cfcfb
RH
2980 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2981 [(set (match_dup 0) (match_dup 1))]
2982{
2983 rtx c = get_pool_constant (XEXP (operands[1], 0));
2984 rtx r = operands[0];
2985
2986 if (GET_CODE (r) == SUBREG)
2987 r = SUBREG_REG (r);
2988
2989 if (SSE_REG_P (r))
2990 {
2991 if (!standard_sse_constant_p (c))
2992 FAIL;
2993 }
2994 else if (FP_REG_P (r))
2995 {
2996 if (!standard_80387_constant_p (c))
2997 FAIL;
2998 }
2999 else if (MMX_REG_P (r))
3000 FAIL;
3001
3002 operands[1] = c;
3003})
d7a29404 3004
e075ae69
RH
3005(define_insn "swapxf"
3006 [(set (match_operand:XF 0 "register_operand" "+f")
3007 (match_operand:XF 1 "register_operand" "+f"))
0be5d99f
MM
3008 (set (match_dup 1)
3009 (match_dup 0))]
6c4ccfd8 3010 "TARGET_80387"
0be5d99f
MM
3011{
3012 if (STACK_TOP_P (operands[0]))
0f40f9f7 3013 return "fxch\t%1";
0be5d99f 3014 else
0f40f9f7
ZW
3015 return "fxch\t%0";
3016}
0b5107cf 3017 [(set_attr "type" "fxch")
6ef67412 3018 (set_attr "mode" "XF")])
ef719a44
RH
3019
3020(define_expand "movtf"
3021 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3022 (match_operand:TF 1 "nonimmediate_operand" ""))]
3023 "TARGET_64BIT"
3024{
3025 ix86_expand_move (TFmode, operands);
3026 DONE;
3027})
3028
3029(define_insn "*movtf_internal"
3030 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3031 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3032 "TARGET_64BIT
3033 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3034{
3035 switch (which_alternative)
3036 {
3037 case 0:
3038 case 1:
3039 return "#";
3040 case 2:
3041 if (get_attr_mode (insn) == MODE_V4SF)
3042 return "xorps\t%0, %0";
3043 else
3044 return "pxor\t%0, %0";
3045 case 3:
3046 case 4:
3047 if (get_attr_mode (insn) == MODE_V4SF)
3048 return "movaps\t{%1, %0|%0, %1}";
3049 else
3050 return "movdqa\t{%1, %0|%0, %1}";
3051 default:
3052 abort ();
3053 }
3054}
3055 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
3056 (set (attr "mode")
3057 (cond [(eq_attr "alternative" "2,3")
3058 (if_then_else
3059 (ne (symbol_ref "optimize_size")
3060 (const_int 0))
3061 (const_string "V4SF")
3062 (const_string "TI"))
3063 (eq_attr "alternative" "4")
3064 (if_then_else
3065 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3066 (const_int 0))
3067 (ne (symbol_ref "optimize_size")
3068 (const_int 0)))
3069 (const_string "V4SF")
3070 (const_string "TI"))]
3071 (const_string "DI")))])
3072
3073(define_split
3074 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3075 (match_operand:TF 1 "general_operand" ""))]
3076 "reload_completed && !SSE_REG_P (operands[0])
3077 && !SSE_REG_P (operands[1])"
3078 [(const_int 0)]
3079 "ix86_split_long_move (operands); DONE;")
886c62d1 3080\f
e075ae69 3081;; Zero extension instructions
886c62d1 3082
8f7661f2
JH
3083(define_expand "zero_extendhisi2"
3084 [(set (match_operand:SI 0 "register_operand" "")
3085 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
d626200a 3086 ""
e075ae69 3087{
8f7661f2 3088 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2ae0f82c 3089 {
8f7661f2
JH
3090 operands[1] = force_reg (HImode, operands[1]);
3091 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3092 DONE;
2ae0f82c 3093 }
0f40f9f7 3094})
886c62d1 3095
8f7661f2
JH
3096(define_insn "zero_extendhisi2_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r")
3098 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
8bc527af 3099 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
3100 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3101 "#"
6ef67412
JH
3102 [(set_attr "type" "alu1")
3103 (set_attr "mode" "SI")])
2ae0f82c
SC
3104
3105(define_split
3106 [(set (match_operand:SI 0 "register_operand" "")
8f7661f2 3107 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
8bc527af 3108 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
3109 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3110 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
8bc527af 3111 (clobber (reg:CC FLAGS_REG))])]
d626200a
JL
3112 "")
3113
8f7661f2
JH
3114(define_insn "*zero_extendhisi2_movzwl"
3115 [(set (match_operand:SI 0 "register_operand" "=r")
3116 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3117 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
0f40f9f7 3118 "movz{wl|x}\t{%1, %0|%0, %1}"
6ef67412
JH
3119 [(set_attr "type" "imovx")
3120 (set_attr "mode" "SI")])
8f7661f2
JH
3121
3122(define_expand "zero_extendqihi2"
3123 [(parallel
3124 [(set (match_operand:HI 0 "register_operand" "")
3125 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 3126 (clobber (reg:CC FLAGS_REG))])]
e075ae69 3127 ""
8f7661f2
JH
3128 "")
3129
3130(define_insn "*zero_extendqihi2_and"
3131 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3132 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
8bc527af 3133 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
3134 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3135 "#"
6ef67412
JH
3136 [(set_attr "type" "alu1")
3137 (set_attr "mode" "HI")])
8f7661f2
JH
3138
3139(define_insn "*zero_extendqihi2_movzbw_and"
3140 [(set (match_operand:HI 0 "register_operand" "=r,r")
3141 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
8bc527af 3142 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
3143 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3144 "#"
6ef67412
JH
3145 [(set_attr "type" "imovx,alu1")
3146 (set_attr "mode" "HI")])
886c62d1 3147
8f7661f2
JH
3148(define_insn "*zero_extendqihi2_movzbw"
3149 [(set (match_operand:HI 0 "register_operand" "=r")
3150 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1c27d4b2 3151 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
0f40f9f7 3152 "movz{bw|x}\t{%1, %0|%0, %1}"
6ef67412
JH
3153 [(set_attr "type" "imovx")
3154 (set_attr "mode" "HI")])
8f7661f2
JH
3155
3156;; For the movzbw case strip only the clobber
2ae0f82c
SC
3157(define_split
3158 [(set (match_operand:HI 0 "register_operand" "")
e075ae69 3159 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 3160 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
3161 "reload_completed
3162 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
1a06f5fe 3163 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2
JH
3164 [(set (match_operand:HI 0 "register_operand" "")
3165 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2ae0f82c 3166
8f7661f2
JH
3167;; When source and destination does not overlap, clear destination
3168;; first and then do the movb
2ae0f82c
SC
3169(define_split
3170 [(set (match_operand:HI 0 "register_operand" "")
8f7661f2 3171 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 3172 (clobber (reg:CC FLAGS_REG))]
e075ae69 3173 "reload_completed
1a06f5fe 3174 && ANY_QI_REG_P (operands[0])
8f7661f2
JH
3175 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3176 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3177 [(set (match_dup 0) (const_int 0))
3178 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3179 "operands[2] = gen_lowpart (QImode, operands[0]);")
2ae0f82c 3180
8f7661f2 3181;; Rest is handled by single and.
2ae0f82c
SC
3182(define_split
3183 [(set (match_operand:HI 0 "register_operand" "")
e075ae69 3184 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
8bc527af 3185 (clobber (reg:CC FLAGS_REG))]
e075ae69 3186 "reload_completed
8f7661f2
JH
3187 && true_regnum (operands[0]) == true_regnum (operands[1])"
3188 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
8bc527af 3189 (clobber (reg:CC FLAGS_REG))])]
d626200a
JL
3190 "")
3191
8f7661f2
JH
3192(define_expand "zero_extendqisi2"
3193 [(parallel
3194 [(set (match_operand:SI 0 "register_operand" "")
3195 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 3196 (clobber (reg:CC FLAGS_REG))])]
e075ae69 3197 ""
8f7661f2
JH
3198 "")
3199
3200(define_insn "*zero_extendqisi2_and"
3201 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3202 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
8bc527af 3203 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
3204 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3205 "#"
6ef67412
JH
3206 [(set_attr "type" "alu1")
3207 (set_attr "mode" "SI")])
8f7661f2
JH
3208
3209(define_insn "*zero_extendqisi2_movzbw_and"
3210 [(set (match_operand:SI 0 "register_operand" "=r,r")
3211 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
8bc527af 3212 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
3213 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3214 "#"
6ef67412
JH
3215 [(set_attr "type" "imovx,alu1")
3216 (set_attr "mode" "SI")])
2ae0f82c 3217
8f7661f2
JH
3218(define_insn "*zero_extendqisi2_movzbw"
3219 [(set (match_operand:SI 0 "register_operand" "=r")
3220 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3221 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
0f40f9f7 3222 "movz{bl|x}\t{%1, %0|%0, %1}"
6ef67412
JH
3223 [(set_attr "type" "imovx")
3224 (set_attr "mode" "SI")])
8f7661f2
JH
3225
3226;; For the movzbl case strip only the clobber
3227(define_split
3228 [(set (match_operand:SI 0 "register_operand" "")
3229 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 3230 (clobber (reg:CC FLAGS_REG))]
8f7661f2
JH
3231 "reload_completed
3232 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
1a06f5fe 3233 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2
JH
3234 [(set (match_dup 0)
3235 (zero_extend:SI (match_dup 1)))])
3236
3237;; When source and destination does not overlap, clear destination
3238;; first and then do the movb
2ae0f82c
SC
3239(define_split
3240 [(set (match_operand:SI 0 "register_operand" "")
e075ae69 3241 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 3242 (clobber (reg:CC FLAGS_REG))]
e075ae69 3243 "reload_completed
1a06f5fe
JH
3244 && ANY_QI_REG_P (operands[0])
3245 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
8f7661f2 3246 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
e075ae69 3247 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8f7661f2
JH
3248 [(set (match_dup 0) (const_int 0))
3249 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3250 "operands[2] = gen_lowpart (QImode, operands[0]);")
2ae0f82c 3251
8f7661f2 3252;; Rest is handled by single and.
2ae0f82c
SC
3253(define_split
3254 [(set (match_operand:SI 0 "register_operand" "")
e075ae69 3255 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
8bc527af 3256 (clobber (reg:CC FLAGS_REG))]
e075ae69 3257 "reload_completed
8f7661f2
JH
3258 && true_regnum (operands[0]) == true_regnum (operands[1])"
3259 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
8bc527af 3260 (clobber (reg:CC FLAGS_REG))])]
e075ae69 3261 "")
2ae0f82c 3262
e075ae69 3263;; %%% Kill me once multi-word ops are sane.
123bf9e3
JH
3264(define_expand "zero_extendsidi2"
3265 [(set (match_operand:DI 0 "register_operand" "=r")
3266 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3267 ""
3268 "if (!TARGET_64BIT)
3269 {
3270 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3271 DONE;
3272 }
3273 ")
3274
3275(define_insn "zero_extendsidi2_32"
ebe75517
JH
3276 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3277 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
8bc527af 3278 (clobber (reg:CC FLAGS_REG))]
ebe75517
JH
3279 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3280 "@
3281 #
3282 #
3283 #
3284 movd\t{%1, %0|%0, %1}
3285 movd\t{%1, %0|%0, %1}"
3286 [(set_attr "mode" "SI,SI,SI,DI,TI")
3287 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3288
3289(define_insn "*zero_extendsidi2_32_1"
3290 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3291 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
8bc527af 3292 (clobber (reg:CC FLAGS_REG))]
ebe75517
JH
3293 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3294 "@
3295 #
3296 #
3297 #
3298 movd\t{%1, %0|%0, %1}
3299 movd\t{%1, %0|%0, %1}"
3300 [(set_attr "mode" "SI,SI,SI,DI,TI")
3301 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
2ae0f82c 3302
123bf9e3 3303(define_insn "zero_extendsidi2_rex64"
ebe75517
JH
3304 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3305 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3306 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
123bf9e3 3307 "@
0f40f9f7 3308 mov\t{%k1, %k0|%k0, %k1}
ebe75517
JH
3309 #
3310 movd\t{%1, %0|%0, %1}
3311 movd\t{%1, %0|%0, %1}"
3312 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3313 (set_attr "mode" "SI,DI,DI,TI")])
3314
3315(define_insn "*zero_extendsidi2_rex64_1"
3316 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3317 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3318 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3319 "@
3320 mov\t{%k1, %k0|%k0, %k1}
3321 #
3322 movd\t{%1, %0|%0, %1}
3323 movd\t{%1, %0|%0, %1}"
3324 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3325 (set_attr "mode" "SI,DI,SI,SI")])
123bf9e3
JH
3326
3327(define_split
3328 [(set (match_operand:DI 0 "memory_operand" "")
3329 (zero_extend:DI (match_dup 0)))]
1b0c37d7 3330 "TARGET_64BIT"
123bf9e3
JH
3331 [(set (match_dup 4) (const_int 0))]
3332 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3333
bb62e19a
JH
3334(define_split
3335 [(set (match_operand:DI 0 "register_operand" "")
e075ae69 3336 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3337 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
3338 "!TARGET_64BIT && reload_completed
3339 && true_regnum (operands[0]) == true_regnum (operands[1])"
591702de 3340 [(set (match_dup 4) (const_int 0))]
bb62e19a
JH
3341 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3342
3343(define_split
3344 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69 3345 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
8bc527af 3346 (clobber (reg:CC FLAGS_REG))]
ebe75517
JH
3347 "!TARGET_64BIT && reload_completed
3348 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
bb62e19a 3349 [(set (match_dup 3) (match_dup 1))
591702de 3350 (set (match_dup 4) (const_int 0))]
bb62e19a 3351 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
123bf9e3
JH
3352
3353(define_insn "zero_extendhidi2"
3354 [(set (match_operand:DI 0 "register_operand" "=r,r")
3355 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3356 "TARGET_64BIT"
3357 "@
5a0855a0 3358 movz{wl|x}\t{%1, %k0|%k0, %1}
0f40f9f7 3359 movz{wq|x}\t{%1, %0|%0, %1}"
123bf9e3
JH
3360 [(set_attr "type" "imovx")
3361 (set_attr "mode" "SI,DI")])
3362
3363(define_insn "zero_extendqidi2"
3364 [(set (match_operand:DI 0 "register_operand" "=r,r")
3365 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3366 "TARGET_64BIT"
3367 "@
5a0855a0 3368 movz{bl|x}\t{%1, %k0|%k0, %1}
0f40f9f7 3369 movz{bq|x}\t{%1, %0|%0, %1}"
123bf9e3
JH
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI,DI")])
886c62d1 3372\f
e075ae69 3373;; Sign extension instructions
886c62d1 3374
123bf9e3
JH
3375(define_expand "extendsidi2"
3376 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3377 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3378 (clobber (reg:CC FLAGS_REG))
123bf9e3
JH
3379 (clobber (match_scratch:SI 2 ""))])]
3380 ""
123bf9e3
JH
3381{
3382 if (TARGET_64BIT)
3383 {
3384 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3385 DONE;
3386 }
0f40f9f7 3387})
123bf9e3
JH
3388
3389(define_insn "*extendsidi2_1"
e075ae69
RH
3390 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3391 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
8bc527af 3392 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3393 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
123bf9e3 3394 "!TARGET_64BIT"
724d568a
JH
3395 "#")
3396
123bf9e3
JH
3397(define_insn "extendsidi2_rex64"
3398 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3399 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3400 "TARGET_64BIT"
3401 "@
3402 {cltq|cdqe}
0f40f9f7 3403 movs{lq|x}\t{%1,%0|%0, %1}"
123bf9e3
JH
3404 [(set_attr "type" "imovx")
3405 (set_attr "mode" "DI")
3406 (set_attr "prefix_0f" "0")
3407 (set_attr "modrm" "0,1")])
3408
3409(define_insn "extendhidi2"
3410 [(set (match_operand:DI 0 "register_operand" "=r")
3411 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3412 "TARGET_64BIT"
0f40f9f7 3413 "movs{wq|x}\t{%1,%0|%0, %1}"
123bf9e3
JH
3414 [(set_attr "type" "imovx")
3415 (set_attr "mode" "DI")])
3416
3417(define_insn "extendqidi2"
3418 [(set (match_operand:DI 0 "register_operand" "=r")
3419 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3420 "TARGET_64BIT"
0f40f9f7 3421 "movs{bq|x}\t{%1,%0|%0, %1}"
123bf9e3
JH
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "DI")])
3424
724d568a
JH
3425;; Extend to memory case when source register does die.
3426(define_split
3427 [(set (match_operand:DI 0 "memory_operand" "")
3428 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3429 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3430 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 3431 "(reload_completed
724d568a
JH
3432 && dead_or_set_p (insn, operands[1])
3433 && !reg_mentioned_p (operands[1], operands[0]))"
3434 [(set (match_dup 3) (match_dup 1))
e075ae69 3435 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
8bc527af 3436 (clobber (reg:CC FLAGS_REG))])
724d568a
JH
3437 (set (match_dup 4) (match_dup 1))]
3438 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3439
3440;; Extend to memory case when source register does not die.
3441(define_split
3442 [(set (match_operand:DI 0 "memory_operand" "")
3443 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3444 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3445 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 3446 "reload_completed"
724d568a 3447 [(const_int 0)]
9c530261 3448{
724d568a
JH
3449 split_di (&operands[0], 1, &operands[3], &operands[4]);
3450
3451 emit_move_insn (operands[3], operands[1]);
3452
3453 /* Generate a cltd if possible and doing so it profitable. */
3454 if (true_regnum (operands[1]) == 0
3455 && true_regnum (operands[2]) == 1
e075ae69 3456 && (optimize_size || TARGET_USE_CLTD))
71a247f0 3457 {
e075ae69 3458 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
724d568a
JH
3459 }
3460 else
3461 {
3462 emit_move_insn (operands[2], operands[1]);
e075ae69 3463 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
71a247f0 3464 }
724d568a
JH
3465 emit_move_insn (operands[4], operands[2]);
3466 DONE;
0f40f9f7 3467})
9c530261 3468
724d568a
JH
3469;; Extend to register case. Optimize case where source and destination
3470;; registers match and cases where we can use cltd.
3471(define_split
3472 [(set (match_operand:DI 0 "register_operand" "")
3473 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
8bc527af 3474 (clobber (reg:CC FLAGS_REG))
6b29b0e2 3475 (clobber (match_scratch:SI 2 ""))]
724d568a
JH
3476 "reload_completed"
3477 [(const_int 0)]
724d568a
JH
3478{
3479 split_di (&operands[0], 1, &operands[3], &operands[4]);
3480
3481 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3482 emit_move_insn (operands[3], operands[1]);
9c530261 3483
724d568a
JH
3484 /* Generate a cltd if possible and doing so it profitable. */
3485 if (true_regnum (operands[3]) == 0
e075ae69 3486 && (optimize_size || TARGET_USE_CLTD))
724d568a 3487 {
e075ae69 3488 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
724d568a
JH
3489 DONE;
3490 }
3491
3492 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3493 emit_move_insn (operands[4], operands[1]);
3494
e075ae69 3495 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
724d568a 3496 DONE;
0f40f9f7 3497})
886c62d1 3498
886c62d1 3499(define_insn "extendhisi2"
e075ae69
RH
3500 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3501 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
886c62d1 3502 ""
886c62d1 3503{
6ef67412 3504 switch (get_attr_prefix_0f (insn))
e075ae69 3505 {
6ef67412 3506 case 0:
0f40f9f7 3507 return "{cwtl|cwde}";
e075ae69 3508 default:
0f40f9f7 3509 return "movs{wl|x}\t{%1,%0|%0, %1}";
e075ae69 3510 }
0f40f9f7 3511}
e075ae69 3512 [(set_attr "type" "imovx")
6ef67412
JH
3513 (set_attr "mode" "SI")
3514 (set (attr "prefix_0f")
3515 ;; movsx is short decodable while cwtl is vector decoded.
3516 (if_then_else (and (eq_attr "cpu" "!k6")
3517 (eq_attr "alternative" "0"))
3518 (const_string "0")
3519 (const_string "1")))
3520 (set (attr "modrm")
3521 (if_then_else (eq_attr "prefix_0f" "0")
3522 (const_string "0")
3523 (const_string "1")))])
886c62d1 3524
123bf9e3
JH
3525(define_insn "*extendhisi2_zext"
3526 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3527 (zero_extend:DI
3528 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3529 "TARGET_64BIT"
123bf9e3
JH
3530{
3531 switch (get_attr_prefix_0f (insn))
3532 {
3533 case 0:
0f40f9f7 3534 return "{cwtl|cwde}";
123bf9e3 3535 default:
0f40f9f7 3536 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
123bf9e3 3537 }
0f40f9f7 3538}
123bf9e3
JH
3539 [(set_attr "type" "imovx")
3540 (set_attr "mode" "SI")
3541 (set (attr "prefix_0f")
3542 ;; movsx is short decodable while cwtl is vector decoded.
3543 (if_then_else (and (eq_attr "cpu" "!k6")
3544 (eq_attr "alternative" "0"))
3545 (const_string "0")
3546 (const_string "1")))
3547 (set (attr "modrm")
3548 (if_then_else (eq_attr "prefix_0f" "0")
3549 (const_string "0")
3550 (const_string "1")))])
3551
886c62d1 3552(define_insn "extendqihi2"
e075ae69
RH
3553 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3554 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
886c62d1 3555 ""
886c62d1 3556{
6ef67412 3557 switch (get_attr_prefix_0f (insn))
e075ae69 3558 {
6ef67412 3559 case 0:
0f40f9f7 3560 return "{cbtw|cbw}";
e075ae69 3561 default:
0f40f9f7 3562 return "movs{bw|x}\t{%1,%0|%0, %1}";
e075ae69 3563 }
0f40f9f7 3564}
e075ae69 3565 [(set_attr "type" "imovx")
6ef67412
JH
3566 (set_attr "mode" "HI")
3567 (set (attr "prefix_0f")
3568 ;; movsx is short decodable while cwtl is vector decoded.
3569 (if_then_else (and (eq_attr "cpu" "!k6")
3570 (eq_attr "alternative" "0"))
3571 (const_string "0")
3572 (const_string "1")))
3573 (set (attr "modrm")
3574 (if_then_else (eq_attr "prefix_0f" "0")
3575 (const_string "0")
3576 (const_string "1")))])
886c62d1
JVA
3577
3578(define_insn "extendqisi2"
2ae0f82c
SC
3579 [(set (match_operand:SI 0 "register_operand" "=r")
3580 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
886c62d1 3581 ""
0f40f9f7 3582 "movs{bl|x}\t{%1,%0|%0, %1}"
6ef67412
JH
3583 [(set_attr "type" "imovx")
3584 (set_attr "mode" "SI")])
123bf9e3
JH
3585
3586(define_insn "*extendqisi2_zext"
3587 [(set (match_operand:DI 0 "register_operand" "=r")
3588 (zero_extend:DI
3589 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3590 "TARGET_64BIT"
0f40f9f7 3591 "movs{bl|x}\t{%1,%k0|%k0, %1}"
123bf9e3
JH
3592 [(set_attr "type" "imovx")
3593 (set_attr "mode" "SI")])
886c62d1
JVA
3594\f
3595;; Conversions between float and double.
3596
e075ae69
RH
3597;; These are all no-ops in the model used for the 80387. So just
3598;; emit moves.
6a4a5d95 3599
e075ae69 3600;; %%% Kill these when call knows how to work out a DFmode push earlier.
6343a50e 3601(define_insn "*dummy_extendsfdf2"
e075ae69 3602 [(set (match_operand:DF 0 "push_operand" "=<")
42a0aa6f 3603 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
e075ae69
RH
3604 "0"
3605 "#")
6a4a5d95
JW
3606
3607(define_split
e075ae69 3608 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3
GS
3609 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3610 "!TARGET_64BIT"
8bc527af
SB
3611 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3612 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
0fcad513 3613
123bf9e3
JH
3614(define_split
3615 [(set (match_operand:DF 0 "push_operand" "")
c3c637e3
GS
3616 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3617 "TARGET_64BIT"
8bc527af
SB
3618 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3619 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
123bf9e3 3620
6343a50e 3621(define_insn "*dummy_extendsfxf2"
e075ae69
RH
3622 [(set (match_operand:XF 0 "push_operand" "=<")
3623 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3624 "0"
3625 "#")
e4ad1003
JW
3626
3627(define_split
e075ae69 3628 [(set (match_operand:XF 0 "push_operand" "")
c3c637e3 3629 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
f8a1ebc6 3630 ""
8bc527af
SB
3631 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3632 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
f8a1ebc6 3633 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
123bf9e3
JH
3634
3635(define_split
f8a1ebc6
JH
3636 [(set (match_operand:XF 0 "push_operand" "")
3637 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
c3c637e3 3638 "TARGET_64BIT"
8bc527af
SB
3639 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3640 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
f8a1ebc6 3641 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
e4ad1003
JW
3642
3643(define_split
e075ae69 3644 [(set (match_operand:XF 0 "push_operand" "")
c3c637e3 3645 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
f8a1ebc6 3646 ""
8bc527af
SB
3647 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3648 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
f8a1ebc6 3649 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4fb21e90 3650
123bf9e3 3651(define_split
f8a1ebc6
JH
3652 [(set (match_operand:XF 0 "push_operand" "")
3653 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
c3c637e3 3654 "TARGET_64BIT"
8bc527af
SB
3655 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3656 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
f8a1ebc6 3657 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
123bf9e3 3658
f97d9ec3
JH
3659(define_expand "extendsfdf2"
3660 [(set (match_operand:DF 0 "nonimmediate_operand" "")
51286de6 3661 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
2312581e 3662 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
f97d9ec3 3663{
51286de6
RH
3664 /* ??? Needed for compress_float_constant since all fp constants
3665 are LEGITIMATE_CONSTANT_P. */
3666 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3667 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
f97d9ec3 3668 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 3669 operands[1] = force_reg (SFmode, operands[1]);
0f40f9f7 3670})
f97d9ec3 3671
2312581e
UB
3672(define_insn "*extendsfdf2_mixed"
3673 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
a811cc63 3674 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
2312581e 3675 "TARGET_SSE2 && TARGET_MIX_SSE_I387
f97d9ec3 3676 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4fb21e90 3677{
e075ae69 3678 switch (which_alternative)
4fb21e90 3679 {
e075ae69 3680 case 0:
5ea9cb6e 3681 return output_387_reg_move (insn, operands);
886c62d1 3682
e075ae69
RH
3683 case 1:
3684 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3685 return "fstp%z0\t%y0";
e075ae69 3686 else
0f40f9f7 3687 return "fst%z0\t%y0";
5ea9cb6e 3688
42a0aa6f 3689 case 2:
0f40f9f7 3690 return "cvtss2sd\t{%1, %0|%0, %1}";
4fb21e90 3691
e075ae69
RH
3692 default:
3693 abort ();
3694 }
0f40f9f7 3695}
3d34cd91 3696 [(set_attr "type" "fmov,fmov,ssecvt")
a811cc63 3697 (set_attr "mode" "SF,XF,DF")])
42a0aa6f 3698
2312581e 3699(define_insn "*extendsfdf2_sse"
42a0aa6f
JH
3700 [(set (match_operand:DF 0 "register_operand" "=Y")
3701 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
2312581e 3702 "TARGET_SSE2 && TARGET_SSE_MATH
42a0aa6f 3703 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 3704 "cvtss2sd\t{%1, %0|%0, %1}"
3d34cd91 3705 [(set_attr "type" "ssecvt")
42a0aa6f 3706 (set_attr "mode" "DF")])
e075ae69 3707
2312581e
UB
3708(define_insn "*extendsfdf2_i387"
3709 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3710 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3711 "TARGET_80387
3712 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3713{
3714 switch (which_alternative)
3715 {
3716 case 0:
3717 return output_387_reg_move (insn, operands);
3718
3719 case 1:
3720 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3721 return "fstp%z0\t%y0";
3722 else
3723 return "fst%z0\t%y0";
3724
3725 default:
3726 abort ();
3727 }
3728}
3729 [(set_attr "type" "fmov")
3730 (set_attr "mode" "SF,XF")])
3731
f97d9ec3
JH
3732(define_expand "extendsfxf2"
3733 [(set (match_operand:XF 0 "nonimmediate_operand" "")
51286de6 3734 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
f8a1ebc6 3735 "TARGET_80387"
f97d9ec3 3736{
51286de6
RH
3737 /* ??? Needed for compress_float_constant since all fp constants
3738 are LEGITIMATE_CONSTANT_P. */
3739 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3740 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
f97d9ec3 3741 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 3742 operands[1] = force_reg (SFmode, operands[1]);
0f40f9f7 3743})
f97d9ec3 3744
2312581e 3745(define_insn "*extendsfxf2_i387"
e075ae69
RH
3746 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3747 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2b589241
JH
3748 "TARGET_80387
3749 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2b589241
JH
3750{
3751 switch (which_alternative)
3752 {
3753 case 0:
5ea9cb6e 3754 return output_387_reg_move (insn, operands);
2b589241
JH
3755
3756 case 1:
3757 /* There is no non-popping store to memory for XFmode. So if
3758 we need one, follow the store with a load. */
2312581e 3759 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3760 return "fstp%z0\t%y0";
2312581e
UB
3761 else
3762 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
2b589241
JH
3763
3764 default:
3765 abort ();
3766 }
0f40f9f7 3767}
2b589241
JH
3768 [(set_attr "type" "fmov")
3769 (set_attr "mode" "SF,XF")])
3770
f97d9ec3
JH
3771(define_expand "extenddfxf2"
3772 [(set (match_operand:XF 0 "nonimmediate_operand" "")
51286de6 3773 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
f8a1ebc6 3774 "TARGET_80387"
f97d9ec3 3775{
51286de6
RH
3776 /* ??? Needed for compress_float_constant since all fp constants
3777 are LEGITIMATE_CONSTANT_P. */
3778 if (GET_CODE (operands[1]) == CONST_DOUBLE)
110b3faa 3779 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
f97d9ec3 3780 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 3781 operands[1] = force_reg (DFmode, operands[1]);
0f40f9f7 3782})
f97d9ec3 3783
2312581e 3784(define_insn "*extenddfxf2_i387"
e075ae69
RH
3785 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3786 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
2b589241
JH
3787 "TARGET_80387
3788 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2b589241
JH
3789{
3790 switch (which_alternative)
3791 {
3792 case 0:
5ea9cb6e 3793 return output_387_reg_move (insn, operands);
2b589241
JH
3794
3795 case 1:
3796 /* There is no non-popping store to memory for XFmode. So if
3797 we need one, follow the store with a load. */
3798 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3799 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
2b589241 3800 else
0f40f9f7 3801 return "fstp%z0\t%y0";
2b589241
JH
3802
3803 default:
3804 abort ();
3805 }
0f40f9f7 3806}
2b589241
JH
3807 [(set_attr "type" "fmov")
3808 (set_attr "mode" "DF,XF")])
3809
e075ae69
RH
3810;; %%% This seems bad bad news.
3811;; This cannot output into an f-reg because there is no way to be sure
3812;; of truncating in that case. Otherwise this is just like a simple move
3813;; insn. So we pretend we can output to a reg in order to get better
3814;; register preferencing, but we really use a stack slot.
886c62d1 3815
5b1f1e63 3816;; Conversion from DFmode to SFmode.
bc725565 3817
5b1f1e63
RH
3818(define_expand "truncdfsf2"
3819 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3820 (float_truncate:SF
3821 (match_operand:DF 1 "nonimmediate_operand" "")))]
3822 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
82a6a758 3823{
5b1f1e63
RH
3824 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3825 operands[1] = force_reg (DFmode, operands[1]);
0c5faf29 3826
5b1f1e63
RH
3827 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3828 ;
3829 else if (flag_unsafe_math_optimizations)
3830 ;
3831 else
3832 {
3833 rtx temp = assign_386_stack_local (SFmode, 0);
3834 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3835 DONE;
3836 }
3837})
3838
3839(define_expand "truncdfsf2_with_temp"
3840 [(parallel [(set (match_operand:SF 0 "" "")
3841 (float_truncate:SF (match_operand:DF 1 "" "")))
3842 (clobber (match_operand:SF 2 "" ""))])]
3843 "")
3844
3845(define_insn "*truncdfsf_fast_mixed"
3846 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3847 (float_truncate:SF
3848 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3849 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
e075ae69
RH
3850{
3851 switch (which_alternative)
3852 {
3853 case 0:
3854 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3855 return "fstp%z0\t%y0";
e075ae69 3856 else
0f40f9f7 3857 return "fst%z0\t%y0";
5b1f1e63
RH
3858 case 1:
3859 return output_387_reg_move (insn, operands);
3860 case 2:
3861 return "cvtsd2ss\t{%1, %0|%0, %1}";
46ed7963
JH
3862 default:
3863 abort ();
e075ae69 3864 }
0f40f9f7 3865}
5b1f1e63
RH
3866 [(set_attr "type" "fmov,fmov,ssecvt")
3867 (set_attr "mode" "SF")])
3868
3869;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3870;; because nothing we do here is unsafe.
3871(define_insn "*truncdfsf_fast_sse"
3872 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3873 (float_truncate:SF
3874 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3875 "TARGET_SSE2 && TARGET_SSE_MATH"
3876 "cvtsd2ss\t{%1, %0|%0, %1}"
3877 [(set_attr "type" "ssecvt")
3878 (set_attr "mode" "SF")])
3879
3880(define_insn "*truncdfsf_fast_i387"
3881 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3882 (float_truncate:SF
3883 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3884 "TARGET_80387 && flag_unsafe_math_optimizations"
3885 "* return output_387_reg_move (insn, operands);"
3886 [(set_attr "type" "fmov")
3887 (set_attr "mode" "SF")])
42a0aa6f 3888
5b1f1e63
RH
3889(define_insn "*truncdfsf_mixed"
3890 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
42a0aa6f 3891 (float_truncate:SF
5b1f1e63
RH
3892 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3893 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3894 "TARGET_MIX_SSE_I387"
4977bab6
ZW
3895{
3896 switch (which_alternative)
3897 {
3898 case 0:
3899 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3900 return "fstp%z0\t%y0";
3901 else
3902 return "fst%z0\t%y0";
5b1f1e63 3903 case 1:
4977bab6 3904 return "#";
5b1f1e63
RH
3905 case 2:
3906 return "cvtsd2ss\t{%1, %0|%0, %1}";
46ed7963
JH
3907 default:
3908 abort ();
42a0aa6f 3909 }
0f40f9f7 3910}
5b1f1e63
RH
3911 [(set_attr "type" "fmov,multi,ssecvt")
3912 (set_attr "mode" "SF")])
53b5ce19 3913
5b1f1e63
RH
3914(define_insn "*truncdfsf_i387"
3915 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
42a0aa6f 3916 (float_truncate:SF
5b1f1e63
RH
3917 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3918 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3919 "TARGET_80387"
42a0aa6f
JH
3920{
3921 switch (which_alternative)
3922 {
3923 case 0:
3924 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3925 return "fstp%z0\t%y0";
42a0aa6f 3926 else
0f40f9f7 3927 return "fst%z0\t%y0";
5b1f1e63
RH
3928 case 1:
3929 return "#";
0f40f9f7
ZW
3930 default:
3931 abort ();
42a0aa6f 3932 }
0f40f9f7 3933}
5b1f1e63 3934 [(set_attr "type" "fmov,multi")
26f74aa3 3935 (set_attr "mode" "SF")])
42a0aa6f 3936
42a0aa6f 3937(define_split
4977bab6 3938 [(set (match_operand:SF 0 "register_operand" "")
42a0aa6f 3939 (float_truncate:SF
5b1f1e63 3940 (match_operand:DF 1 "fp_register_operand" "")))
42a0aa6f 3941 (clobber (match_operand 2 "" ""))]
5b1f1e63
RH
3942 "reload_completed"
3943 [(set (match_dup 2) (match_dup 1))
3944 (set (match_dup 0) (match_dup 2))]
4977bab6 3945{
5b1f1e63 3946 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4977bab6 3947})
42a0aa6f 3948
5b1f1e63 3949;; Conversion from XFmode to SFmode.
53b5ce19 3950
e075ae69
RH
3951(define_expand "truncxfsf2"
3952 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3953 (float_truncate:SF
3954 (match_operand:XF 1 "register_operand" "")))
3955 (clobber (match_dup 2))])]
f8a1ebc6 3956 "TARGET_80387"
5b1f1e63 3957{
0c5faf29
RS
3958 if (flag_unsafe_math_optimizations)
3959 {
3960 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
5b1f1e63 3961 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
0c5faf29
RS
3962 if (reg != operands[0])
3963 emit_move_insn (operands[0], reg);
3964 DONE;
3965 }
3966 else
3967 operands[2] = assign_386_stack_local (SFmode, 0);
5b1f1e63
RH
3968})
3969
3970(define_insn "*truncxfsf2_mixed"
3971 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3972 (float_truncate:SF
3973 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3974 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3975 "TARGET_MIX_SSE_I387"
3976{
3977 switch (which_alternative)
3978 {
3979 case 0:
3980 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981 return "fstp%z0\t%y0";
3982 else
3983 return "fst%z0\t%y0";
3984 default:
3985 abort();
3986 }
3987}
3988 [(set_attr "type" "fmov,multi,multi,multi")
3989 (set_attr "mode" "SF")])
0c5faf29 3990
5b1f1e63 3991(define_insn "truncxfsf2_i387_noop"
0c5faf29
RS
3992 [(set (match_operand:SF 0 "register_operand" "=f")
3993 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3994 "TARGET_80387 && flag_unsafe_math_optimizations"
82a6a758 3995{
5ea9cb6e 3996 return output_387_reg_move (insn, operands);
82a6a758
RS
3997}
3998 [(set_attr "type" "fmov")
3999 (set_attr "mode" "SF")])
53b5ce19 4000
5b1f1e63
RH
4001(define_insn "*truncxfsf2_i387"
4002 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
e075ae69 4003 (float_truncate:SF
5b1f1e63
RH
4004 (match_operand:XF 1 "register_operand" "f,f,f")))
4005 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
f8a1ebc6 4006 "TARGET_80387"
e075ae69
RH
4007{
4008 switch (which_alternative)
4009 {
4010 case 0:
4011 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4012 return "fstp%z0\t%y0";
e075ae69 4013 else
0f40f9f7 4014 return "fst%z0\t%y0";
46ed7963 4015 default:
5b1f1e63 4016 abort ();
e075ae69 4017 }
0f40f9f7 4018}
5b1f1e63 4019 [(set_attr "type" "fmov,multi,multi")
6ef67412 4020 (set_attr "mode" "SF")])
886c62d1 4021
5b1f1e63 4022(define_insn "*truncxfsf2_i387_1"
dd80b906 4023 [(set (match_operand:SF 0 "memory_operand" "=m")
e075ae69
RH
4024 (float_truncate:SF
4025 (match_operand:XF 1 "register_operand" "f")))]
f8a1ebc6 4026 "TARGET_80387"
e075ae69
RH
4027{
4028 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4029 return "fstp%z0\t%y0";
e075ae69 4030 else
0f40f9f7
ZW
4031 return "fst%z0\t%y0";
4032}
6ef67412
JH
4033 [(set_attr "type" "fmov")
4034 (set_attr "mode" "SF")])
bc725565
JW
4035
4036(define_split
5b1f1e63 4037 [(set (match_operand:SF 0 "register_operand" "")
e075ae69
RH
4038 (float_truncate:SF
4039 (match_operand:XF 1 "register_operand" "")))
4040 (clobber (match_operand:SF 2 "memory_operand" ""))]
5b1f1e63
RH
4041 "TARGET_80387 && reload_completed"
4042 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4043 (set (match_dup 0) (match_dup 2))]
886c62d1
JVA
4044 "")
4045
bc725565 4046(define_split
5b1f1e63 4047 [(set (match_operand:SF 0 "memory_operand" "")
e075ae69
RH
4048 (float_truncate:SF
4049 (match_operand:XF 1 "register_operand" "")))
4050 (clobber (match_operand:SF 2 "memory_operand" ""))]
5b1f1e63
RH
4051 "TARGET_80387"
4052 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
886c62d1
JVA
4053 "")
4054
5b1f1e63
RH
4055;; Conversion from XFmode to DFmode.
4056
e075ae69
RH
4057(define_expand "truncxfdf2"
4058 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4059 (float_truncate:DF
4060 (match_operand:XF 1 "register_operand" "")))
4061 (clobber (match_dup 2))])]
f8a1ebc6 4062 "TARGET_80387"
5b1f1e63 4063{
0c5faf29
RS
4064 if (flag_unsafe_math_optimizations)
4065 {
4066 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
5b1f1e63 4067 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
0c5faf29
RS
4068 if (reg != operands[0])
4069 emit_move_insn (operands[0], reg);
4070 DONE;
4071 }
4072 else
4073 operands[2] = assign_386_stack_local (DFmode, 0);
5b1f1e63
RH
4074})
4075
4076(define_insn "*truncxfdf2_mixed"
4077 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4078 (float_truncate:DF
4079 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4080 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4081 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4082{
4083 switch (which_alternative)
4084 {
4085 case 0:
4086 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4087 return "fstp%z0\t%y0";
4088 else
4089 return "fst%z0\t%y0";
4090 default:
4091 abort();
4092 }
4093 abort ();
4094}
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "mode" "DF")])
0c5faf29 4097
5b1f1e63 4098(define_insn "truncxfdf2_i387_noop"
0c5faf29
RS
4099 [(set (match_operand:DF 0 "register_operand" "=f")
4100 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4101 "TARGET_80387 && flag_unsafe_math_optimizations"
82a6a758 4102{
5ea9cb6e 4103 return output_387_reg_move (insn, operands);
82a6a758
RS
4104}
4105 [(set_attr "type" "fmov")
4106 (set_attr "mode" "DF")])
bc725565 4107
5b1f1e63
RH
4108(define_insn "*truncxfdf2_i387"
4109 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
e075ae69 4110 (float_truncate:DF
5b1f1e63
RH
4111 (match_operand:XF 1 "register_operand" "f,f,f")))
4112 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
f8a1ebc6 4113 "TARGET_80387"
e075ae69
RH
4114{
4115 switch (which_alternative)
4116 {
4117 case 0:
4118 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4119 return "fstp%z0\t%y0";
e075ae69 4120 else
0f40f9f7 4121 return "fst%z0\t%y0";
46ed7963 4122 default:
5b1f1e63 4123 abort ();
e075ae69 4124 }
0f40f9f7 4125}
5b1f1e63 4126 [(set_attr "type" "fmov,multi,multi")
6ef67412 4127 (set_attr "mode" "DF")])
bc725565 4128
5b1f1e63 4129(define_insn "*truncxfdf2_i387_1"
e075ae69
RH
4130 [(set (match_operand:DF 0 "memory_operand" "=m")
4131 (float_truncate:DF
4132 (match_operand:XF 1 "register_operand" "f")))]
f8a1ebc6 4133 "TARGET_80387"
e075ae69
RH
4134{
4135 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4136 return "fstp%z0\t%y0";
e075ae69 4137 else
0f40f9f7
ZW
4138 return "fst%z0\t%y0";
4139}
6ef67412
JH
4140 [(set_attr "type" "fmov")
4141 (set_attr "mode" "DF")])
bc725565
JW
4142
4143(define_split
5b1f1e63 4144 [(set (match_operand:DF 0 "register_operand" "")
e075ae69
RH
4145 (float_truncate:DF
4146 (match_operand:XF 1 "register_operand" "")))
4147 (clobber (match_operand:DF 2 "memory_operand" ""))]
5b1f1e63
RH
4148 "TARGET_80387 && reload_completed"
4149 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4150 (set (match_dup 0) (match_dup 2))]
4fb21e90
JVA
4151 "")
4152
bc725565 4153(define_split
5b1f1e63 4154 [(set (match_operand:DF 0 "memory_operand" "")
e075ae69
RH
4155 (float_truncate:DF
4156 (match_operand:XF 1 "register_operand" "")))
4157 (clobber (match_operand:DF 2 "memory_operand" ""))]
5b1f1e63
RH
4158 "TARGET_80387"
4159 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4fb21e90 4160 "")
e075ae69
RH
4161\f
4162;; %%% Break up all these bad boys.
4fb21e90 4163
e075ae69
RH
4164;; Signed conversion to DImode.
4165
2b589241 4166(define_expand "fix_truncxfdi2"
ec13ba83
CT
4167 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4168 (fix:DI (match_operand:XF 1 "register_operand" "")))
8bc527af 4169 (clobber (reg:CC FLAGS_REG))])]
bc725565 4170 "TARGET_80387"
22fb740d 4171 "")
bc725565 4172
e075ae69 4173(define_expand "fix_truncdfdi2"
ec13ba83
CT
4174 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4175 (fix:DI (match_operand:DF 1 "register_operand" "")))
8bc527af 4176 (clobber (reg:CC FLAGS_REG))])]
fab072b5 4177 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
46ed7963 4178{
1b0c37d7 4179 if (TARGET_64BIT && TARGET_SSE2)
46ed7963
JH
4180 {
4181 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4182 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4183 if (out != operands[0])
4184 emit_move_insn (operands[0], out);
4185 DONE;
4186 }
0f40f9f7 4187})
53b5ce19 4188
e075ae69 4189(define_expand "fix_truncsfdi2"
ec13ba83
CT
4190 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4191 (fix:DI (match_operand:SF 1 "register_operand" "")))
8bc527af 4192 (clobber (reg:CC FLAGS_REG))])]
fab072b5 4193 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
46ed7963 4194{
fab072b5 4195 if (TARGET_64BIT && TARGET_SSE)
46ed7963
JH
4196 {
4197 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4198 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4199 if (out != operands[0])
4200 emit_move_insn (operands[0], out);
4201 DONE;
4202 }
0f40f9f7 4203})
e075ae69 4204
22fb740d
JH
4205;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4206;; of the machinery.
fab072b5 4207(define_insn_and_split "*fix_truncdi_i387"
22fb740d 4208 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
ec13ba83 4209 (fix:DI (match_operand 1 "register_operand" "f,f")))
8bc527af 4210 (clobber (reg:CC FLAGS_REG))]
22fb740d
JH
4211 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4212 && !reload_completed && !reload_in_progress
4213 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4214 "#"
14f73b5a 4215 "&& 1"
22fb740d
JH
4216 [(const_int 0)]
4217{
fa1a0d02 4218 ix86_optimize_mode_switching = 1;
22fb740d
JH
4219 operands[2] = assign_386_stack_local (HImode, 1);
4220 operands[3] = assign_386_stack_local (HImode, 2);
4221 if (memory_operand (operands[0], VOIDmode))
4222 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4223 operands[2], operands[3]));
4224 else
4225 {
4226 operands[4] = assign_386_stack_local (DImode, 0);
4227 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4228 operands[2], operands[3],
4229 operands[4]));
4230 }
4231 DONE;
4232}
26f74aa3 4233 [(set_attr "type" "fistp")
edeacc14 4234 (set_attr "i387_cw" "trunc")
26f74aa3 4235 (set_attr "mode" "DI")])
22fb740d
JH
4236
4237(define_insn "fix_truncdi_nomemory"
c76aab11 4238 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
e075ae69 4239 (fix:DI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
4240 (use (match_operand:HI 2 "memory_operand" "m,m"))
4241 (use (match_operand:HI 3 "memory_operand" "m,m"))
4242 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
22fb740d 4243 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
46ed7963 4244 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
22fb740d
JH
4245 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4246 "#"
26f74aa3 4247 [(set_attr "type" "fistp")
edeacc14 4248 (set_attr "i387_cw" "trunc")
26f74aa3 4249 (set_attr "mode" "DI")])
22fb740d
JH
4250
4251(define_insn "fix_truncdi_memory"
4252 [(set (match_operand:DI 0 "memory_operand" "=m")
4253 (fix:DI (match_operand 1 "register_operand" "f")))
4254 (use (match_operand:HI 2 "memory_operand" "m"))
4255 (use (match_operand:HI 3 "memory_operand" "m"))
4256 (clobber (match_scratch:DF 4 "=&1f"))]
4257 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4258 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
869d095e 4259 "* return output_fix_trunc (insn, operands);"
26f74aa3 4260 [(set_attr "type" "fistp")
edeacc14 4261 (set_attr "i387_cw" "trunc")
26f74aa3 4262 (set_attr "mode" "DI")])
53b5ce19 4263
e075ae69
RH
4264(define_split
4265 [(set (match_operand:DI 0 "register_operand" "")
4266 (fix:DI (match_operand 1 "register_operand" "")))
7a2e09f4
JH
4267 (use (match_operand:HI 2 "memory_operand" ""))
4268 (use (match_operand:HI 3 "memory_operand" ""))
4269 (clobber (match_operand:DI 4 "memory_operand" ""))
a05924f9 4270 (clobber (match_scratch 5 ""))]
7a2e09f4
JH
4271 "reload_completed"
4272 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4273 (use (match_dup 2))
4274 (use (match_dup 3))
e075ae69 4275 (clobber (match_dup 5))])
7a2e09f4 4276 (set (match_dup 0) (match_dup 4))]
53b5ce19
JW
4277 "")
4278
22fb740d
JH
4279(define_split
4280 [(set (match_operand:DI 0 "memory_operand" "")
4281 (fix:DI (match_operand 1 "register_operand" "")))
4282 (use (match_operand:HI 2 "memory_operand" ""))
4283 (use (match_operand:HI 3 "memory_operand" ""))
4284 (clobber (match_operand:DI 4 "memory_operand" ""))
4285 (clobber (match_scratch 5 ""))]
4286 "reload_completed"
4287 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4288 (use (match_dup 2))
4289 (use (match_dup 3))
4290 (clobber (match_dup 5))])]
4291 "")
4292
46ed7963
JH
4293;; When SSE available, it is always faster to use it!
4294(define_insn "fix_truncsfdi_sse"
f56e86bd
JH
4295 [(set (match_operand:DI 0 "register_operand" "=r,r")
4296 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
1b0c37d7 4297 "TARGET_64BIT && TARGET_SSE"
0f40f9f7 4298 "cvttss2si{q}\t{%1, %0|%0, %1}"
f56e86bd 4299 [(set_attr "type" "sseicvt")
26f74aa3 4300 (set_attr "mode" "SF")
f56e86bd 4301 (set_attr "athlon_decode" "double,vector")])
46ed7963 4302
8dfa3bb0
JH
4303;; Avoid vector decoded form of the instruction.
4304(define_peephole2
4305 [(match_scratch:SF 2 "x")
4306 (set (match_operand:DI 0 "register_operand" "")
4307 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4308 "TARGET_K8 && !optimize_size"
4309 [(set (match_dup 2) (match_dup 1))
4310 (set (match_dup 0) (fix:DI (match_dup 2)))]
4311 "")
4312
46ed7963 4313(define_insn "fix_truncdfdi_sse"
f56e86bd
JH
4314 [(set (match_operand:DI 0 "register_operand" "=r,r")
4315 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
1b0c37d7 4316 "TARGET_64BIT && TARGET_SSE2"
0f40f9f7 4317 "cvttsd2si{q}\t{%1, %0|%0, %1}"
f56e86bd 4318 [(set_attr "type" "sseicvt,sseicvt")
26f74aa3 4319 (set_attr "mode" "DF")
f56e86bd 4320 (set_attr "athlon_decode" "double,vector")])
46ed7963 4321
8dfa3bb0
JH
4322;; Avoid vector decoded form of the instruction.
4323(define_peephole2
4324 [(match_scratch:DF 2 "Y")
4325 (set (match_operand:DI 0 "register_operand" "")
4326 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4327 "TARGET_K8 && !optimize_size"
4328 [(set (match_dup 2) (match_dup 1))
4329 (set (match_dup 0) (fix:DI (match_dup 2)))]
4330 "")
4331
e075ae69 4332;; Signed conversion to SImode.
53b5ce19 4333
e075ae69 4334(define_expand "fix_truncxfsi2"
ec13ba83
CT
4335 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4336 (fix:SI (match_operand:XF 1 "register_operand" "")))
8bc527af 4337 (clobber (reg:CC FLAGS_REG))])]
2b589241 4338 "TARGET_80387"
22fb740d 4339 "")
2b589241 4340
e075ae69 4341(define_expand "fix_truncdfsi2"
ec13ba83
CT
4342 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4343 (fix:SI (match_operand:DF 1 "register_operand" "")))
8bc527af 4344 (clobber (reg:CC FLAGS_REG))])]
42a0aa6f 4345 "TARGET_80387 || TARGET_SSE2"
42a0aa6f
JH
4346{
4347 if (TARGET_SSE2)
4348 {
ca9a9b12 4349 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
b1675dbd
JH
4350 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4351 if (out != operands[0])
4352 emit_move_insn (operands[0], out);
42a0aa6f
JH
4353 DONE;
4354 }
0f40f9f7 4355})
886c62d1 4356
e075ae69 4357(define_expand "fix_truncsfsi2"
ec13ba83
CT
4358 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4359 (fix:SI (match_operand:SF 1 "register_operand" "")))
8bc527af 4360 (clobber (reg:CC FLAGS_REG))])]
42a0aa6f 4361 "TARGET_80387 || TARGET_SSE"
42a0aa6f 4362{
22fb740d 4363 if (TARGET_SSE)
42a0aa6f 4364 {
ca9a9b12 4365 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
46ed7963 4366 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
b1675dbd
JH
4367 if (out != operands[0])
4368 emit_move_insn (operands[0], out);
42a0aa6f
JH
4369 DONE;
4370 }
0f40f9f7 4371})
e075ae69 4372
22fb740d
JH
4373;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4374;; of the machinery.
fab072b5 4375(define_insn_and_split "*fix_truncsi_i387"
22fb740d 4376 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
ec13ba83 4377 (fix:SI (match_operand 1 "register_operand" "f,f")))
8bc527af 4378 (clobber (reg:CC FLAGS_REG))]
22fb740d
JH
4379 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4380 && !reload_completed && !reload_in_progress
4381 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4382 "#"
ab75d1f1 4383 "&& 1"
22fb740d
JH
4384 [(const_int 0)]
4385{
fa1a0d02 4386 ix86_optimize_mode_switching = 1;
22fb740d
JH
4387 operands[2] = assign_386_stack_local (HImode, 1);
4388 operands[3] = assign_386_stack_local (HImode, 2);
4389 if (memory_operand (operands[0], VOIDmode))
4390 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4391 operands[2], operands[3]));
4392 else
4393 {
4394 operands[4] = assign_386_stack_local (SImode, 0);
4395 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4396 operands[2], operands[3],
4397 operands[4]));
4398 }
4399 DONE;
4400}
26f74aa3 4401 [(set_attr "type" "fistp")
edeacc14 4402 (set_attr "i387_cw" "trunc")
26f74aa3 4403 (set_attr "mode" "SI")])
22fb740d
JH
4404
4405(define_insn "fix_truncsi_nomemory"
c76aab11 4406 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
e075ae69 4407 (fix:SI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
4408 (use (match_operand:HI 2 "memory_operand" "m,m"))
4409 (use (match_operand:HI 3 "memory_operand" "m,m"))
4410 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
42a0aa6f 4411 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
22fb740d
JH
4412 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4413 "#"
26f74aa3 4414 [(set_attr "type" "fistp")
edeacc14 4415 (set_attr "i387_cw" "trunc")
26f74aa3 4416 (set_attr "mode" "SI")])
22fb740d
JH
4417
4418(define_insn "fix_truncsi_memory"
4419 [(set (match_operand:SI 0 "memory_operand" "=m")
4420 (fix:SI (match_operand 1 "register_operand" "f")))
4421 (use (match_operand:HI 2 "memory_operand" "m"))
4422 (use (match_operand:HI 3 "memory_operand" "m"))]
4423 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4424 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
e075ae69 4425 "* return output_fix_trunc (insn, operands);"
26f74aa3 4426 [(set_attr "type" "fistp")
edeacc14 4427 (set_attr "i387_cw" "trunc")
26f74aa3 4428 (set_attr "mode" "SI")])
bc725565 4429
42a0aa6f
JH
4430;; When SSE available, it is always faster to use it!
4431(define_insn "fix_truncsfsi_sse"
f56e86bd
JH
4432 [(set (match_operand:SI 0 "register_operand" "=r,r")
4433 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
42a0aa6f 4434 "TARGET_SSE"
0f40f9f7 4435 "cvttss2si\t{%1, %0|%0, %1}"
f56e86bd 4436 [(set_attr "type" "sseicvt")
26f74aa3 4437 (set_attr "mode" "DF")
f56e86bd 4438 (set_attr "athlon_decode" "double,vector")])
42a0aa6f 4439
8dfa3bb0
JH
4440;; Avoid vector decoded form of the instruction.
4441(define_peephole2
4442 [(match_scratch:SF 2 "x")
4443 (set (match_operand:SI 0 "register_operand" "")
4444 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4445 "TARGET_K8 && !optimize_size"
4446 [(set (match_dup 2) (match_dup 1))
4447 (set (match_dup 0) (fix:SI (match_dup 2)))]
4448 "")
4449
42a0aa6f 4450(define_insn "fix_truncdfsi_sse"
f56e86bd
JH
4451 [(set (match_operand:SI 0 "register_operand" "=r,r")
4452 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
42a0aa6f 4453 "TARGET_SSE2"
0f40f9f7 4454 "cvttsd2si\t{%1, %0|%0, %1}"
f56e86bd 4455 [(set_attr "type" "sseicvt")
26f74aa3 4456 (set_attr "mode" "DF")
f56e86bd 4457 (set_attr "athlon_decode" "double,vector")])
42a0aa6f 4458
18d13f34 4459;; Avoid vector decoded form of the instruction.
8dfa3bb0
JH
4460(define_peephole2
4461 [(match_scratch:DF 2 "Y")
4462 (set (match_operand:SI 0 "register_operand" "")
4463 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4464 "TARGET_K8 && !optimize_size"
4465 [(set (match_dup 2) (match_dup 1))
4466 (set (match_dup 0) (fix:SI (match_dup 2)))]
4467 "")
4468
e075ae69
RH
4469(define_split
4470 [(set (match_operand:SI 0 "register_operand" "")
4471 (fix:SI (match_operand 1 "register_operand" "")))
7a2e09f4
JH
4472 (use (match_operand:HI 2 "memory_operand" ""))
4473 (use (match_operand:HI 3 "memory_operand" ""))
4474 (clobber (match_operand:SI 4 "memory_operand" ""))]
e075ae69 4475 "reload_completed"
7a2e09f4
JH
4476 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4477 (use (match_dup 2))
22fb740d 4478 (use (match_dup 3))])
7a2e09f4 4479 (set (match_dup 0) (match_dup 4))]
bc725565 4480 "")
4fb21e90 4481
22fb740d
JH
4482(define_split
4483 [(set (match_operand:SI 0 "memory_operand" "")
4484 (fix:SI (match_operand 1 "register_operand" "")))
4485 (use (match_operand:HI 2 "memory_operand" ""))
4486 (use (match_operand:HI 3 "memory_operand" ""))
4487 (clobber (match_operand:SI 4 "memory_operand" ""))]
4488 "reload_completed"
4489 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4490 (use (match_dup 2))
4491 (use (match_dup 3))])]
4492 "")
4493
46d21d2c
JW
4494;; Signed conversion to HImode.
4495
4496(define_expand "fix_truncxfhi2"
ec13ba83
CT
4497 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4498 (fix:HI (match_operand:XF 1 "register_operand" "")))
8bc527af 4499 (clobber (reg:CC FLAGS_REG))])]
2b589241 4500 "TARGET_80387"
22fb740d 4501 "")
2b589241 4502
46d21d2c 4503(define_expand "fix_truncdfhi2"
ec13ba83
CT
4504 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4505 (fix:HI (match_operand:DF 1 "register_operand" "")))
8bc527af 4506 (clobber (reg:CC FLAGS_REG))])]
42a0aa6f 4507 "TARGET_80387 && !TARGET_SSE2"
22fb740d 4508 "")
46d21d2c
JW
4509
4510(define_expand "fix_truncsfhi2"
ec13ba83
CT
4511 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4512 (fix:HI (match_operand:SF 1 "register_operand" "")))
8bc527af 4513 (clobber (reg:CC FLAGS_REG))])]
42a0aa6f 4514 "TARGET_80387 && !TARGET_SSE"
22fb740d
JH
4515 "")
4516
4517;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4518;; of the machinery.
fab072b5 4519(define_insn_and_split "*fix_trunchi_i387"
22fb740d 4520 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
ec13ba83 4521 (fix:HI (match_operand 1 "register_operand" "f,f")))
8bc527af 4522 (clobber (reg:CC FLAGS_REG))]
22fb740d
JH
4523 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4524 && !reload_completed && !reload_in_progress
4525 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4526 "#"
d7518354 4527 "&& 1"
22fb740d
JH
4528 [(const_int 0)]
4529{
fa1a0d02 4530 ix86_optimize_mode_switching = 1;
22fb740d
JH
4531 operands[2] = assign_386_stack_local (HImode, 1);
4532 operands[3] = assign_386_stack_local (HImode, 2);
4533 if (memory_operand (operands[0], VOIDmode))
4534 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4535 operands[2], operands[3]));
4536 else
4537 {
4538 operands[4] = assign_386_stack_local (HImode, 0);
4539 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4540 operands[2], operands[3],
4541 operands[4]));
4542 }
4543 DONE;
4544}
26f74aa3 4545 [(set_attr "type" "fistp")
edeacc14 4546 (set_attr "i387_cw" "trunc")
26f74aa3 4547 (set_attr "mode" "HI")])
46d21d2c 4548
22fb740d 4549(define_insn "fix_trunchi_nomemory"
46d21d2c
JW
4550 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4551 (fix:HI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
4552 (use (match_operand:HI 2 "memory_operand" "m,m"))
4553 (use (match_operand:HI 3 "memory_operand" "m,m"))
4554 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
42a0aa6f 4555 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
22fb740d
JH
4556 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4557 "#"
26f74aa3 4558 [(set_attr "type" "fistp")
edeacc14 4559 (set_attr "i387_cw" "trunc")
26f74aa3 4560 (set_attr "mode" "HI")])
22fb740d
JH
4561
4562(define_insn "fix_trunchi_memory"
4563 [(set (match_operand:HI 0 "memory_operand" "=m")
4564 (fix:HI (match_operand 1 "register_operand" "f")))
4565 (use (match_operand:HI 2 "memory_operand" "m"))
4566 (use (match_operand:HI 3 "memory_operand" "m"))]
4567 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
46d21d2c 4569 "* return output_fix_trunc (insn, operands);"
26f74aa3 4570 [(set_attr "type" "fistp")
edeacc14 4571 (set_attr "i387_cw" "trunc")
26f74aa3 4572 (set_attr "mode" "HI")])
22fb740d
JH
4573
4574(define_split
4575 [(set (match_operand:HI 0 "memory_operand" "")
4576 (fix:HI (match_operand 1 "register_operand" "")))
4577 (use (match_operand:HI 2 "memory_operand" ""))
4578 (use (match_operand:HI 3 "memory_operand" ""))
4579 (clobber (match_operand:HI 4 "memory_operand" ""))]
4580 "reload_completed"
4581 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4582 (use (match_dup 2))
4583 (use (match_dup 3))])]
4584 "")
46d21d2c
JW
4585
4586(define_split
4587 [(set (match_operand:HI 0 "register_operand" "")
4588 (fix:HI (match_operand 1 "register_operand" "")))
7a2e09f4
JH
4589 (use (match_operand:HI 2 "memory_operand" ""))
4590 (use (match_operand:HI 3 "memory_operand" ""))
4591 (clobber (match_operand:HI 4 "memory_operand" ""))]
46d21d2c 4592 "reload_completed"
7a2e09f4
JH
4593 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4594 (use (match_dup 2))
4595 (use (match_dup 3))
46d21d2c 4596 (clobber (match_dup 4))])
7a2e09f4 4597 (set (match_dup 0) (match_dup 4))]
46d21d2c
JW
4598 "")
4599
e075ae69 4600(define_insn "x86_fnstcw_1"
c76aab11 4601 [(set (match_operand:HI 0 "memory_operand" "=m")
8bc527af 4602 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
e1f998ad 4603 "TARGET_80387"
0f40f9f7 4604 "fnstcw\t%0"
6ef67412
JH
4605 [(set_attr "length" "2")
4606 (set_attr "mode" "HI")
56bab446 4607 (set_attr "unit" "i387")])
bc725565 4608
e075ae69 4609(define_insn "x86_fldcw_1"
8bc527af 4610 [(set (reg:HI FPSR_REG)
8ee41eaf 4611 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
bc725565 4612 "TARGET_80387"
0f40f9f7 4613 "fldcw\t%0"
6ef67412
JH
4614 [(set_attr "length" "2")
4615 (set_attr "mode" "HI")
3d34cd91 4616 (set_attr "unit" "i387")
56bab446 4617 (set_attr "athlon_decode" "vector")])
e075ae69
RH
4618\f
4619;; Conversion between fixed point and floating point.
886c62d1 4620
e075ae69
RH
4621;; Even though we only accept memory inputs, the backend _really_
4622;; wants to be able to do this between registers.
4623
35c28a13
JH
4624(define_expand "floathisf2"
4625 [(set (match_operand:SF 0 "register_operand" "")
4626 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
da8947b0 4627 "TARGET_80387 || TARGET_SSE_MATH"
35c28a13 4628{
da8947b0 4629 if (TARGET_SSE_MATH)
35c28a13
JH
4630 {
4631 emit_insn (gen_floatsisf2 (operands[0],
4632 convert_to_mode (SImode, operands[1], 0)));
4633 DONE;
4634 }
4635})
4636
da8947b0 4637(define_insn "*floathisf2_i387"
155d8a47 4638 [(set (match_operand:SF 0 "register_operand" "=f,f")
da8947b0 4639 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
692308bb 4640 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
155d8a47 4641 "@
0f40f9f7 4642 fild%z1\t%1
155d8a47
JW
4643 #"
4644 [(set_attr "type" "fmov,multi")
6ef67412 4645 (set_attr "mode" "SF")
155d8a47
JW
4646 (set_attr "fp_int_src" "true")])
4647
42a0aa6f
JH
4648(define_expand "floatsisf2"
4649 [(set (match_operand:SF 0 "register_operand" "")
4650 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
da8947b0 4651 "TARGET_80387 || TARGET_SSE_MATH"
42a0aa6f
JH
4652 "")
4653
da8947b0 4654(define_insn "*floatsisf2_mixed"
f56e86bd
JH
4655 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4656 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
da8947b0 4657 "TARGET_MIX_SSE_I387"
e075ae69 4658 "@
0f40f9f7 4659 fild%z1\t%1
42a0aa6f 4660 #
f56e86bd 4661 cvtsi2ss\t{%1, %0|%0, %1}
0f40f9f7 4662 cvtsi2ss\t{%1, %0|%0, %1}"
f56e86bd 4663 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
42a0aa6f 4664 (set_attr "mode" "SF")
f56e86bd 4665 (set_attr "athlon_decode" "*,*,vector,double")
42a0aa6f
JH
4666 (set_attr "fp_int_src" "true")])
4667
4668(define_insn "*floatsisf2_sse"
f56e86bd
JH
4669 [(set (match_operand:SF 0 "register_operand" "=x,x")
4670 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
da8947b0 4671 "TARGET_SSE_MATH"
0f40f9f7 4672 "cvtsi2ss\t{%1, %0|%0, %1}"
f56e86bd 4673 [(set_attr "type" "sseicvt")
6ef67412 4674 (set_attr "mode" "SF")
f56e86bd 4675 (set_attr "athlon_decode" "vector,double")
e075ae69 4676 (set_attr "fp_int_src" "true")])
bc725565 4677
da8947b0
UB
4678(define_insn "*floatsisf2_i387"
4679 [(set (match_operand:SF 0 "register_operand" "=f,f")
4680 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4681 "TARGET_80387"
ef6257cd 4682 "@
0f40f9f7 4683 fild%z1\t%1
ef6257cd
JH
4684 #"
4685 [(set_attr "type" "fmov,multi")
4686 (set_attr "mode" "SF")
4687 (set_attr "fp_int_src" "true")])
4688
da8947b0
UB
4689(define_expand "floatdisf2"
4690 [(set (match_operand:SF 0 "register_operand" "")
4691 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4692 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4693 "")
4694
4695(define_insn "*floatdisf2_mixed"
f56e86bd
JH
4696 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4697 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
da8947b0 4698 "TARGET_64BIT && TARGET_MIX_SSE_I387"
e075ae69 4699 "@
0f40f9f7 4700 fild%z1\t%1
46ed7963 4701 #
f56e86bd 4702 cvtsi2ss{q}\t{%1, %0|%0, %1}
0f40f9f7 4703 cvtsi2ss{q}\t{%1, %0|%0, %1}"
f56e86bd 4704 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
46ed7963 4705 (set_attr "mode" "SF")
f56e86bd 4706 (set_attr "athlon_decode" "*,*,vector,double")
46ed7963
JH
4707 (set_attr "fp_int_src" "true")])
4708
4709(define_insn "*floatdisf2_sse"
f56e86bd
JH
4710 [(set (match_operand:SF 0 "register_operand" "=x,x")
4711 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
da8947b0 4712 "TARGET_64BIT && TARGET_SSE_MATH"
0f40f9f7 4713 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
f56e86bd 4714 [(set_attr "type" "sseicvt")
6ef67412 4715 (set_attr "mode" "SF")
f56e86bd 4716 (set_attr "athlon_decode" "vector,double")
e075ae69 4717 (set_attr "fp_int_src" "true")])
bc725565 4718
da8947b0
UB
4719(define_insn "*floatdisf2_i387"
4720 [(set (match_operand:SF 0 "register_operand" "=f,f")
4721 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4722 "TARGET_80387"
4723 "@
4724 fild%z1\t%1
4725 #"
4726 [(set_attr "type" "fmov,multi")
4727 (set_attr "mode" "SF")
4728 (set_attr "fp_int_src" "true")])
4729
35c28a13
JH
4730(define_expand "floathidf2"
4731 [(set (match_operand:DF 0 "register_operand" "")
4732 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
da8947b0 4733 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
35c28a13 4734{
da8947b0 4735 if (TARGET_SSE2 && TARGET_SSE_MATH)
35c28a13
JH
4736 {
4737 emit_insn (gen_floatsidf2 (operands[0],
4738 convert_to_mode (SImode, operands[1], 0)));
4739 DONE;
4740 }
4741})
4742
da8947b0 4743(define_insn "*floathidf2_i387"
155d8a47 4744 [(set (match_operand:DF 0 "register_operand" "=f,f")
da8947b0 4745 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
692308bb 4746 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
155d8a47 4747 "@
0f40f9f7 4748 fild%z1\t%1
155d8a47
JW
4749 #"
4750 [(set_attr "type" "fmov,multi")
6ef67412 4751 (set_attr "mode" "DF")
155d8a47
JW
4752 (set_attr "fp_int_src" "true")])
4753
42a0aa6f
JH
4754(define_expand "floatsidf2"
4755 [(set (match_operand:DF 0 "register_operand" "")
4756 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
da8947b0 4757 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
42a0aa6f
JH
4758 "")
4759
da8947b0 4760(define_insn "*floatsidf2_mixed"
f56e86bd
JH
4761 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4762 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
da8947b0 4763 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
e075ae69 4764 "@
0f40f9f7 4765 fild%z1\t%1
42a0aa6f 4766 #
f56e86bd 4767 cvtsi2sd\t{%1, %0|%0, %1}
0f40f9f7 4768 cvtsi2sd\t{%1, %0|%0, %1}"
f56e86bd 4769 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
42a0aa6f 4770 (set_attr "mode" "DF")
f56e86bd 4771 (set_attr "athlon_decode" "*,*,double,direct")
42a0aa6f
JH
4772 (set_attr "fp_int_src" "true")])
4773
4774(define_insn "*floatsidf2_sse"
f56e86bd
JH
4775 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4776 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
da8947b0 4777 "TARGET_SSE2 && TARGET_SSE_MATH"
0f40f9f7 4778 "cvtsi2sd\t{%1, %0|%0, %1}"
f56e86bd 4779 [(set_attr "type" "sseicvt")
6ef67412 4780 (set_attr "mode" "DF")
f56e86bd 4781 (set_attr "athlon_decode" "double,direct")
e075ae69 4782 (set_attr "fp_int_src" "true")])
e1f998ad 4783
da8947b0
UB
4784(define_insn "*floatsidf2_i387"
4785 [(set (match_operand:DF 0 "register_operand" "=f,f")
4786 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4787 "TARGET_80387"
ef6257cd 4788 "@
0f40f9f7 4789 fild%z1\t%1
ef6257cd
JH
4790 #"
4791 [(set_attr "type" "fmov,multi")
4792 (set_attr "mode" "DF")
4793 (set_attr "fp_int_src" "true")])
4794
da8947b0
UB
4795(define_expand "floatdidf2"
4796 [(set (match_operand:DF 0 "register_operand" "")
4797 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4798 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4799 "")
4800
4801(define_insn "*floatdidf2_mixed"
f56e86bd
JH
4802 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4803 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
da8947b0 4804 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
e075ae69 4805 "@
0f40f9f7 4806 fild%z1\t%1
46ed7963 4807 #
f56e86bd 4808 cvtsi2sd{q}\t{%1, %0|%0, %1}
0f40f9f7 4809 cvtsi2sd{q}\t{%1, %0|%0, %1}"
f56e86bd 4810 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
46ed7963 4811 (set_attr "mode" "DF")
f56e86bd 4812 (set_attr "athlon_decode" "*,*,double,direct")
46ed7963
JH
4813 (set_attr "fp_int_src" "true")])
4814
4815(define_insn "*floatdidf2_sse"
f56e86bd
JH
4816 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4817 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
da8947b0 4818 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
0f40f9f7 4819 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
f56e86bd 4820 [(set_attr "type" "sseicvt")
6ef67412 4821 (set_attr "mode" "DF")
f56e86bd 4822 (set_attr "athlon_decode" "double,direct")
e075ae69 4823 (set_attr "fp_int_src" "true")])
bc725565 4824
da8947b0
UB
4825(define_insn "*floatdidf2_i387"
4826 [(set (match_operand:DF 0 "register_operand" "=f,f")
4827 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4828 "TARGET_80387"
4829 "@
4830 fild%z1\t%1
4831 #"
4832 [(set_attr "type" "fmov,multi")
4833 (set_attr "mode" "DF")
4834 (set_attr "fp_int_src" "true")])
4835
155d8a47
JW
4836(define_insn "floathixf2"
4837 [(set (match_operand:XF 0 "register_operand" "=f,f")
da8947b0 4838 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
2b589241
JH
4839 "TARGET_80387"
4840 "@
0f40f9f7 4841 fild%z1\t%1
2b589241
JH
4842 #"
4843 [(set_attr "type" "fmov,multi")
4844 (set_attr "mode" "XF")
4845 (set_attr "fp_int_src" "true")])
4846
e075ae69
RH
4847(define_insn "floatsixf2"
4848 [(set (match_operand:XF 0 "register_operand" "=f,f")
da8947b0 4849 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
2b589241
JH
4850 "TARGET_80387"
4851 "@
0f40f9f7 4852 fild%z1\t%1
2b589241
JH
4853 #"
4854 [(set_attr "type" "fmov,multi")
4855 (set_attr "mode" "XF")
4856 (set_attr "fp_int_src" "true")])
4857
e075ae69 4858(define_insn "floatdixf2"
53b5ce19 4859 [(set (match_operand:XF 0 "register_operand" "=f,f")
da8947b0 4860 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
2b589241
JH
4861 "TARGET_80387"
4862 "@
0f40f9f7 4863 fild%z1\t%1
2b589241
JH
4864 #"
4865 [(set_attr "type" "fmov,multi")
4866 (set_attr "mode" "XF")
4867 (set_attr "fp_int_src" "true")])
4868
e075ae69 4869;; %%% Kill these when reload knows how to do it.
155d8a47 4870(define_split
c3c637e3 4871 [(set (match_operand 0 "fp_register_operand" "")
4211a8fb 4872 (float (match_operand 1 "register_operand" "")))]
da8947b0
UB
4873 "reload_completed
4874 && TARGET_80387
4875 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211a8fb 4876 [(const_int 0)]
4211a8fb
JH
4877{
4878 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4879 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4881 ix86_free_from_memory (GET_MODE (operands[1]));
4882 DONE;
0f40f9f7 4883})
8d705469
JH
4884
4885(define_expand "floatunssisf2"
4886 [(use (match_operand:SF 0 "register_operand" ""))
4887 (use (match_operand:SI 1 "register_operand" ""))]
da8947b0 4888 "!TARGET_64BIT && TARGET_SSE_MATH"
8d705469
JH
4889 "x86_emit_floatuns (operands); DONE;")
4890
4891(define_expand "floatunsdisf2"
4892 [(use (match_operand:SF 0 "register_operand" ""))
4893 (use (match_operand:DI 1 "register_operand" ""))]
da8947b0 4894 "TARGET_64BIT && TARGET_SSE_MATH"
8d705469
JH
4895 "x86_emit_floatuns (operands); DONE;")
4896
4897(define_expand "floatunsdidf2"
4898 [(use (match_operand:DF 0 "register_operand" ""))
4899 (use (match_operand:DI 1 "register_operand" ""))]
da8947b0 4900 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
8d705469 4901 "x86_emit_floatuns (operands); DONE;")
e075ae69 4902\f
997404de
JH
4903;; SSE extract/set expanders
4904
997404de 4905\f
e075ae69 4906;; Add instructions
53b5ce19 4907
e075ae69
RH
4908;; %%% splits for addsidi3
4909; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4910; (plus:DI (match_operand:DI 1 "general_operand" "")
4911; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
e1f998ad 4912
9b70259d
JH
4913(define_expand "adddi3"
4914 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4915 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4916 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 4917 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
4918 ""
4919 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4920
4921(define_insn "*adddi3_1"
e075ae69
RH
4922 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4923 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4924 (match_operand:DI 2 "general_operand" "roiF,riF")))
8bc527af 4925 (clobber (reg:CC FLAGS_REG))]
c15c18c5 4926 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
bc725565
JW
4927 "#")
4928
4929(define_split
e075ae69 4930 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4cbfbb1b 4931 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
e075ae69 4932 (match_operand:DI 2 "general_operand" "")))
8bc527af 4933 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 4934 "!TARGET_64BIT && reload_completed"
8bc527af 4935 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
8ee41eaf 4936 UNSPEC_ADD_CARRY))
e075ae69
RH
4937 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4938 (parallel [(set (match_dup 3)
8bc527af 4939 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9dcbdc7e
JH
4940 (match_dup 4))
4941 (match_dup 5)))
8bc527af 4942 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
4943 "split_di (operands+0, 1, operands+0, operands+3);
4944 split_di (operands+1, 1, operands+1, operands+4);
4945 split_di (operands+2, 1, operands+2, operands+5);")
4946
7b52eede 4947(define_insn "adddi3_carry_rex64"
9b70259d 4948 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
e6e81735 4949 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
9b70259d
JH
4950 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4951 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8bc527af 4952 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 4953 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
0f40f9f7 4954 "adc{q}\t{%2, %0|%0, %2}"
9b70259d
JH
4955 [(set_attr "type" "alu")
4956 (set_attr "pent_pair" "pu")
56bab446 4957 (set_attr "mode" "DI")])
9b70259d
JH
4958
4959(define_insn "*adddi3_cc_rex64"
8bc527af 4960 [(set (reg:CC FLAGS_REG)
8ee41eaf
RH
4961 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4962 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4963 UNSPEC_ADD_CARRY))
9b70259d
JH
4964 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4965 (plus:DI (match_dup 1) (match_dup 2)))]
4966 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
0f40f9f7 4967 "add{q}\t{%2, %0|%0, %2}"
9b70259d
JH
4968 [(set_attr "type" "alu")
4969 (set_attr "mode" "DI")])
4970
7b52eede 4971(define_insn "addqi3_carry"
d67e96cf 4972 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
e6e81735 4973 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7b52eede 4974 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
d67e96cf 4975 (match_operand:QI 2 "general_operand" "qi,qm")))
8bc527af 4976 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
4977 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4978 "adc{b}\t{%2, %0|%0, %2}"
4979 [(set_attr "type" "alu")
4980 (set_attr "pent_pair" "pu")
56bab446 4981 (set_attr "mode" "QI")])
7b52eede
JH
4982
4983(define_insn "addhi3_carry"
4984 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
e6e81735 4985 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7b52eede
JH
4986 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4987 (match_operand:HI 2 "general_operand" "ri,rm")))
8bc527af 4988 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
4989 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4990 "adc{w}\t{%2, %0|%0, %2}"
4991 [(set_attr "type" "alu")
4992 (set_attr "pent_pair" "pu")
56bab446 4993 (set_attr "mode" "HI")])
7b52eede
JH
4994
4995(define_insn "addsi3_carry"
e075ae69 4996 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
e6e81735 4997 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9dcbdc7e
JH
4998 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4999 (match_operand:SI 2 "general_operand" "ri,rm")))
8bc527af 5000 (clobber (reg:CC FLAGS_REG))]
d525dfdf 5001 "ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 5002 "adc{l}\t{%2, %0|%0, %2}"
e075ae69
RH
5003 [(set_attr "type" "alu")
5004 (set_attr "pent_pair" "pu")
56bab446 5005 (set_attr "mode" "SI")])
4fb21e90 5006
9b70259d
JH
5007(define_insn "*addsi3_carry_zext"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (zero_extend:DI
e6e81735 5010 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9b70259d
JH
5011 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5012 (match_operand:SI 2 "general_operand" "rim"))))
8bc527af 5013 (clobber (reg:CC FLAGS_REG))]
9b70259d 5014 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 5015 "adc{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
5016 [(set_attr "type" "alu")
5017 (set_attr "pent_pair" "pu")
56bab446 5018 (set_attr "mode" "SI")])
9b70259d 5019
7e08e190 5020(define_insn "*addsi3_cc"
8bc527af 5021 [(set (reg:CC FLAGS_REG)
8ee41eaf
RH
5022 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5023 (match_operand:SI 2 "general_operand" "ri,rm")]
5024 UNSPEC_ADD_CARRY))
7e08e190
JH
5025 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5026 (plus:SI (match_dup 1) (match_dup 2)))]
265dab10 5027 "ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 5028 "add{l}\t{%2, %0|%0, %2}"
265dab10 5029 [(set_attr "type" "alu")
7e08e190
JH
5030 (set_attr "mode" "SI")])
5031
5032(define_insn "addqi3_cc"
8bc527af 5033 [(set (reg:CC FLAGS_REG)
8ee41eaf
RH
5034 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5035 (match_operand:QI 2 "general_operand" "qi,qm")]
5036 UNSPEC_ADD_CARRY))
7e08e190
JH
5037 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5038 (plus:QI (match_dup 1) (match_dup 2)))]
5039 "ix86_binary_operator_ok (PLUS, QImode, operands)"
0f40f9f7 5040 "add{b}\t{%2, %0|%0, %2}"
7e08e190
JH
5041 [(set_attr "type" "alu")
5042 (set_attr "mode" "QI")])
265dab10 5043
e075ae69
RH
5044(define_expand "addsi3"
5045 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5046 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5047 (match_operand:SI 2 "general_operand" "")))
8bc527af 5048 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
5049 ""
5050 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
886c62d1 5051
ac62a60e 5052(define_insn "*lea_1"
e075ae69 5053 [(set (match_operand:SI 0 "register_operand" "=r")
74dc3e94 5054 (match_operand:SI 1 "no_seg_address_operand" "p"))]
ac62a60e 5055 "!TARGET_64BIT"
0f40f9f7 5056 "lea{l}\t{%a1, %0|%0, %a1}"
6ef67412
JH
5057 [(set_attr "type" "lea")
5058 (set_attr "mode" "SI")])
2ae0f82c 5059
ac62a60e
JH
5060(define_insn "*lea_1_rex64"
5061 [(set (match_operand:SI 0 "register_operand" "=r")
74dc3e94 5062 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
ac62a60e 5063 "TARGET_64BIT"
0f40f9f7 5064 "lea{l}\t{%a1, %0|%0, %a1}"
ac62a60e
JH
5065 [(set_attr "type" "lea")
5066 (set_attr "mode" "SI")])
5067
5068(define_insn "*lea_1_zext"
5069 [(set (match_operand:DI 0 "register_operand" "=r")
74dc3e94
RH
5070 (zero_extend:DI
5071 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
d4f33f6c 5072 "TARGET_64BIT"
0f40f9f7 5073 "lea{l}\t{%a1, %k0|%k0, %a1}"
ac62a60e
JH
5074 [(set_attr "type" "lea")
5075 (set_attr "mode" "SI")])
5076
5077(define_insn "*lea_2_rex64"
5078 [(set (match_operand:DI 0 "register_operand" "=r")
74dc3e94 5079 (match_operand:DI 1 "no_seg_address_operand" "p"))]
ac62a60e 5080 "TARGET_64BIT"
0f40f9f7 5081 "lea{q}\t{%a1, %0|%0, %a1}"
ac62a60e
JH
5082 [(set_attr "type" "lea")
5083 (set_attr "mode" "DI")])
5084
58787064
JH
5085;; The lea patterns for non-Pmodes needs to be matched by several
5086;; insns converted to real lea by splitters.
5087
5088(define_insn_and_split "*lea_general_1"
5089 [(set (match_operand 0 "register_operand" "=r")
9a9286af 5090 (plus (plus (match_operand 1 "index_register_operand" "l")
58787064
JH
5091 (match_operand 2 "register_operand" "r"))
5092 (match_operand 3 "immediate_operand" "i")))]
ac62a60e
JH
5093 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5094 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
58787064
JH
5095 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5096 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5097 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5098 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5099 || GET_MODE (operands[3]) == VOIDmode)"
5100 "#"
cb694d2c 5101 "&& reload_completed"
58787064 5102 [(const_int 0)]
58787064
JH
5103{
5104 rtx pat;
5105 operands[0] = gen_lowpart (SImode, operands[0]);
5106 operands[1] = gen_lowpart (Pmode, operands[1]);
5107 operands[2] = gen_lowpart (Pmode, operands[2]);
5108 operands[3] = gen_lowpart (Pmode, operands[3]);
5109 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5110 operands[3]);
5111 if (Pmode != SImode)
5112 pat = gen_rtx_SUBREG (SImode, pat, 0);
5113 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5114 DONE;
0f40f9f7 5115}
58787064
JH
5116 [(set_attr "type" "lea")
5117 (set_attr "mode" "SI")])
5118
ac62a60e
JH
5119(define_insn_and_split "*lea_general_1_zext"
5120 [(set (match_operand:DI 0 "register_operand" "=r")
5121 (zero_extend:DI
9a9286af 5122 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
ac62a60e
JH
5123 (match_operand:SI 2 "register_operand" "r"))
5124 (match_operand:SI 3 "immediate_operand" "i"))))]
5125 "TARGET_64BIT"
5126 "#"
5127 "&& reload_completed"
5128 [(set (match_dup 0)
5129 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5130 (match_dup 2))
5131 (match_dup 3)) 0)))]
ac62a60e
JH
5132{
5133 operands[1] = gen_lowpart (Pmode, operands[1]);
5134 operands[2] = gen_lowpart (Pmode, operands[2]);
5135 operands[3] = gen_lowpart (Pmode, operands[3]);
0f40f9f7 5136}
ac62a60e
JH
5137 [(set_attr "type" "lea")
5138 (set_attr "mode" "SI")])
5139
58787064
JH
5140(define_insn_and_split "*lea_general_2"
5141 [(set (match_operand 0 "register_operand" "=r")
9a9286af 5142 (plus (mult (match_operand 1 "index_register_operand" "l")
58787064
JH
5143 (match_operand 2 "const248_operand" "i"))
5144 (match_operand 3 "nonmemory_operand" "ri")))]
ac62a60e
JH
5145 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5146 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
58787064
JH
5147 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5148 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5149 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5150 || GET_MODE (operands[3]) == VOIDmode)"
5151 "#"
cb694d2c 5152 "&& reload_completed"
58787064 5153 [(const_int 0)]
58787064
JH
5154{
5155 rtx pat;
5156 operands[0] = gen_lowpart (SImode, operands[0]);
5157 operands[1] = gen_lowpart (Pmode, operands[1]);
5158 operands[3] = gen_lowpart (Pmode, operands[3]);
5159 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5160 operands[3]);
5161 if (Pmode != SImode)
5162 pat = gen_rtx_SUBREG (SImode, pat, 0);
5163 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5164 DONE;
0f40f9f7 5165}
58787064
JH
5166 [(set_attr "type" "lea")
5167 (set_attr "mode" "SI")])
5168
ac62a60e
JH
5169(define_insn_and_split "*lea_general_2_zext"
5170 [(set (match_operand:DI 0 "register_operand" "=r")
5171 (zero_extend:DI
9a9286af 5172 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
ac62a60e
JH
5173 (match_operand:SI 2 "const248_operand" "n"))
5174 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5175 "TARGET_64BIT"
5176 "#"
5177 "&& reload_completed"
5178 [(set (match_dup 0)
5179 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5180 (match_dup 2))
5181 (match_dup 3)) 0)))]
ac62a60e
JH
5182{
5183 operands[1] = gen_lowpart (Pmode, operands[1]);
5184 operands[3] = gen_lowpart (Pmode, operands[3]);
0f40f9f7 5185}
ac62a60e
JH
5186 [(set_attr "type" "lea")
5187 (set_attr "mode" "SI")])
5188
58787064
JH
5189(define_insn_and_split "*lea_general_3"
5190 [(set (match_operand 0 "register_operand" "=r")
9a9286af 5191 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
58787064
JH
5192 (match_operand 2 "const248_operand" "i"))
5193 (match_operand 3 "register_operand" "r"))
5194 (match_operand 4 "immediate_operand" "i")))]
ac62a60e
JH
5195 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5196 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
58787064
JH
5197 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5198 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5199 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5200 "#"
cb694d2c 5201 "&& reload_completed"
58787064 5202 [(const_int 0)]
58787064
JH
5203{
5204 rtx pat;
5205 operands[0] = gen_lowpart (SImode, operands[0]);
5206 operands[1] = gen_lowpart (Pmode, operands[1]);
5207 operands[3] = gen_lowpart (Pmode, operands[3]);
5208 operands[4] = gen_lowpart (Pmode, operands[4]);
5209 pat = gen_rtx_PLUS (Pmode,
5210 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5211 operands[2]),
5212 operands[3]),
5213 operands[4]);
5214 if (Pmode != SImode)
5215 pat = gen_rtx_SUBREG (SImode, pat, 0);
5216 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5217 DONE;
0f40f9f7 5218}
58787064
JH
5219 [(set_attr "type" "lea")
5220 (set_attr "mode" "SI")])
5221
ac62a60e
JH
5222(define_insn_and_split "*lea_general_3_zext"
5223 [(set (match_operand:DI 0 "register_operand" "=r")
5224 (zero_extend:DI
9a9286af
RH
5225 (plus:SI (plus:SI (mult:SI
5226 (match_operand:SI 1 "index_register_operand" "l")
5227 (match_operand:SI 2 "const248_operand" "n"))
ac62a60e
JH
5228 (match_operand:SI 3 "register_operand" "r"))
5229 (match_operand:SI 4 "immediate_operand" "i"))))]
5230 "TARGET_64BIT"
5231 "#"
5232 "&& reload_completed"
5233 [(set (match_dup 0)
5234 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5235 (match_dup 2))
5236 (match_dup 3))
5237 (match_dup 4)) 0)))]
ac62a60e
JH
5238{
5239 operands[1] = gen_lowpart (Pmode, operands[1]);
5240 operands[3] = gen_lowpart (Pmode, operands[3]);
5241 operands[4] = gen_lowpart (Pmode, operands[4]);
0f40f9f7 5242}
ac62a60e
JH
5243 [(set_attr "type" "lea")
5244 (set_attr "mode" "SI")])
5245
9b70259d
JH
5246(define_insn "*adddi_1_rex64"
5247 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5248 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
9a9286af 5249 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
8bc527af 5250 (clobber (reg:CC FLAGS_REG))]
9b70259d 5251 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
2ae0f82c 5252{
e075ae69 5253 switch (get_attr_type (insn))
2ae0f82c 5254 {
e075ae69
RH
5255 case TYPE_LEA:
5256 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 5257 return "lea{q}\t{%a2, %0|%0, %a2}";
2ae0f82c 5258
e075ae69
RH
5259 case TYPE_INCDEC:
5260 if (! rtx_equal_p (operands[0], operands[1]))
5261 abort ();
5262 if (operands[2] == const1_rtx)
0f40f9f7 5263 return "inc{q}\t%0";
e075ae69 5264 else if (operands[2] == constm1_rtx)
0f40f9f7 5265 return "dec{q}\t%0";
2ae0f82c 5266 else
9b70259d 5267 abort ();
2ae0f82c 5268
e075ae69
RH
5269 default:
5270 if (! rtx_equal_p (operands[0], operands[1]))
5271 abort ();
2ae0f82c 5272
e075ae69
RH
5273 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5274 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5275 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5276 /* Avoid overflows. */
0f40f9f7 5277 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
e075ae69
RH
5278 && (INTVAL (operands[2]) == 128
5279 || (INTVAL (operands[2]) < 0
5280 && INTVAL (operands[2]) != -128)))
5281 {
5282 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5283 return "sub{q}\t{%2, %0|%0, %2}";
e075ae69 5284 }
0f40f9f7 5285 return "add{q}\t{%2, %0|%0, %2}";
e075ae69 5286 }
0f40f9f7 5287}
e075ae69
RH
5288 [(set (attr "type")
5289 (cond [(eq_attr "alternative" "2")
5290 (const_string "lea")
5291 ; Current assemblers are broken and do not allow @GOTOFF in
5292 ; ought but a memory context.
9b70259d 5293 (match_operand:DI 2 "pic_symbolic_operand" "")
e075ae69 5294 (const_string "lea")
9b70259d 5295 (match_operand:DI 2 "incdec_operand" "")
e075ae69
RH
5296 (const_string "incdec")
5297 ]
6ef67412 5298 (const_string "alu")))
9b70259d 5299 (set_attr "mode" "DI")])
e075ae69 5300
1c27d4b2
JH
5301;; Convert lea to the lea pattern to avoid flags dependency.
5302(define_split
9b70259d
JH
5303 [(set (match_operand:DI 0 "register_operand" "")
5304 (plus:DI (match_operand:DI 1 "register_operand" "")
5305 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
8bc527af 5306 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 5307 "TARGET_64BIT && reload_completed
abe24fb3 5308 && true_regnum (operands[0]) != true_regnum (operands[1])"
9b70259d
JH
5309 [(set (match_dup 0)
5310 (plus:DI (match_dup 1)
5311 (match_dup 2)))]
5312 "")
1c27d4b2 5313
9b70259d 5314(define_insn "*adddi_2_rex64"
42fabf21 5315 [(set (reg FLAGS_REG)
16189740 5316 (compare
9b70259d
JH
5317 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5318 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
e075ae69 5319 (const_int 0)))
9b70259d
JH
5320 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5321 (plus:DI (match_dup 1) (match_dup 2)))]
5322 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5323 && ix86_binary_operator_ok (PLUS, DImode, operands)
e075ae69 5324 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5325 ought but a memory context. */
e075ae69 5326 && ! pic_symbolic_operand (operands[2], VOIDmode)"
886c62d1 5327{
e075ae69 5328 switch (get_attr_type (insn))
96f218bb 5329 {
e075ae69
RH
5330 case TYPE_INCDEC:
5331 if (! rtx_equal_p (operands[0], operands[1]))
5332 abort ();
5333 if (operands[2] == const1_rtx)
0f40f9f7 5334 return "inc{q}\t%0";
e075ae69 5335 else if (operands[2] == constm1_rtx)
0f40f9f7 5336 return "dec{q}\t%0";
96f218bb 5337 else
9b70259d 5338 abort ();
96f218bb 5339
e075ae69
RH
5340 default:
5341 if (! rtx_equal_p (operands[0], operands[1]))
5342 abort ();
9b70259d 5343 /* ???? We ought to handle there the 32bit case too
5bdc5878 5344 - do we need new constraint? */
e075ae69
RH
5345 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5346 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5347 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5348 /* Avoid overflows. */
0f40f9f7 5349 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
e075ae69
RH
5350 && (INTVAL (operands[2]) == 128
5351 || (INTVAL (operands[2]) < 0
5352 && INTVAL (operands[2]) != -128)))
5353 {
5354 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5355 return "sub{q}\t{%2, %0|%0, %2}";
e075ae69 5356 }
0f40f9f7 5357 return "add{q}\t{%2, %0|%0, %2}";
9c530261 5358 }
0f40f9f7 5359}
e075ae69 5360 [(set (attr "type")
9b70259d 5361 (if_then_else (match_operand:DI 2 "incdec_operand" "")
e075ae69 5362 (const_string "incdec")
6ef67412 5363 (const_string "alu")))
9b70259d 5364 (set_attr "mode" "DI")])
e075ae69 5365
e74061a9 5366(define_insn "*adddi_3_rex64"
42fabf21 5367 [(set (reg FLAGS_REG)
9b70259d
JH
5368 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5369 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5370 (clobber (match_scratch:DI 0 "=r"))]
e74061a9
JH
5371 "TARGET_64BIT
5372 && ix86_match_ccmode (insn, CCZmode)
d90ffc8d
JH
5373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5374 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5375 ought but a memory context. */
d90ffc8d 5376 && ! pic_symbolic_operand (operands[2], VOIDmode)"
d90ffc8d
JH
5377{
5378 switch (get_attr_type (insn))
5379 {
5380 case TYPE_INCDEC:
5381 if (! rtx_equal_p (operands[0], operands[1]))
5382 abort ();
5383 if (operands[2] == const1_rtx)
0f40f9f7 5384 return "inc{q}\t%0";
d90ffc8d 5385 else if (operands[2] == constm1_rtx)
0f40f9f7 5386 return "dec{q}\t%0";
d90ffc8d 5387 else
9b70259d 5388 abort ();
d90ffc8d
JH
5389
5390 default:
5391 if (! rtx_equal_p (operands[0], operands[1]))
5392 abort ();
9b70259d 5393 /* ???? We ought to handle there the 32bit case too
5bdc5878 5394 - do we need new constraint? */
d90ffc8d
JH
5395 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5396 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5397 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5398 /* Avoid overflows. */
0f40f9f7 5399 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
d90ffc8d
JH
5400 && (INTVAL (operands[2]) == 128
5401 || (INTVAL (operands[2]) < 0
5402 && INTVAL (operands[2]) != -128)))
5403 {
5404 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5405 return "sub{q}\t{%2, %0|%0, %2}";
d90ffc8d 5406 }
0f40f9f7 5407 return "add{q}\t{%2, %0|%0, %2}";
d90ffc8d 5408 }
0f40f9f7 5409}
d90ffc8d 5410 [(set (attr "type")
9b70259d 5411 (if_then_else (match_operand:DI 2 "incdec_operand" "")
d90ffc8d
JH
5412 (const_string "incdec")
5413 (const_string "alu")))
9b70259d 5414 (set_attr "mode" "DI")])
d90ffc8d 5415
9b70259d 5416; For comparisons against 1, -1 and 128, we may generate better code
7e08e190
JH
5417; by converting cmp to add, inc or dec as done by peephole2. This pattern
5418; is matched then. We can't accept general immediate, because for
5419; case of overflows, the result is messed up.
9b70259d 5420; This pattern also don't hold of 0x8000000000000000, since the value overflows
7e08e190 5421; when negated.
d6a7951f 5422; Also carry flag is reversed compared to cmp, so this conversion is valid
7e08e190 5423; only for comparisons not depending on it.
e74061a9 5424(define_insn "*adddi_4_rex64"
42fabf21 5425 [(set (reg FLAGS_REG)
9b70259d
JH
5426 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5427 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5428 (clobber (match_scratch:DI 0 "=rm"))]
e74061a9
JH
5429 "TARGET_64BIT
5430 && ix86_match_ccmode (insn, CCGCmode)"
7e08e190
JH
5431{
5432 switch (get_attr_type (insn))
5433 {
5434 case TYPE_INCDEC:
5435 if (operands[2] == constm1_rtx)
0f40f9f7 5436 return "inc{q}\t%0";
7e08e190 5437 else if (operands[2] == const1_rtx)
0f40f9f7 5438 return "dec{q}\t%0";
7e08e190
JH
5439 else
5440 abort();
e075ae69 5441
7e08e190
JH
5442 default:
5443 if (! rtx_equal_p (operands[0], operands[1]))
5444 abort ();
5445 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5446 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5447 if ((INTVAL (operands[2]) == -128
5448 || (INTVAL (operands[2]) > 0
ef6257cd
JH
5449 && INTVAL (operands[2]) != 128))
5450 /* Avoid overflows. */
0f40f9f7
ZW
5451 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5452 return "sub{q}\t{%2, %0|%0, %2}";
7e08e190 5453 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5454 return "add{q}\t{%2, %0|%0, %2}";
7e08e190 5455 }
0f40f9f7 5456}
7e08e190 5457 [(set (attr "type")
9b70259d 5458 (if_then_else (match_operand:DI 2 "incdec_operand" "")
7e08e190
JH
5459 (const_string "incdec")
5460 (const_string "alu")))
9b70259d 5461 (set_attr "mode" "DI")])
d90ffc8d 5462
e74061a9 5463(define_insn "*adddi_5_rex64"
42fabf21 5464 [(set (reg FLAGS_REG)
9076b9c1 5465 (compare
9b70259d
JH
5466 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5467 (match_operand:DI 2 "x86_64_general_operand" "rme"))
9076b9c1 5468 (const_int 0)))
9b70259d 5469 (clobber (match_scratch:DI 0 "=r"))]
e74061a9
JH
5470 "TARGET_64BIT
5471 && ix86_match_ccmode (insn, CCGOCmode)
9076b9c1
JH
5472 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5473 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5474 ought but a memory context. */
9076b9c1 5475 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9076b9c1
JH
5476{
5477 switch (get_attr_type (insn))
5478 {
5479 case TYPE_INCDEC:
5480 if (! rtx_equal_p (operands[0], operands[1]))
5481 abort ();
5482 if (operands[2] == const1_rtx)
0f40f9f7 5483 return "inc{q}\t%0";
9076b9c1 5484 else if (operands[2] == constm1_rtx)
0f40f9f7 5485 return "dec{q}\t%0";
9076b9c1
JH
5486 else
5487 abort();
5488
5489 default:
5490 if (! rtx_equal_p (operands[0], operands[1]))
5491 abort ();
5492 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5493 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5494 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5495 /* Avoid overflows. */
0f40f9f7 5496 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
9076b9c1
JH
5497 && (INTVAL (operands[2]) == 128
5498 || (INTVAL (operands[2]) < 0
5499 && INTVAL (operands[2]) != -128)))
5500 {
5501 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5502 return "sub{q}\t{%2, %0|%0, %2}";
9076b9c1 5503 }
0f40f9f7 5504 return "add{q}\t{%2, %0|%0, %2}";
9076b9c1 5505 }
0f40f9f7 5506}
9076b9c1 5507 [(set (attr "type")
9b70259d 5508 (if_then_else (match_operand:DI 2 "incdec_operand" "")
9076b9c1
JH
5509 (const_string "incdec")
5510 (const_string "alu")))
9b70259d 5511 (set_attr "mode" "DI")])
2ae0f82c 5512
e075ae69 5513
9b70259d
JH
5514(define_insn "*addsi_1"
5515 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5516 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
9a9286af 5517 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
8bc527af 5518 (clobber (reg:CC FLAGS_REG))]
9b70259d 5519 "ix86_binary_operator_ok (PLUS, SImode, operands)"
58787064
JH
5520{
5521 switch (get_attr_type (insn))
5522 {
5523 case TYPE_LEA:
9b70259d 5524 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 5525 return "lea{l}\t{%a2, %0|%0, %a2}";
9b70259d 5526
58787064 5527 case TYPE_INCDEC:
9b70259d
JH
5528 if (! rtx_equal_p (operands[0], operands[1]))
5529 abort ();
58787064 5530 if (operands[2] == const1_rtx)
0f40f9f7 5531 return "inc{l}\t%0";
9b70259d 5532 else if (operands[2] == constm1_rtx)
0f40f9f7 5533 return "dec{l}\t%0";
9b70259d
JH
5534 else
5535 abort();
58787064
JH
5536
5537 default:
9b70259d
JH
5538 if (! rtx_equal_p (operands[0], operands[1]))
5539 abort ();
5540
58787064
JH
5541 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5542 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5543 if (GET_CODE (operands[2]) == CONST_INT
5544 && (INTVAL (operands[2]) == 128
5545 || (INTVAL (operands[2]) < 0
5546 && INTVAL (operands[2]) != -128)))
9b70259d
JH
5547 {
5548 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5549 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5550 }
0f40f9f7 5551 return "add{l}\t{%2, %0|%0, %2}";
58787064 5552 }
0f40f9f7 5553}
58787064 5554 [(set (attr "type")
9b70259d
JH
5555 (cond [(eq_attr "alternative" "2")
5556 (const_string "lea")
5557 ; Current assemblers are broken and do not allow @GOTOFF in
5558 ; ought but a memory context.
5559 (match_operand:SI 2 "pic_symbolic_operand" "")
5560 (const_string "lea")
5561 (match_operand:SI 2 "incdec_operand" "")
5562 (const_string "incdec")
5563 ]
5564 (const_string "alu")))
5565 (set_attr "mode" "SI")])
58787064 5566
9b70259d
JH
5567;; Convert lea to the lea pattern to avoid flags dependency.
5568(define_split
5569 [(set (match_operand 0 "register_operand" "")
5570 (plus (match_operand 1 "register_operand" "")
5571 (match_operand 2 "nonmemory_operand" "")))
8bc527af 5572 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
5573 "reload_completed
5574 && true_regnum (operands[0]) != true_regnum (operands[1])"
5575 [(const_int 0)]
9b70259d
JH
5576{
5577 rtx pat;
5578 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5579 may confuse gen_lowpart. */
5580 if (GET_MODE (operands[0]) != Pmode)
5581 {
5582 operands[1] = gen_lowpart (Pmode, operands[1]);
5583 operands[2] = gen_lowpart (Pmode, operands[2]);
5584 }
5585 operands[0] = gen_lowpart (SImode, operands[0]);
5586 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5587 if (Pmode != SImode)
5588 pat = gen_rtx_SUBREG (SImode, pat, 0);
5589 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5590 DONE;
0f40f9f7 5591})
9b70259d
JH
5592
5593;; It may seem that nonimmediate operand is proper one for operand 1.
5594;; The addsi_1 pattern allows nonimmediate operand at that place and
5595;; we take care in ix86_binary_operator_ok to not allow two memory
5596;; operands so proper swapping will be done in reload. This allow
5597;; patterns constructed from addsi_1 to match.
5598(define_insn "addsi_1_zext"
5599 [(set (match_operand:DI 0 "register_operand" "=r,r")
5600 (zero_extend:DI
5601 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
9a9286af 5602 (match_operand:SI 2 "general_operand" "rmni,lni"))))
8bc527af 5603 (clobber (reg:CC FLAGS_REG))]
9b70259d 5604 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
886c62d1 5605{
e075ae69 5606 switch (get_attr_type (insn))
7c802a40 5607 {
9b70259d
JH
5608 case TYPE_LEA:
5609 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 5610 return "lea{l}\t{%a2, %k0|%k0, %a2}";
9b70259d 5611
e075ae69
RH
5612 case TYPE_INCDEC:
5613 if (operands[2] == const1_rtx)
0f40f9f7 5614 return "inc{l}\t%k0";
9b70259d 5615 else if (operands[2] == constm1_rtx)
0f40f9f7 5616 return "dec{l}\t%k0";
9b70259d
JH
5617 else
5618 abort();
5619
5620 default:
5621 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5622 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5623 if (GET_CODE (operands[2]) == CONST_INT
5624 && (INTVAL (operands[2]) == 128
5625 || (INTVAL (operands[2]) < 0
5626 && INTVAL (operands[2]) != -128)))
5627 {
5628 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5629 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 5630 }
0f40f9f7 5631 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 5632 }
0f40f9f7 5633}
9b70259d
JH
5634 [(set (attr "type")
5635 (cond [(eq_attr "alternative" "1")
5636 (const_string "lea")
5637 ; Current assemblers are broken and do not allow @GOTOFF in
5638 ; ought but a memory context.
5639 (match_operand:SI 2 "pic_symbolic_operand" "")
5640 (const_string "lea")
5641 (match_operand:SI 2 "incdec_operand" "")
5642 (const_string "incdec")
5643 ]
5644 (const_string "alu")))
5645 (set_attr "mode" "SI")])
5646
5647;; Convert lea to the lea pattern to avoid flags dependency.
5648(define_split
5649 [(set (match_operand:DI 0 "register_operand" "")
5650 (zero_extend:DI
5651 (plus:SI (match_operand:SI 1 "register_operand" "")
5652 (match_operand:SI 2 "nonmemory_operand" ""))))
8bc527af 5653 (clobber (reg:CC FLAGS_REG))]
bc8a6d63 5654 "TARGET_64BIT && reload_completed
9b70259d
JH
5655 && true_regnum (operands[0]) != true_regnum (operands[1])"
5656 [(set (match_dup 0)
5657 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
9b70259d
JH
5658{
5659 operands[1] = gen_lowpart (Pmode, operands[1]);
5660 operands[2] = gen_lowpart (Pmode, operands[2]);
0f40f9f7 5661})
9b70259d
JH
5662
5663(define_insn "*addsi_2"
42fabf21 5664 [(set (reg FLAGS_REG)
9b70259d
JH
5665 (compare
5666 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5667 (match_operand:SI 2 "general_operand" "rmni,rni"))
5668 (const_int 0)))
5669 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5670 (plus:SI (match_dup 1) (match_dup 2)))]
5671 "ix86_match_ccmode (insn, CCGOCmode)
5672 && ix86_binary_operator_ok (PLUS, SImode, operands)
5673 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5674 ought but a memory context. */
9b70259d 5675 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
5676{
5677 switch (get_attr_type (insn))
5678 {
5679 case TYPE_INCDEC:
5680 if (! rtx_equal_p (operands[0], operands[1]))
5681 abort ();
5682 if (operands[2] == const1_rtx)
0f40f9f7 5683 return "inc{l}\t%0";
9b70259d 5684 else if (operands[2] == constm1_rtx)
0f40f9f7 5685 return "dec{l}\t%0";
9b70259d
JH
5686 else
5687 abort();
5688
5689 default:
5690 if (! rtx_equal_p (operands[0], operands[1]))
5691 abort ();
5692 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5693 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5694 if (GET_CODE (operands[2]) == CONST_INT
5695 && (INTVAL (operands[2]) == 128
5696 || (INTVAL (operands[2]) < 0
5697 && INTVAL (operands[2]) != -128)))
5698 {
5699 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5700 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5701 }
0f40f9f7 5702 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 5703 }
0f40f9f7 5704}
9b70259d
JH
5705 [(set (attr "type")
5706 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5707 (const_string "incdec")
5708 (const_string "alu")))
5709 (set_attr "mode" "SI")])
5710
5711;; See comment for addsi_1_zext why we do use nonimmediate_operand
5712(define_insn "*addsi_2_zext"
42fabf21 5713 [(set (reg FLAGS_REG)
9b70259d
JH
5714 (compare
5715 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5716 (match_operand:SI 2 "general_operand" "rmni"))
5717 (const_int 0)))
5718 (set (match_operand:DI 0 "register_operand" "=r")
5719 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5720 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5721 && ix86_binary_operator_ok (PLUS, SImode, operands)
5722 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5723 ought but a memory context. */
9b70259d 5724 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
5725{
5726 switch (get_attr_type (insn))
5727 {
5728 case TYPE_INCDEC:
5729 if (operands[2] == const1_rtx)
0f40f9f7 5730 return "inc{l}\t%k0";
9b70259d 5731 else if (operands[2] == constm1_rtx)
0f40f9f7 5732 return "dec{l}\t%k0";
9b70259d
JH
5733 else
5734 abort();
5735
5736 default:
5737 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5738 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5739 if (GET_CODE (operands[2]) == CONST_INT
5740 && (INTVAL (operands[2]) == 128
5741 || (INTVAL (operands[2]) < 0
5742 && INTVAL (operands[2]) != -128)))
5743 {
5744 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5745 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 5746 }
0f40f9f7 5747 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 5748 }
0f40f9f7 5749}
9b70259d
JH
5750 [(set (attr "type")
5751 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5752 (const_string "incdec")
5753 (const_string "alu")))
5754 (set_attr "mode" "SI")])
5755
5756(define_insn "*addsi_3"
42fabf21 5757 [(set (reg FLAGS_REG)
9b70259d
JH
5758 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5759 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5760 (clobber (match_scratch:SI 0 "=r"))]
5761 "ix86_match_ccmode (insn, CCZmode)
5762 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5763 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5764 ought but a memory context. */
9b70259d 5765 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
5766{
5767 switch (get_attr_type (insn))
5768 {
5769 case TYPE_INCDEC:
5770 if (! rtx_equal_p (operands[0], operands[1]))
5771 abort ();
5772 if (operands[2] == const1_rtx)
0f40f9f7 5773 return "inc{l}\t%0";
9b70259d 5774 else if (operands[2] == constm1_rtx)
0f40f9f7 5775 return "dec{l}\t%0";
9b70259d
JH
5776 else
5777 abort();
5778
5779 default:
5780 if (! rtx_equal_p (operands[0], operands[1]))
5781 abort ();
5782 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5783 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5784 if (GET_CODE (operands[2]) == CONST_INT
5785 && (INTVAL (operands[2]) == 128
5786 || (INTVAL (operands[2]) < 0
5787 && INTVAL (operands[2]) != -128)))
5788 {
5789 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5790 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5791 }
0f40f9f7 5792 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 5793 }
0f40f9f7 5794}
9b70259d
JH
5795 [(set (attr "type")
5796 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5797 (const_string "incdec")
5798 (const_string "alu")))
5799 (set_attr "mode" "SI")])
5800
5801;; See comment for addsi_1_zext why we do use nonimmediate_operand
5802(define_insn "*addsi_3_zext"
42fabf21 5803 [(set (reg FLAGS_REG)
9b70259d
JH
5804 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5805 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5806 (set (match_operand:DI 0 "register_operand" "=r")
5807 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5808 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5809 && ix86_binary_operator_ok (PLUS, SImode, operands)
5810 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5811 ought but a memory context. */
9b70259d 5812 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
5813{
5814 switch (get_attr_type (insn))
5815 {
5816 case TYPE_INCDEC:
5817 if (operands[2] == const1_rtx)
0f40f9f7 5818 return "inc{l}\t%k0";
9b70259d 5819 else if (operands[2] == constm1_rtx)
0f40f9f7 5820 return "dec{l}\t%k0";
9b70259d
JH
5821 else
5822 abort();
5823
5824 default:
5825 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5826 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5827 if (GET_CODE (operands[2]) == CONST_INT
5828 && (INTVAL (operands[2]) == 128
5829 || (INTVAL (operands[2]) < 0
5830 && INTVAL (operands[2]) != -128)))
5831 {
5832 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5833 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 5834 }
0f40f9f7 5835 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 5836 }
0f40f9f7 5837}
9b70259d
JH
5838 [(set (attr "type")
5839 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5840 (const_string "incdec")
5841 (const_string "alu")))
5842 (set_attr "mode" "SI")])
5843
4aae8a9a 5844; For comparisons against 1, -1 and 128, we may generate better code
9b70259d
JH
5845; by converting cmp to add, inc or dec as done by peephole2. This pattern
5846; is matched then. We can't accept general immediate, because for
5847; case of overflows, the result is messed up.
5848; This pattern also don't hold of 0x80000000, since the value overflows
5849; when negated.
d6a7951f 5850; Also carry flag is reversed compared to cmp, so this conversion is valid
9b70259d
JH
5851; only for comparisons not depending on it.
5852(define_insn "*addsi_4"
42fabf21 5853 [(set (reg FLAGS_REG)
9b70259d
JH
5854 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5855 (match_operand:SI 2 "const_int_operand" "n")))
5856 (clobber (match_scratch:SI 0 "=rm"))]
5857 "ix86_match_ccmode (insn, CCGCmode)
5858 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
9b70259d
JH
5859{
5860 switch (get_attr_type (insn))
5861 {
5862 case TYPE_INCDEC:
5863 if (operands[2] == constm1_rtx)
0f40f9f7 5864 return "inc{l}\t%0";
9b70259d 5865 else if (operands[2] == const1_rtx)
0f40f9f7 5866 return "dec{l}\t%0";
9b70259d
JH
5867 else
5868 abort();
5869
5870 default:
5871 if (! rtx_equal_p (operands[0], operands[1]))
5872 abort ();
5873 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5875 if ((INTVAL (operands[2]) == -128
5876 || (INTVAL (operands[2]) > 0
5877 && INTVAL (operands[2]) != 128)))
0f40f9f7 5878 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5879 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5880 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 5881 }
0f40f9f7 5882}
9b70259d
JH
5883 [(set (attr "type")
5884 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5885 (const_string "incdec")
5886 (const_string "alu")))
5887 (set_attr "mode" "SI")])
5888
5889(define_insn "*addsi_5"
42fabf21 5890 [(set (reg FLAGS_REG)
9b70259d
JH
5891 (compare
5892 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5893 (match_operand:SI 2 "general_operand" "rmni"))
5894 (const_int 0)))
5895 (clobber (match_scratch:SI 0 "=r"))]
5896 "ix86_match_ccmode (insn, CCGOCmode)
5897 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5898 /* Current assemblers are broken and do not allow @GOTOFF in
892a2d68 5899 ought but a memory context. */
9b70259d 5900 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
5901{
5902 switch (get_attr_type (insn))
5903 {
5904 case TYPE_INCDEC:
5905 if (! rtx_equal_p (operands[0], operands[1]))
5906 abort ();
5907 if (operands[2] == const1_rtx)
0f40f9f7 5908 return "inc{l}\t%0";
9b70259d 5909 else if (operands[2] == constm1_rtx)
0f40f9f7 5910 return "dec{l}\t%0";
9b70259d
JH
5911 else
5912 abort();
5913
5914 default:
5915 if (! rtx_equal_p (operands[0], operands[1]))
5916 abort ();
5917 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5918 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5919 if (GET_CODE (operands[2]) == CONST_INT
5920 && (INTVAL (operands[2]) == 128
5921 || (INTVAL (operands[2]) < 0
5922 && INTVAL (operands[2]) != -128)))
5923 {
5924 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5925 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5926 }
0f40f9f7 5927 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 5928 }
0f40f9f7 5929}
9b70259d
JH
5930 [(set (attr "type")
5931 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5932 (const_string "incdec")
5933 (const_string "alu")))
5934 (set_attr "mode" "SI")])
5935
5936(define_expand "addhi3"
5937 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5938 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5939 (match_operand:HI 2 "general_operand" "")))
8bc527af 5940 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
5941 "TARGET_HIMODE_MATH"
5942 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5943
5944;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5945;; type optimizations enabled by define-splits. This is not important
5946;; for PII, and in fact harmful because of partial register stalls.
5947
5948(define_insn "*addhi_1_lea"
5949 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5950 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
9a9286af 5951 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
8bc527af 5952 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
5953 "!TARGET_PARTIAL_REG_STALL
5954 && ix86_binary_operator_ok (PLUS, HImode, operands)"
9b70259d
JH
5955{
5956 switch (get_attr_type (insn))
5957 {
5958 case TYPE_LEA:
0f40f9f7 5959 return "#";
9b70259d
JH
5960 case TYPE_INCDEC:
5961 if (operands[2] == const1_rtx)
0f40f9f7 5962 return "inc{w}\t%0";
2f41793e 5963 else if (operands[2] == constm1_rtx)
0f40f9f7 5964 return "dec{w}\t%0";
9b70259d
JH
5965 abort();
5966
5967 default:
5968 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5969 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5970 if (GET_CODE (operands[2]) == CONST_INT
5971 && (INTVAL (operands[2]) == 128
5972 || (INTVAL (operands[2]) < 0
5973 && INTVAL (operands[2]) != -128)))
5974 {
5975 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5976 return "sub{w}\t{%2, %0|%0, %2}";
9b70259d 5977 }
0f40f9f7 5978 return "add{w}\t{%2, %0|%0, %2}";
9b70259d 5979 }
0f40f9f7 5980}
9b70259d
JH
5981 [(set (attr "type")
5982 (if_then_else (eq_attr "alternative" "2")
5983 (const_string "lea")
5984 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5985 (const_string "incdec")
5986 (const_string "alu"))))
5987 (set_attr "mode" "HI,HI,SI")])
5988
5989(define_insn "*addhi_1"
5990 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5991 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5992 (match_operand:HI 2 "general_operand" "ri,rm")))
8bc527af 5993 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
5994 "TARGET_PARTIAL_REG_STALL
5995 && ix86_binary_operator_ok (PLUS, HImode, operands)"
9b70259d
JH
5996{
5997 switch (get_attr_type (insn))
5998 {
5999 case TYPE_INCDEC:
6000 if (operands[2] == const1_rtx)
0f40f9f7 6001 return "inc{w}\t%0";
2f41793e 6002 else if (operands[2] == constm1_rtx)
0f40f9f7 6003 return "dec{w}\t%0";
e075ae69 6004 abort();
7c802a40 6005
e075ae69
RH
6006 default:
6007 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6008 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6009 if (GET_CODE (operands[2]) == CONST_INT
6010 && (INTVAL (operands[2]) == 128
6011 || (INTVAL (operands[2]) < 0
6012 && INTVAL (operands[2]) != -128)))
6013 {
6014 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6015 return "sub{w}\t{%2, %0|%0, %2}";
e075ae69 6016 }
0f40f9f7 6017 return "add{w}\t{%2, %0|%0, %2}";
7c802a40 6018 }
0f40f9f7 6019}
e075ae69
RH
6020 [(set (attr "type")
6021 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6022 (const_string "incdec")
6ef67412
JH
6023 (const_string "alu")))
6024 (set_attr "mode" "HI")])
7c802a40 6025
e075ae69 6026(define_insn "*addhi_2"
42fabf21 6027 [(set (reg FLAGS_REG)
16189740 6028 (compare
e075ae69
RH
6029 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6030 (match_operand:HI 2 "general_operand" "rmni,rni"))
6031 (const_int 0)))
6032 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6033 (plus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 6034 "ix86_match_ccmode (insn, CCGOCmode)
16189740 6035 && ix86_binary_operator_ok (PLUS, HImode, operands)"
e075ae69
RH
6036{
6037 switch (get_attr_type (insn))
b980bec0 6038 {
e075ae69
RH
6039 case TYPE_INCDEC:
6040 if (operands[2] == const1_rtx)
0f40f9f7 6041 return "inc{w}\t%0";
2f41793e 6042 else if (operands[2] == constm1_rtx)
0f40f9f7 6043 return "dec{w}\t%0";
e075ae69 6044 abort();
b980bec0 6045
e075ae69
RH
6046 default:
6047 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6048 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6049 if (GET_CODE (operands[2]) == CONST_INT
6050 && (INTVAL (operands[2]) == 128
6051 || (INTVAL (operands[2]) < 0
6052 && INTVAL (operands[2]) != -128)))
6053 {
6054 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6055 return "sub{w}\t{%2, %0|%0, %2}";
e075ae69 6056 }
0f40f9f7 6057 return "add{w}\t{%2, %0|%0, %2}";
b980bec0 6058 }
0f40f9f7 6059}
e075ae69
RH
6060 [(set (attr "type")
6061 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6062 (const_string "incdec")
6ef67412
JH
6063 (const_string "alu")))
6064 (set_attr "mode" "HI")])
e075ae69
RH
6065
6066(define_insn "*addhi_3"
42fabf21 6067 [(set (reg FLAGS_REG)
7e08e190
JH
6068 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6069 (match_operand:HI 1 "nonimmediate_operand" "%0")))
d90ffc8d 6070 (clobber (match_scratch:HI 0 "=r"))]
7e08e190 6071 "ix86_match_ccmode (insn, CCZmode)
d90ffc8d 6072 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
d90ffc8d
JH
6073{
6074 switch (get_attr_type (insn))
6075 {
6076 case TYPE_INCDEC:
6077 if (operands[2] == const1_rtx)
0f40f9f7 6078 return "inc{w}\t%0";
2f41793e 6079 else if (operands[2] == constm1_rtx)
0f40f9f7 6080 return "dec{w}\t%0";
d90ffc8d
JH
6081 abort();
6082
6083 default:
6084 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6085 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6086 if (GET_CODE (operands[2]) == CONST_INT
6087 && (INTVAL (operands[2]) == 128
6088 || (INTVAL (operands[2]) < 0
6089 && INTVAL (operands[2]) != -128)))
6090 {
6091 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6092 return "sub{w}\t{%2, %0|%0, %2}";
d90ffc8d 6093 }
0f40f9f7 6094 return "add{w}\t{%2, %0|%0, %2}";
d90ffc8d 6095 }
0f40f9f7 6096}
d90ffc8d
JH
6097 [(set (attr "type")
6098 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6099 (const_string "incdec")
6100 (const_string "alu")))
6101 (set_attr "mode" "HI")])
6102
d1c9ce9f 6103; See comments above addsi_4 for details.
d90ffc8d 6104(define_insn "*addhi_4"
42fabf21 6105 [(set (reg FLAGS_REG)
7e08e190
JH
6106 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6107 (match_operand:HI 2 "const_int_operand" "n")))
6108 (clobber (match_scratch:HI 0 "=rm"))]
6109 "ix86_match_ccmode (insn, CCGCmode)
6110 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7e08e190
JH
6111{
6112 switch (get_attr_type (insn))
6113 {
6114 case TYPE_INCDEC:
2f41793e 6115 if (operands[2] == constm1_rtx)
0f40f9f7 6116 return "inc{w}\t%0";
7e08e190 6117 else if (operands[2] == const1_rtx)
0f40f9f7 6118 return "dec{w}\t%0";
7e08e190
JH
6119 else
6120 abort();
6121
6122 default:
6123 if (! rtx_equal_p (operands[0], operands[1]))
6124 abort ();
6125 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6127 if ((INTVAL (operands[2]) == -128
6128 || (INTVAL (operands[2]) > 0
6129 && INTVAL (operands[2]) != 128)))
0f40f9f7 6130 return "sub{w}\t{%2, %0|%0, %2}";
7e08e190 6131 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6132 return "add{w}\t{%2, %0|%0, %2}";
7e08e190 6133 }
0f40f9f7 6134}
7e08e190
JH
6135 [(set (attr "type")
6136 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6137 (const_string "incdec")
6138 (const_string "alu")))
6139 (set_attr "mode" "SI")])
b980bec0 6140
d90ffc8d 6141
7e08e190 6142(define_insn "*addhi_5"
42fabf21 6143 [(set (reg FLAGS_REG)
9076b9c1
JH
6144 (compare
6145 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6146 (match_operand:HI 2 "general_operand" "rmni"))
6147 (const_int 0)))
6148 (clobber (match_scratch:HI 0 "=r"))]
6149 "ix86_match_ccmode (insn, CCGOCmode)
6150 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9076b9c1
JH
6151{
6152 switch (get_attr_type (insn))
6153 {
6154 case TYPE_INCDEC:
6155 if (operands[2] == const1_rtx)
0f40f9f7 6156 return "inc{w}\t%0";
2f41793e 6157 else if (operands[2] == constm1_rtx)
0f40f9f7 6158 return "dec{w}\t%0";
9076b9c1
JH
6159 abort();
6160
6161 default:
6162 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6163 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6164 if (GET_CODE (operands[2]) == CONST_INT
6165 && (INTVAL (operands[2]) == 128
6166 || (INTVAL (operands[2]) < 0
6167 && INTVAL (operands[2]) != -128)))
6168 {
6169 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6170 return "sub{w}\t{%2, %0|%0, %2}";
9076b9c1 6171 }
0f40f9f7 6172 return "add{w}\t{%2, %0|%0, %2}";
9076b9c1 6173 }
0f40f9f7 6174}
9076b9c1
JH
6175 [(set (attr "type")
6176 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6177 (const_string "incdec")
6178 (const_string "alu")))
6179 (set_attr "mode" "HI")])
6180
e075ae69 6181(define_expand "addqi3"
4cbfbb1b
JH
6182 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6183 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
e075ae69 6184 (match_operand:QI 2 "general_operand" "")))
8bc527af 6185 (clobber (reg:CC FLAGS_REG))])]
d9f32422 6186 "TARGET_QIMODE_MATH"
e075ae69
RH
6187 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6188
6189;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
6190(define_insn "*addqi_1_lea"
6191 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6192 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
9a9286af 6193 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
8bc527af 6194 (clobber (reg:CC FLAGS_REG))]
58787064
JH
6195 "!TARGET_PARTIAL_REG_STALL
6196 && ix86_binary_operator_ok (PLUS, QImode, operands)"
58787064
JH
6197{
6198 int widen = (which_alternative == 2);
6199 switch (get_attr_type (insn))
6200 {
6201 case TYPE_LEA:
0f40f9f7 6202 return "#";
58787064
JH
6203 case TYPE_INCDEC:
6204 if (operands[2] == const1_rtx)
0f40f9f7 6205 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
2f41793e 6206 else if (operands[2] == constm1_rtx)
0f40f9f7 6207 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
58787064
JH
6208 abort();
6209
6210 default:
6211 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6212 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6213 if (GET_CODE (operands[2]) == CONST_INT
6214 && (INTVAL (operands[2]) == 128
6215 || (INTVAL (operands[2]) < 0
6216 && INTVAL (operands[2]) != -128)))
6217 {
6218 operands[2] = GEN_INT (-INTVAL (operands[2]));
6219 if (widen)
0f40f9f7 6220 return "sub{l}\t{%2, %k0|%k0, %2}";
58787064 6221 else
0f40f9f7 6222 return "sub{b}\t{%2, %0|%0, %2}";
58787064
JH
6223 }
6224 if (widen)
0f40f9f7 6225 return "add{l}\t{%k2, %k0|%k0, %k2}";
58787064 6226 else
0f40f9f7 6227 return "add{b}\t{%2, %0|%0, %2}";
58787064 6228 }
0f40f9f7 6229}
58787064
JH
6230 [(set (attr "type")
6231 (if_then_else (eq_attr "alternative" "3")
6232 (const_string "lea")
adc88131 6233 (if_then_else (match_operand:QI 2 "incdec_operand" "")
58787064
JH
6234 (const_string "incdec")
6235 (const_string "alu"))))
adc88131 6236 (set_attr "mode" "QI,QI,SI,SI")])
58787064 6237
e075ae69 6238(define_insn "*addqi_1"
7c6b971d 6239 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 6240 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 6241 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8bc527af 6242 (clobber (reg:CC FLAGS_REG))]
58787064
JH
6243 "TARGET_PARTIAL_REG_STALL
6244 && ix86_binary_operator_ok (PLUS, QImode, operands)"
e075ae69
RH
6245{
6246 int widen = (which_alternative == 2);
6247 switch (get_attr_type (insn))
5bc7cd8e 6248 {
e075ae69
RH
6249 case TYPE_INCDEC:
6250 if (operands[2] == const1_rtx)
0f40f9f7 6251 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
2f41793e 6252 else if (operands[2] == constm1_rtx)
0f40f9f7 6253 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
e075ae69 6254 abort();
5bc7cd8e 6255
e075ae69
RH
6256 default:
6257 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6258 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6259 if (GET_CODE (operands[2]) == CONST_INT
6260 && (INTVAL (operands[2]) == 128
6261 || (INTVAL (operands[2]) < 0
6262 && INTVAL (operands[2]) != -128)))
5bc7cd8e 6263 {
e075ae69
RH
6264 operands[2] = GEN_INT (-INTVAL (operands[2]));
6265 if (widen)
0f40f9f7 6266 return "sub{l}\t{%2, %k0|%k0, %2}";
e075ae69 6267 else
0f40f9f7 6268 return "sub{b}\t{%2, %0|%0, %2}";
5bc7cd8e 6269 }
e075ae69 6270 if (widen)
0f40f9f7 6271 return "add{l}\t{%k2, %k0|%k0, %k2}";
e075ae69 6272 else
0f40f9f7 6273 return "add{b}\t{%2, %0|%0, %2}";
5bc7cd8e 6274 }
0f40f9f7 6275}
e075ae69
RH
6276 [(set (attr "type")
6277 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6278 (const_string "incdec")
6ef67412
JH
6279 (const_string "alu")))
6280 (set_attr "mode" "QI,QI,SI")])
e075ae69 6281
2f41793e
JH
6282(define_insn "*addqi_1_slp"
6283 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1b245ade
JH
6284 (plus:QI (match_dup 0)
6285 (match_operand:QI 1 "general_operand" "qn,qnm")))
8bc527af 6286 (clobber (reg:CC FLAGS_REG))]
2f41793e 6287 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade 6288 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f41793e
JH
6289{
6290 switch (get_attr_type (insn))
6291 {
6292 case TYPE_INCDEC:
95199202 6293 if (operands[1] == const1_rtx)
2f41793e 6294 return "inc{b}\t%0";
95199202 6295 else if (operands[1] == constm1_rtx)
2f41793e
JH
6296 return "dec{b}\t%0";
6297 abort();
6298
6299 default:
6300 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
95199202
JH
6301 if (GET_CODE (operands[1]) == CONST_INT
6302 && INTVAL (operands[1]) < 0)
2f41793e 6303 {
79551a56 6304 operands[1] = GEN_INT (-INTVAL (operands[1]));
1b245ade 6305 return "sub{b}\t{%1, %0|%0, %1}";
2f41793e 6306 }
1b245ade 6307 return "add{b}\t{%1, %0|%0, %1}";
2f41793e
JH
6308 }
6309}
6310 [(set (attr "type")
ba3ed8d8 6311 (if_then_else (match_operand:QI 1 "incdec_operand" "")
2f41793e 6312 (const_string "incdec")
95199202 6313 (const_string "alu1")))
ebc0c8bb
JJ
6314 (set (attr "memory")
6315 (if_then_else (match_operand 1 "memory_operand" "")
6316 (const_string "load")
6317 (const_string "none")))
2f41793e
JH
6318 (set_attr "mode" "QI")])
6319
e075ae69 6320(define_insn "*addqi_2"
42fabf21 6321 [(set (reg FLAGS_REG)
16189740 6322 (compare
e075ae69
RH
6323 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6324 (match_operand:QI 2 "general_operand" "qmni,qni"))
6325 (const_int 0)))
6326 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6327 (plus:QI (match_dup 1) (match_dup 2)))]
9076b9c1 6328 "ix86_match_ccmode (insn, CCGOCmode)
16189740 6329 && ix86_binary_operator_ok (PLUS, QImode, operands)"
e075ae69
RH
6330{
6331 switch (get_attr_type (insn))
6332 {
6333 case TYPE_INCDEC:
6334 if (operands[2] == const1_rtx)
0f40f9f7 6335 return "inc{b}\t%0";
e075ae69
RH
6336 else if (operands[2] == constm1_rtx
6337 || (GET_CODE (operands[2]) == CONST_INT
6338 && INTVAL (operands[2]) == 255))
0f40f9f7 6339 return "dec{b}\t%0";
e075ae69 6340 abort();
5bc7cd8e 6341
e075ae69
RH
6342 default:
6343 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6344 if (GET_CODE (operands[2]) == CONST_INT
6345 && INTVAL (operands[2]) < 0)
6346 {
6347 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6348 return "sub{b}\t{%2, %0|%0, %2}";
e075ae69 6349 }
0f40f9f7 6350 return "add{b}\t{%2, %0|%0, %2}";
e075ae69 6351 }
0f40f9f7 6352}
e075ae69
RH
6353 [(set (attr "type")
6354 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6355 (const_string "incdec")
6ef67412
JH
6356 (const_string "alu")))
6357 (set_attr "mode" "QI")])
e075ae69
RH
6358
6359(define_insn "*addqi_3"
42fabf21 6360 [(set (reg FLAGS_REG)
7e08e190
JH
6361 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6362 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6363 (clobber (match_scratch:QI 0 "=q"))]
6364 "ix86_match_ccmode (insn, CCZmode)
d90ffc8d 6365 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
d90ffc8d
JH
6366{
6367 switch (get_attr_type (insn))
6368 {
6369 case TYPE_INCDEC:
6370 if (operands[2] == const1_rtx)
0f40f9f7 6371 return "inc{b}\t%0";
d90ffc8d
JH
6372 else if (operands[2] == constm1_rtx
6373 || (GET_CODE (operands[2]) == CONST_INT
6374 && INTVAL (operands[2]) == 255))
0f40f9f7 6375 return "dec{b}\t%0";
d90ffc8d
JH
6376 abort();
6377
6378 default:
6379 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6380 if (GET_CODE (operands[2]) == CONST_INT
6381 && INTVAL (operands[2]) < 0)
6382 {
6383 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6384 return "sub{b}\t{%2, %0|%0, %2}";
d90ffc8d 6385 }
0f40f9f7 6386 return "add{b}\t{%2, %0|%0, %2}";
d90ffc8d 6387 }
0f40f9f7 6388}
d90ffc8d
JH
6389 [(set (attr "type")
6390 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6391 (const_string "incdec")
6392 (const_string "alu")))
6393 (set_attr "mode" "QI")])
6394
d1c9ce9f 6395; See comments above addsi_4 for details.
d90ffc8d 6396(define_insn "*addqi_4"
42fabf21 6397 [(set (reg FLAGS_REG)
7e08e190
JH
6398 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6399 (match_operand:QI 2 "const_int_operand" "n")))
6400 (clobber (match_scratch:QI 0 "=qm"))]
6401 "ix86_match_ccmode (insn, CCGCmode)
6402 && (INTVAL (operands[2]) & 0xff) != 0x80"
7e08e190
JH
6403{
6404 switch (get_attr_type (insn))
6405 {
6406 case TYPE_INCDEC:
6407 if (operands[2] == constm1_rtx
6408 || (GET_CODE (operands[2]) == CONST_INT
6409 && INTVAL (operands[2]) == 255))
0f40f9f7 6410 return "inc{b}\t%0";
7e08e190 6411 else if (operands[2] == const1_rtx)
0f40f9f7 6412 return "dec{b}\t%0";
7e08e190
JH
6413 else
6414 abort();
6415
6416 default:
6417 if (! rtx_equal_p (operands[0], operands[1]))
6418 abort ();
6419 if (INTVAL (operands[2]) < 0)
6420 {
6421 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6422 return "add{b}\t{%2, %0|%0, %2}";
7e08e190 6423 }
0f40f9f7 6424 return "sub{b}\t{%2, %0|%0, %2}";
7e08e190 6425 }
0f40f9f7 6426}
7e08e190
JH
6427 [(set (attr "type")
6428 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6429 (const_string "incdec")
6430 (const_string "alu")))
6ef67412 6431 (set_attr "mode" "QI")])
886c62d1 6432
9dcbdc7e 6433
d90ffc8d 6434(define_insn "*addqi_5"
42fabf21 6435 [(set (reg FLAGS_REG)
9076b9c1
JH
6436 (compare
6437 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6438 (match_operand:QI 2 "general_operand" "qmni"))
6439 (const_int 0)))
7e08e190 6440 (clobber (match_scratch:QI 0 "=q"))]
9076b9c1
JH
6441 "ix86_match_ccmode (insn, CCGOCmode)
6442 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9076b9c1
JH
6443{
6444 switch (get_attr_type (insn))
6445 {
6446 case TYPE_INCDEC:
6447 if (operands[2] == const1_rtx)
0f40f9f7 6448 return "inc{b}\t%0";
9076b9c1
JH
6449 else if (operands[2] == constm1_rtx
6450 || (GET_CODE (operands[2]) == CONST_INT
6451 && INTVAL (operands[2]) == 255))
0f40f9f7 6452 return "dec{b}\t%0";
9076b9c1
JH
6453 abort();
6454
6455 default:
6456 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6457 if (GET_CODE (operands[2]) == CONST_INT
6458 && INTVAL (operands[2]) < 0)
6459 {
6460 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6461 return "sub{b}\t{%2, %0|%0, %2}";
9076b9c1 6462 }
0f40f9f7 6463 return "add{b}\t{%2, %0|%0, %2}";
9076b9c1 6464 }
0f40f9f7 6465}
9076b9c1
JH
6466 [(set (attr "type")
6467 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6468 (const_string "incdec")
6469 (const_string "alu")))
6470 (set_attr "mode" "QI")])
6471
e075ae69
RH
6472
6473(define_insn "addqi_ext_1"
3522082b 6474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6475 (const_int 8)
6476 (const_int 8))
6477 (plus:SI
6478 (zero_extract:SI
6479 (match_operand 1 "ext_register_operand" "0")
6480 (const_int 8)
6481 (const_int 8))
3522082b 6482 (match_operand:QI 2 "general_operand" "Qmn")))
8bc527af 6483 (clobber (reg:CC FLAGS_REG))]
d2836273 6484 "!TARGET_64BIT"
d2836273
JH
6485{
6486 switch (get_attr_type (insn))
6487 {
6488 case TYPE_INCDEC:
6489 if (operands[2] == const1_rtx)
0f40f9f7 6490 return "inc{b}\t%h0";
d2836273
JH
6491 else if (operands[2] == constm1_rtx
6492 || (GET_CODE (operands[2]) == CONST_INT
6493 && INTVAL (operands[2]) == 255))
0f40f9f7 6494 return "dec{b}\t%h0";
d2836273
JH
6495 abort();
6496
6497 default:
0f40f9f7 6498 return "add{b}\t{%2, %h0|%h0, %2}";
d2836273 6499 }
0f40f9f7 6500}
d2836273
JH
6501 [(set (attr "type")
6502 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6503 (const_string "incdec")
6504 (const_string "alu")))
6505 (set_attr "mode" "QI")])
6506
6507(define_insn "*addqi_ext_1_rex64"
6508 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6509 (const_int 8)
6510 (const_int 8))
6511 (plus:SI
6512 (zero_extract:SI
6513 (match_operand 1 "ext_register_operand" "0")
6514 (const_int 8)
6515 (const_int 8))
6516 (match_operand:QI 2 "nonmemory_operand" "Qn")))
8bc527af 6517 (clobber (reg:CC FLAGS_REG))]
d2836273 6518 "TARGET_64BIT"
e075ae69
RH
6519{
6520 switch (get_attr_type (insn))
6521 {
6522 case TYPE_INCDEC:
6523 if (operands[2] == const1_rtx)
0f40f9f7 6524 return "inc{b}\t%h0";
e075ae69
RH
6525 else if (operands[2] == constm1_rtx
6526 || (GET_CODE (operands[2]) == CONST_INT
6527 && INTVAL (operands[2]) == 255))
0f40f9f7 6528 return "dec{b}\t%h0";
e075ae69 6529 abort();
886c62d1 6530
e075ae69 6531 default:
0f40f9f7 6532 return "add{b}\t{%2, %h0|%h0, %2}";
e075ae69 6533 }
0f40f9f7 6534}
e075ae69
RH
6535 [(set (attr "type")
6536 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6537 (const_string "incdec")
6ef67412
JH
6538 (const_string "alu")))
6539 (set_attr "mode" "QI")])
e075ae69
RH
6540
6541(define_insn "*addqi_ext_2"
d2836273 6542 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6543 (const_int 8)
6544 (const_int 8))
6545 (plus:SI
6546 (zero_extract:SI
6547 (match_operand 1 "ext_register_operand" "%0")
6548 (const_int 8)
6549 (const_int 8))
6550 (zero_extract:SI
d2836273 6551 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
6552 (const_int 8)
6553 (const_int 8))))
8bc527af 6554 (clobber (reg:CC FLAGS_REG))]
e075ae69 6555 ""
0f40f9f7 6556 "add{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
6557 [(set_attr "type" "alu")
6558 (set_attr "mode" "QI")])
886c62d1 6559
886c62d1
JVA
6560;; The patterns that match these are at the end of this file.
6561
4fb21e90
JVA
6562(define_expand "addxf3"
6563 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
6564 (plus:XF (match_operand:XF 1 "register_operand" "")
6565 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
6566 "TARGET_80387"
6567 "")
6568
886c62d1
JVA
6569(define_expand "adddf3"
6570 [(set (match_operand:DF 0 "register_operand" "")
06a964de 6571 (plus:DF (match_operand:DF 1 "register_operand" "")
886c62d1 6572 (match_operand:DF 2 "nonimmediate_operand" "")))]
965f5423 6573 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
886c62d1
JVA
6574 "")
6575
6576(define_expand "addsf3"
6577 [(set (match_operand:SF 0 "register_operand" "")
06a964de 6578 (plus:SF (match_operand:SF 1 "register_operand" "")
886c62d1 6579 (match_operand:SF 2 "nonimmediate_operand" "")))]
965f5423 6580 "TARGET_80387 || TARGET_SSE_MATH"
886c62d1
JVA
6581 "")
6582\f
e075ae69 6583;; Subtract instructions
a269a03c 6584
e075ae69 6585;; %%% splits for subsidi3
2ae0f82c 6586
9b70259d
JH
6587(define_expand "subdi3"
6588 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6589 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6590 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 6591 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
6592 ""
6593 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6594
6595(define_insn "*subdi3_1"
e075ae69 6596 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4cbfbb1b 6597 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
e075ae69 6598 (match_operand:DI 2 "general_operand" "roiF,riF")))
8bc527af 6599 (clobber (reg:CC FLAGS_REG))]
43146684 6600 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
e075ae69 6601 "#")
9c530261 6602
e075ae69
RH
6603(define_split
6604 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4cbfbb1b 6605 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
e075ae69 6606 (match_operand:DI 2 "general_operand" "")))
8bc527af 6607 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 6608 "!TARGET_64BIT && reload_completed"
8bc527af 6609 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
e075ae69
RH
6610 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6611 (parallel [(set (match_dup 3)
6612 (minus:SI (match_dup 4)
8bc527af 6613 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9dcbdc7e 6614 (match_dup 5))))
8bc527af 6615 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
6616 "split_di (operands+0, 1, operands+0, operands+3);
6617 split_di (operands+1, 1, operands+1, operands+4);
6618 split_di (operands+2, 1, operands+2, operands+5);")
6619
9b70259d
JH
6620(define_insn "subdi3_carry_rex64"
6621 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6622 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
9b74f3ea 6623 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
9b70259d 6624 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
8bc527af 6625 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 6626 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 6627 "sbb{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6628 [(set_attr "type" "alu")
6629 (set_attr "pent_pair" "pu")
9b70259d
JH
6630 (set_attr "mode" "DI")])
6631
6632(define_insn "*subdi_1_rex64"
6633 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6634 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6635 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8bc527af 6636 (clobber (reg:CC FLAGS_REG))]
9b70259d 6637 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 6638 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6639 [(set_attr "type" "alu")
6640 (set_attr "mode" "DI")])
6641
6642(define_insn "*subdi_2_rex64"
42fabf21 6643 [(set (reg FLAGS_REG)
9b70259d
JH
6644 (compare
6645 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6646 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6647 (const_int 0)))
6648 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6649 (minus:DI (match_dup 1) (match_dup 2)))]
6650 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6651 && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 6652 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6653 [(set_attr "type" "alu")
6654 (set_attr "mode" "DI")])
6655
6656(define_insn "*subdi_3_rex63"
42fabf21 6657 [(set (reg FLAGS_REG)
9b70259d
JH
6658 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6659 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
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, CCmode)
6663 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6664 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6665 [(set_attr "type" "alu")
6666 (set_attr "mode" "DI")])
6667
7b52eede 6668(define_insn "subqi3_carry"
d67e96cf 6669 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7b52eede 6670 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
e6e81735 6671 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
d67e96cf 6672 (match_operand:QI 2 "general_operand" "qi,qm"))))
8bc527af 6673 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
6674 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6675 "sbb{b}\t{%2, %0|%0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "pent_pair" "pu")
7b52eede
JH
6678 (set_attr "mode" "QI")])
6679
6680(define_insn "subhi3_carry"
6681 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6682 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
e6e81735 6683 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7b52eede 6684 (match_operand:HI 2 "general_operand" "ri,rm"))))
8bc527af 6685 (clobber (reg:CC FLAGS_REG))]
7b52eede
JH
6686 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6687 "sbb{w}\t{%2, %0|%0, %2}"
6688 [(set_attr "type" "alu")
6689 (set_attr "pent_pair" "pu")
7b52eede 6690 (set_attr "mode" "HI")])
9b70259d 6691
7e08e190 6692(define_insn "subsi3_carry"
e075ae69
RH
6693 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6694 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
e6e81735 6695 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9dcbdc7e 6696 (match_operand:SI 2 "general_operand" "ri,rm"))))
8bc527af 6697 (clobber (reg:CC FLAGS_REG))]
d525dfdf 6698 "ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6699 "sbb{l}\t{%2, %0|%0, %2}"
e075ae69
RH
6700 [(set_attr "type" "alu")
6701 (set_attr "pent_pair" "pu")
6ef67412 6702 (set_attr "mode" "SI")])
886c62d1 6703
9b70259d
JH
6704(define_insn "subsi3_carry_zext"
6705 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6706 (zero_extend:DI
6707 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
e6e81735 6708 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
9b70259d 6709 (match_operand:SI 2 "general_operand" "ri,rm")))))
8bc527af 6710 (clobber (reg:CC FLAGS_REG))]
9b70259d 6711 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6712 "sbb{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
6713 [(set_attr "type" "alu")
6714 (set_attr "pent_pair" "pu")
9b70259d
JH
6715 (set_attr "mode" "SI")])
6716
2ae0f82c 6717(define_expand "subsi3"
e075ae69
RH
6718 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6719 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6720 (match_operand:SI 2 "general_operand" "")))
8bc527af 6721 (clobber (reg:CC FLAGS_REG))])]
886c62d1 6722 ""
e075ae69 6723 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
2ae0f82c 6724
e075ae69 6725(define_insn "*subsi_1"
2ae0f82c
SC
6726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6727 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
e075ae69 6728 (match_operand:SI 2 "general_operand" "ri,rm")))
8bc527af 6729 (clobber (reg:CC FLAGS_REG))]
e075ae69 6730 "ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6731 "sub{l}\t{%2, %0|%0, %2}"
6ef67412
JH
6732 [(set_attr "type" "alu")
6733 (set_attr "mode" "SI")])
e075ae69 6734
9b70259d
JH
6735(define_insn "*subsi_1_zext"
6736 [(set (match_operand:DI 0 "register_operand" "=r")
6737 (zero_extend:DI
6738 (minus:SI (match_operand:SI 1 "register_operand" "0")
6739 (match_operand:SI 2 "general_operand" "rim"))))
8bc527af 6740 (clobber (reg:CC FLAGS_REG))]
9b70259d 6741 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6742 "sub{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
6743 [(set_attr "type" "alu")
6744 (set_attr "mode" "SI")])
6745
e075ae69 6746(define_insn "*subsi_2"
42fabf21 6747 [(set (reg FLAGS_REG)
16189740 6748 (compare
e075ae69
RH
6749 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6750 (match_operand:SI 2 "general_operand" "ri,rm"))
6751 (const_int 0)))
6752 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6753 (minus:SI (match_dup 1) (match_dup 2)))]
9076b9c1 6754 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 6755 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6756 "sub{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
6757 [(set_attr "type" "alu")
6758 (set_attr "mode" "SI")])
6759
9b70259d 6760(define_insn "*subsi_2_zext"
42fabf21 6761 [(set (reg FLAGS_REG)
9b70259d
JH
6762 (compare
6763 (minus:SI (match_operand:SI 1 "register_operand" "0")
6764 (match_operand:SI 2 "general_operand" "rim"))
6765 (const_int 0)))
6766 (set (match_operand:DI 0 "register_operand" "=r")
6767 (zero_extend:DI
6768 (minus:SI (match_dup 1)
6769 (match_dup 2))))]
6770 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6771 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6772 "sub{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
6773 [(set_attr "type" "alu")
6774 (set_attr "mode" "SI")])
6775
d90ffc8d 6776(define_insn "*subsi_3"
42fabf21 6777 [(set (reg FLAGS_REG)
d90ffc8d
JH
6778 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6779 (match_operand:SI 2 "general_operand" "ri,rm")))
6780 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6781 (minus:SI (match_dup 1) (match_dup 2)))]
16189740
RH
6782 "ix86_match_ccmode (insn, CCmode)
6783 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6784 "sub{l}\t{%2, %0|%0, %2}"
6ef67412
JH
6785 [(set_attr "type" "alu")
6786 (set_attr "mode" "SI")])
886c62d1 6787
9b70259d 6788(define_insn "*subsi_3_zext"
42fabf21 6789 [(set (reg FLAGS_REG)
10e9fecc 6790 (compare (match_operand:SI 1 "register_operand" "0")
9b70259d
JH
6791 (match_operand:SI 2 "general_operand" "rim")))
6792 (set (match_operand:DI 0 "register_operand" "=r")
6793 (zero_extend:DI
6794 (minus:SI (match_dup 1)
6795 (match_dup 2))))]
8362f420 6796 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
9b70259d 6797 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6798 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6799 [(set_attr "type" "alu")
6800 (set_attr "mode" "DI")])
6801
2ae0f82c 6802(define_expand "subhi3"
4cbfbb1b 6803 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
e075ae69
RH
6804 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6805 (match_operand:HI 2 "general_operand" "")))
8bc527af 6806 (clobber (reg:CC FLAGS_REG))])]
d9f32422 6807 "TARGET_HIMODE_MATH"
e075ae69 6808 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
2ae0f82c 6809
e075ae69 6810(define_insn "*subhi_1"
2ae0f82c 6811 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
87fd1847 6812 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
e075ae69 6813 (match_operand:HI 2 "general_operand" "ri,rm")))
8bc527af 6814 (clobber (reg:CC FLAGS_REG))]
2ae0f82c 6815 "ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 6816 "sub{w}\t{%2, %0|%0, %2}"
6ef67412
JH
6817 [(set_attr "type" "alu")
6818 (set_attr "mode" "HI")])
e075ae69
RH
6819
6820(define_insn "*subhi_2"
42fabf21 6821 [(set (reg FLAGS_REG)
16189740 6822 (compare
e075ae69
RH
6823 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6824 (match_operand:HI 2 "general_operand" "ri,rm"))
6825 (const_int 0)))
6826 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6827 (minus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 6828 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 6829 && ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 6830 "sub{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
6831 [(set_attr "type" "alu")
6832 (set_attr "mode" "HI")])
6833
6834(define_insn "*subhi_3"
42fabf21 6835 [(set (reg FLAGS_REG)
d90ffc8d
JH
6836 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6837 (match_operand:HI 2 "general_operand" "ri,rm")))
6838 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6839 (minus:HI (match_dup 1) (match_dup 2)))]
16189740
RH
6840 "ix86_match_ccmode (insn, CCmode)
6841 && ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 6842 "sub{w}\t{%2, %0|%0, %2}"
6ef67412
JH
6843 [(set_attr "type" "alu")
6844 (set_attr "mode" "HI")])
886c62d1 6845
2ae0f82c 6846(define_expand "subqi3"
4cbfbb1b
JH
6847 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6848 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
e075ae69 6849 (match_operand:QI 2 "general_operand" "")))
8bc527af 6850 (clobber (reg:CC FLAGS_REG))])]
d9f32422 6851 "TARGET_QIMODE_MATH"
e075ae69 6852 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
2ae0f82c 6853
e075ae69 6854(define_insn "*subqi_1"
2ae0f82c
SC
6855 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6856 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
e075ae69 6857 (match_operand:QI 2 "general_operand" "qn,qmn")))
8bc527af 6858 (clobber (reg:CC FLAGS_REG))]
e075ae69 6859 "ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 6860 "sub{b}\t{%2, %0|%0, %2}"
6ef67412
JH
6861 [(set_attr "type" "alu")
6862 (set_attr "mode" "QI")])
e075ae69 6863
2f41793e
JH
6864(define_insn "*subqi_1_slp"
6865 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1b245ade
JH
6866 (minus:QI (match_dup 0)
6867 (match_operand:QI 1 "general_operand" "qn,qmn")))
8bc527af 6868 (clobber (reg:CC FLAGS_REG))]
2f41793e 6869 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade
JH
6870 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6871 "sub{b}\t{%1, %0|%0, %1}"
95199202 6872 [(set_attr "type" "alu1")
2f41793e
JH
6873 (set_attr "mode" "QI")])
6874
e075ae69 6875(define_insn "*subqi_2"
42fabf21 6876 [(set (reg FLAGS_REG)
16189740 6877 (compare
e075ae69
RH
6878 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6879 (match_operand:QI 2 "general_operand" "qi,qm"))
6880 (const_int 0)))
6881 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6882 (minus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 6883 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 6884 && ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 6885 "sub{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
6886 [(set_attr "type" "alu")
6887 (set_attr "mode" "QI")])
6888
6889(define_insn "*subqi_3"
42fabf21 6890 [(set (reg FLAGS_REG)
d90ffc8d
JH
6891 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6892 (match_operand:QI 2 "general_operand" "qi,qm")))
6893 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6894 (minus:HI (match_dup 1) (match_dup 2)))]
16189740
RH
6895 "ix86_match_ccmode (insn, CCmode)
6896 && ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 6897 "sub{b}\t{%2, %0|%0, %2}"
6ef67412
JH
6898 [(set_attr "type" "alu")
6899 (set_attr "mode" "QI")])
2ae0f82c 6900
886c62d1
JVA
6901;; The patterns that match these are at the end of this file.
6902
4fb21e90
JVA
6903(define_expand "subxf3"
6904 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
6905 (minus:XF (match_operand:XF 1 "register_operand" "")
6906 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
6907 "TARGET_80387"
6908 "")
6909
886c62d1
JVA
6910(define_expand "subdf3"
6911 [(set (match_operand:DF 0 "register_operand" "")
06a964de 6912 (minus:DF (match_operand:DF 1 "register_operand" "")
886c62d1 6913 (match_operand:DF 2 "nonimmediate_operand" "")))]
965f5423 6914 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
886c62d1
JVA
6915 "")
6916
6917(define_expand "subsf3"
6918 [(set (match_operand:SF 0 "register_operand" "")
06a964de 6919 (minus:SF (match_operand:SF 1 "register_operand" "")
886c62d1 6920 (match_operand:SF 2 "nonimmediate_operand" "")))]
965f5423 6921 "TARGET_80387 || TARGET_SSE_MATH"
886c62d1
JVA
6922 "")
6923\f
e075ae69 6924;; Multiply instructions
886c62d1 6925
9b70259d
JH
6926(define_expand "muldi3"
6927 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6928 (mult:DI (match_operand:DI 1 "register_operand" "")
6929 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 6930 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
6931 "TARGET_64BIT"
6932 "")
6933
6934(define_insn "*muldi3_1_rex64"
6935 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
f56e86bd 6936 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
9b70259d 6937 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
8bc527af 6938 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
6939 "TARGET_64BIT
6940 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9b70259d 6941 "@
0f40f9f7
ZW
6942 imul{q}\t{%2, %1, %0|%0, %1, %2}
6943 imul{q}\t{%2, %1, %0|%0, %1, %2}
6944 imul{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6945 [(set_attr "type" "imul")
6946 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
6947 (set (attr "athlon_decode")
6948 (cond [(eq_attr "cpu" "athlon")
6949 (const_string "vector")
6950 (eq_attr "alternative" "1")
6951 (const_string "vector")
6952 (and (eq_attr "alternative" "2")
6953 (match_operand 1 "memory_operand" ""))
6954 (const_string "vector")]
6955 (const_string "direct")))
9b70259d
JH
6956 (set_attr "mode" "DI")])
6957
d525dfdf
JH
6958(define_expand "mulsi3"
6959 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6960 (mult:SI (match_operand:SI 1 "register_operand" "")
6961 (match_operand:SI 2 "general_operand" "")))
8bc527af 6962 (clobber (reg:CC FLAGS_REG))])]
d525dfdf
JH
6963 ""
6964 "")
6965
6966(define_insn "*mulsi3_1"
e075ae69 6967 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
f56e86bd 6968 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
e075ae69 6969 (match_operand:SI 2 "general_operand" "K,i,mr")))
8bc527af 6970 (clobber (reg:CC FLAGS_REG))]
d525dfdf 6971 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
e075ae69 6972 "@
0f40f9f7
ZW
6973 imul{l}\t{%2, %1, %0|%0, %1, %2}
6974 imul{l}\t{%2, %1, %0|%0, %1, %2}
6975 imul{l}\t{%2, %0|%0, %2}"
e075ae69 6976 [(set_attr "type" "imul")
6ef67412 6977 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
6978 (set (attr "athlon_decode")
6979 (cond [(eq_attr "cpu" "athlon")
6980 (const_string "vector")
6981 (eq_attr "alternative" "1")
6982 (const_string "vector")
6983 (and (eq_attr "alternative" "2")
6984 (match_operand 1 "memory_operand" ""))
6985 (const_string "vector")]
6986 (const_string "direct")))
6ef67412 6987 (set_attr "mode" "SI")])
886c62d1 6988
9b70259d
JH
6989(define_insn "*mulsi3_1_zext"
6990 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6991 (zero_extend:DI
f56e86bd 6992 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9b70259d 6993 (match_operand:SI 2 "general_operand" "K,i,mr"))))
8bc527af 6994 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
6995 "TARGET_64BIT
6996 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9b70259d 6997 "@
0f40f9f7
ZW
6998 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6999 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7000 imul{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
7001 [(set_attr "type" "imul")
7002 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
7003 (set (attr "athlon_decode")
7004 (cond [(eq_attr "cpu" "athlon")
7005 (const_string "vector")
7006 (eq_attr "alternative" "1")
7007 (const_string "vector")
7008 (and (eq_attr "alternative" "2")
7009 (match_operand 1 "memory_operand" ""))
7010 (const_string "vector")]
7011 (const_string "direct")))
9b70259d
JH
7012 (set_attr "mode" "SI")])
7013
d525dfdf
JH
7014(define_expand "mulhi3"
7015 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7016 (mult:HI (match_operand:HI 1 "register_operand" "")
7017 (match_operand:HI 2 "general_operand" "")))
8bc527af 7018 (clobber (reg:CC FLAGS_REG))])]
d9f32422 7019 "TARGET_HIMODE_MATH"
d525dfdf
JH
7020 "")
7021
7022(define_insn "*mulhi3_1"
6ef67412 7023 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
f56e86bd 7024 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6ef67412 7025 (match_operand:HI 2 "general_operand" "K,i,mr")))
8bc527af 7026 (clobber (reg:CC FLAGS_REG))]
d525dfdf 7027 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
e075ae69 7028 "@
0f40f9f7
ZW
7029 imul{w}\t{%2, %1, %0|%0, %1, %2}
7030 imul{w}\t{%2, %1, %0|%0, %1, %2}
7031 imul{w}\t{%2, %0|%0, %2}"
6ef67412
JH
7032 [(set_attr "type" "imul")
7033 (set_attr "prefix_0f" "0,0,1")
f56e86bd
JH
7034 (set (attr "athlon_decode")
7035 (cond [(eq_attr "cpu" "athlon")
7036 (const_string "vector")
7037 (eq_attr "alternative" "1,2")
7038 (const_string "vector")]
7039 (const_string "direct")))
6ef67412 7040 (set_attr "mode" "HI")])
886c62d1 7041
558740bf
JH
7042(define_expand "mulqi3"
7043 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7044 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7045 (match_operand:QI 2 "register_operand" "")))
8bc527af 7046 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7047 "TARGET_QIMODE_MATH"
7048 "")
7049
7050(define_insn "*mulqi3_1"
765a46f9 7051 [(set (match_operand:QI 0 "register_operand" "=a")
558740bf 7052 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
765a46f9 7053 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8bc527af 7054 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7055 "TARGET_QIMODE_MATH
7056 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7057 "mul{b}\t%2"
6ef67412
JH
7058 [(set_attr "type" "imul")
7059 (set_attr "length_immediate" "0")
f56e86bd
JH
7060 (set (attr "athlon_decode")
7061 (if_then_else (eq_attr "cpu" "athlon")
7062 (const_string "vector")
7063 (const_string "direct")))
6ef67412 7064 (set_attr "mode" "QI")])
765a46f9 7065
558740bf
JH
7066(define_expand "umulqihi3"
7067 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7068 (mult:HI (zero_extend:HI
7069 (match_operand:QI 1 "nonimmediate_operand" ""))
7070 (zero_extend:HI
7071 (match_operand:QI 2 "register_operand" ""))))
8bc527af 7072 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7073 "TARGET_QIMODE_MATH"
7074 "")
7075
7076(define_insn "*umulqihi3_1"
2ae0f82c 7077 [(set (match_operand:HI 0 "register_operand" "=a")
558740bf 7078 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
e075ae69 7079 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8bc527af 7080 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7081 "TARGET_QIMODE_MATH
7082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7083 "mul{b}\t%2"
6ef67412
JH
7084 [(set_attr "type" "imul")
7085 (set_attr "length_immediate" "0")
f56e86bd
JH
7086 (set (attr "athlon_decode")
7087 (if_then_else (eq_attr "cpu" "athlon")
7088 (const_string "vector")
7089 (const_string "direct")))
6ef67412 7090 (set_attr "mode" "QI")])
886c62d1 7091
558740bf
JH
7092(define_expand "mulqihi3"
7093 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7094 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7095 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8bc527af 7096 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7097 "TARGET_QIMODE_MATH"
7098 "")
7099
7100(define_insn "*mulqihi3_insn"
2ae0f82c 7101 [(set (match_operand:HI 0 "register_operand" "=a")
558740bf 7102 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
e075ae69 7103 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8bc527af 7104 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7105 "TARGET_QIMODE_MATH
7106 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7107 "imul{b}\t%2"
6ef67412
JH
7108 [(set_attr "type" "imul")
7109 (set_attr "length_immediate" "0")
f56e86bd
JH
7110 (set (attr "athlon_decode")
7111 (if_then_else (eq_attr "cpu" "athlon")
7112 (const_string "vector")
7113 (const_string "direct")))
6ef67412 7114 (set_attr "mode" "QI")])
4b71cd6e 7115
558740bf
JH
7116(define_expand "umulditi3"
7117 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7118 (mult:TI (zero_extend:TI
7119 (match_operand:DI 1 "nonimmediate_operand" ""))
7120 (zero_extend:TI
7121 (match_operand:DI 2 "register_operand" ""))))
8bc527af 7122 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7123 "TARGET_64BIT"
7124 "")
7125
7126(define_insn "*umulditi3_insn"
9b70259d 7127 [(set (match_operand:TI 0 "register_operand" "=A")
558740bf 7128 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
9b70259d 7129 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8bc527af 7130 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7131 "TARGET_64BIT
7132 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7133 "mul{q}\t%2"
1e07edd3 7134 [(set_attr "type" "imul")
1e07edd3 7135 (set_attr "length_immediate" "0")
f56e86bd
JH
7136 (set (attr "athlon_decode")
7137 (if_then_else (eq_attr "cpu" "athlon")
7138 (const_string "vector")
7139 (const_string "double")))
9b70259d 7140 (set_attr "mode" "DI")])
1e07edd3
JH
7141
7142;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
558740bf
JH
7143(define_expand "umulsidi3"
7144 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7145 (mult:DI (zero_extend:DI
7146 (match_operand:SI 1 "nonimmediate_operand" ""))
7147 (zero_extend:DI
7148 (match_operand:SI 2 "register_operand" ""))))
8bc527af 7149 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7150 "!TARGET_64BIT"
7151 "")
7152
7153(define_insn "*umulsidi3_insn"
4b71cd6e 7154 [(set (match_operand:DI 0 "register_operand" "=A")
558740bf 7155 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
e075ae69 7156 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8bc527af 7157 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7158 "!TARGET_64BIT
7159 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7160 "mul{l}\t%2"
e075ae69 7161 [(set_attr "type" "imul")
6ef67412 7162 (set_attr "length_immediate" "0")
f56e86bd
JH
7163 (set (attr "athlon_decode")
7164 (if_then_else (eq_attr "cpu" "athlon")
7165 (const_string "vector")
7166 (const_string "double")))
6ef67412 7167 (set_attr "mode" "SI")])
4b71cd6e 7168
558740bf
JH
7169(define_expand "mulditi3"
7170 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7171 (mult:TI (sign_extend:TI
7172 (match_operand:DI 1 "nonimmediate_operand" ""))
7173 (sign_extend:TI
7174 (match_operand:DI 2 "register_operand" ""))))
8bc527af 7175 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7176 "TARGET_64BIT"
7177 "")
7178
7179(define_insn "*mulditi3_insn"
9b70259d 7180 [(set (match_operand:TI 0 "register_operand" "=A")
558740bf 7181 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
9b70259d 7182 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8bc527af 7183 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7184 "TARGET_64BIT
7185 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7186 "imul{q}\t%2"
9b70259d
JH
7187 [(set_attr "type" "imul")
7188 (set_attr "length_immediate" "0")
f56e86bd
JH
7189 (set (attr "athlon_decode")
7190 (if_then_else (eq_attr "cpu" "athlon")
7191 (const_string "vector")
7192 (const_string "double")))
9b70259d
JH
7193 (set_attr "mode" "DI")])
7194
558740bf
JH
7195(define_expand "mulsidi3"
7196 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7197 (mult:DI (sign_extend:DI
7198 (match_operand:SI 1 "nonimmediate_operand" ""))
7199 (sign_extend:DI
7200 (match_operand:SI 2 "register_operand" ""))))
8bc527af 7201 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7202 "!TARGET_64BIT"
7203 "")
7204
7205(define_insn "*mulsidi3_insn"
4b71cd6e 7206 [(set (match_operand:DI 0 "register_operand" "=A")
558740bf 7207 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
e075ae69 7208 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8bc527af 7209 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7210 "!TARGET_64BIT
7211 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7212 "imul{l}\t%2"
6ef67412
JH
7213 [(set_attr "type" "imul")
7214 (set_attr "length_immediate" "0")
f56e86bd
JH
7215 (set (attr "athlon_decode")
7216 (if_then_else (eq_attr "cpu" "athlon")
7217 (const_string "vector")
7218 (const_string "double")))
6ef67412 7219 (set_attr "mode" "SI")])
2f2a49e8 7220
558740bf
JH
7221(define_expand "umuldi3_highpart"
7222 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7223 (truncate:DI
7224 (lshiftrt:TI
7225 (mult:TI (zero_extend:TI
7226 (match_operand:DI 1 "nonimmediate_operand" ""))
7227 (zero_extend:TI
7228 (match_operand:DI 2 "register_operand" "")))
7229 (const_int 64))))
7230 (clobber (match_scratch:DI 3 ""))
8bc527af 7231 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7232 "TARGET_64BIT"
7233 "")
7234
9b70259d
JH
7235(define_insn "*umuldi3_highpart_rex64"
7236 [(set (match_operand:DI 0 "register_operand" "=d")
7237 (truncate:DI
7238 (lshiftrt:TI
7239 (mult:TI (zero_extend:TI
558740bf 7240 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9b70259d
JH
7241 (zero_extend:TI
7242 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7243 (const_int 64))))
558740bf 7244 (clobber (match_scratch:DI 3 "=1"))
8bc527af 7245 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7246 "TARGET_64BIT
7247 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7248 "mul{q}\t%2"
9b70259d 7249 [(set_attr "type" "imul")
9b70259d 7250 (set_attr "length_immediate" "0")
f56e86bd
JH
7251 (set (attr "athlon_decode")
7252 (if_then_else (eq_attr "cpu" "athlon")
7253 (const_string "vector")
7254 (const_string "double")))
9b70259d
JH
7255 (set_attr "mode" "DI")])
7256
558740bf
JH
7257(define_expand "umulsi3_highpart"
7258 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7259 (truncate:SI
7260 (lshiftrt:DI
7261 (mult:DI (zero_extend:DI
7262 (match_operand:SI 1 "nonimmediate_operand" ""))
7263 (zero_extend:DI
7264 (match_operand:SI 2 "register_operand" "")))
7265 (const_int 32))))
7266 (clobber (match_scratch:SI 3 ""))
8bc527af 7267 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7268 ""
7269 "")
7270
7271(define_insn "*umulsi3_highpart_insn"
2f2a49e8 7272 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
7273 (truncate:SI
7274 (lshiftrt:DI
7275 (mult:DI (zero_extend:DI
558740bf 7276 (match_operand:SI 1 "nonimmediate_operand" "%a"))
e075ae69
RH
7277 (zero_extend:DI
7278 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7279 (const_int 32))))
558740bf 7280 (clobber (match_scratch:SI 3 "=1"))
8bc527af 7281 (clobber (reg:CC FLAGS_REG))]
558740bf 7282 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
0f40f9f7 7283 "mul{l}\t%2"
32ee7d1d 7284 [(set_attr "type" "imul")
32ee7d1d 7285 (set_attr "length_immediate" "0")
f56e86bd
JH
7286 (set (attr "athlon_decode")
7287 (if_then_else (eq_attr "cpu" "athlon")
7288 (const_string "vector")
7289 (const_string "double")))
32ee7d1d
JH
7290 (set_attr "mode" "SI")])
7291
7292(define_insn "*umulsi3_highpart_zext"
7293 [(set (match_operand:DI 0 "register_operand" "=d")
7294 (zero_extend:DI (truncate:SI
7295 (lshiftrt:DI
7296 (mult:DI (zero_extend:DI
558740bf 7297 (match_operand:SI 1 "nonimmediate_operand" "%a"))
32ee7d1d
JH
7298 (zero_extend:DI
7299 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7300 (const_int 32)))))
558740bf 7301 (clobber (match_scratch:SI 3 "=1"))
8bc527af 7302 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7303 "TARGET_64BIT
7304 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7305 "mul{l}\t%2"
e075ae69 7306 [(set_attr "type" "imul")
6ef67412 7307 (set_attr "length_immediate" "0")
f56e86bd
JH
7308 (set (attr "athlon_decode")
7309 (if_then_else (eq_attr "cpu" "athlon")
7310 (const_string "vector")
7311 (const_string "double")))
6ef67412 7312 (set_attr "mode" "SI")])
2f2a49e8 7313
558740bf
JH
7314(define_expand "smuldi3_highpart"
7315 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7316 (truncate:DI
7317 (lshiftrt:TI
7318 (mult:TI (sign_extend:TI
7319 (match_operand:DI 1 "nonimmediate_operand" ""))
7320 (sign_extend:TI
7321 (match_operand:DI 2 "register_operand" "")))
7322 (const_int 64))))
7323 (clobber (match_scratch:DI 3 ""))
8bc527af 7324 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7325 "TARGET_64BIT"
7326 "")
7327
9b70259d
JH
7328(define_insn "*smuldi3_highpart_rex64"
7329 [(set (match_operand:DI 0 "register_operand" "=d")
7330 (truncate:DI
7331 (lshiftrt:TI
7332 (mult:TI (sign_extend:TI
558740bf 7333 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9b70259d
JH
7334 (sign_extend:TI
7335 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7336 (const_int 64))))
558740bf 7337 (clobber (match_scratch:DI 3 "=1"))
8bc527af 7338 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7339 "TARGET_64BIT
7340 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7341 "imul{q}\t%2"
9b70259d 7342 [(set_attr "type" "imul")
f56e86bd
JH
7343 (set (attr "athlon_decode")
7344 (if_then_else (eq_attr "cpu" "athlon")
7345 (const_string "vector")
7346 (const_string "double")))
9b70259d
JH
7347 (set_attr "mode" "DI")])
7348
558740bf
JH
7349(define_expand "smulsi3_highpart"
7350 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7351 (truncate:SI
7352 (lshiftrt:DI
7353 (mult:DI (sign_extend:DI
7354 (match_operand:SI 1 "nonimmediate_operand" ""))
7355 (sign_extend:DI
7356 (match_operand:SI 2 "register_operand" "")))
7357 (const_int 32))))
7358 (clobber (match_scratch:SI 3 ""))
8bc527af 7359 (clobber (reg:CC FLAGS_REG))])]
558740bf
JH
7360 ""
7361 "")
7362
7363(define_insn "*smulsi3_highpart_insn"
2f2a49e8 7364 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
7365 (truncate:SI
7366 (lshiftrt:DI
7367 (mult:DI (sign_extend:DI
558740bf 7368 (match_operand:SI 1 "nonimmediate_operand" "%a"))
e075ae69
RH
7369 (sign_extend:DI
7370 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7371 (const_int 32))))
558740bf 7372 (clobber (match_scratch:SI 3 "=1"))
8bc527af 7373 (clobber (reg:CC FLAGS_REG))]
558740bf 7374 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
0f40f9f7 7375 "imul{l}\t%2"
e075ae69 7376 [(set_attr "type" "imul")
f56e86bd
JH
7377 (set (attr "athlon_decode")
7378 (if_then_else (eq_attr "cpu" "athlon")
7379 (const_string "vector")
7380 (const_string "double")))
6ef67412 7381 (set_attr "mode" "SI")])
4b71cd6e 7382
9b70259d
JH
7383(define_insn "*smulsi3_highpart_zext"
7384 [(set (match_operand:DI 0 "register_operand" "=d")
7385 (zero_extend:DI (truncate:SI
7386 (lshiftrt:DI
7387 (mult:DI (sign_extend:DI
558740bf 7388 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9b70259d
JH
7389 (sign_extend:DI
7390 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7391 (const_int 32)))))
558740bf 7392 (clobber (match_scratch:SI 3 "=1"))
8bc527af 7393 (clobber (reg:CC FLAGS_REG))]
558740bf
JH
7394 "TARGET_64BIT
7395 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 7396 "imul{l}\t%2"
9b70259d 7397 [(set_attr "type" "imul")
f56e86bd
JH
7398 (set (attr "athlon_decode")
7399 (if_then_else (eq_attr "cpu" "athlon")
7400 (const_string "vector")
7401 (const_string "double")))
9b70259d
JH
7402 (set_attr "mode" "SI")])
7403
886c62d1
JVA
7404;; The patterns that match these are at the end of this file.
7405
4fb21e90
JVA
7406(define_expand "mulxf3"
7407 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
7408 (mult:XF (match_operand:XF 1 "register_operand" "")
7409 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
7410 "TARGET_80387"
7411 "")
7412
886c62d1
JVA
7413(define_expand "muldf3"
7414 [(set (match_operand:DF 0 "register_operand" "")
2ae0f82c 7415 (mult:DF (match_operand:DF 1 "register_operand" "")
886c62d1 7416 (match_operand:DF 2 "nonimmediate_operand" "")))]
965f5423 7417 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
886c62d1
JVA
7418 "")
7419
7420(define_expand "mulsf3"
7421 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 7422 (mult:SF (match_operand:SF 1 "register_operand" "")
886c62d1 7423 (match_operand:SF 2 "nonimmediate_operand" "")))]
965f5423 7424 "TARGET_80387 || TARGET_SSE_MATH"
886c62d1
JVA
7425 "")
7426\f
e075ae69 7427;; Divide instructions
886c62d1
JVA
7428
7429(define_insn "divqi3"
2ae0f82c
SC
7430 [(set (match_operand:QI 0 "register_operand" "=a")
7431 (div:QI (match_operand:HI 1 "register_operand" "0")
e075ae69 7432 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8bc527af 7433 (clobber (reg:CC FLAGS_REG))]
d9f32422 7434 "TARGET_QIMODE_MATH"
0f40f9f7 7435 "idiv{b}\t%2"
e075ae69 7436 [(set_attr "type" "idiv")
56bab446 7437 (set_attr "mode" "QI")])
886c62d1
JVA
7438
7439(define_insn "udivqi3"
2ae0f82c
SC
7440 [(set (match_operand:QI 0 "register_operand" "=a")
7441 (udiv:QI (match_operand:HI 1 "register_operand" "0")
e075ae69 7442 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8bc527af 7443 (clobber (reg:CC FLAGS_REG))]
d9f32422 7444 "TARGET_QIMODE_MATH"
0f40f9f7 7445 "div{b}\t%2"
e075ae69 7446 [(set_attr "type" "idiv")
56bab446 7447 (set_attr "mode" "QI")])
886c62d1
JVA
7448
7449;; The patterns that match these are at the end of this file.
7450
4fb21e90
JVA
7451(define_expand "divxf3"
7452 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
7453 (div:XF (match_operand:XF 1 "register_operand" "")
7454 (match_operand:XF 2 "register_operand" "")))]
2b589241
JH
7455 "TARGET_80387"
7456 "")
7457
a78cb986
SC
7458(define_expand "divdf3"
7459 [(set (match_operand:DF 0 "register_operand" "")
7460 (div:DF (match_operand:DF 1 "register_operand" "")
7461 (match_operand:DF 2 "nonimmediate_operand" "")))]
965f5423 7462 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
a78cb986
SC
7463 "")
7464
886c62d1
JVA
7465(define_expand "divsf3"
7466 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 7467 (div:SF (match_operand:SF 1 "register_operand" "")
886c62d1 7468 (match_operand:SF 2 "nonimmediate_operand" "")))]
965f5423 7469 "TARGET_80387 || TARGET_SSE_MATH"
886c62d1
JVA
7470 "")
7471\f
7472;; Remainder instructions.
9b70259d
JH
7473
7474(define_expand "divmoddi4"
7475 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7476 (div:DI (match_operand:DI 1 "register_operand" "")
7477 (match_operand:DI 2 "nonimmediate_operand" "")))
7478 (set (match_operand:DI 3 "register_operand" "")
7479 (mod:DI (match_dup 1) (match_dup 2)))
8bc527af 7480 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
7481 "TARGET_64BIT"
7482 "")
7483
7484;; Allow to come the parameter in eax or edx to avoid extra moves.
d1f87653 7485;; Penalize eax case slightly because it results in worse scheduling
9b70259d
JH
7486;; of code.
7487(define_insn "*divmoddi4_nocltd_rex64"
7488 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7489 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7490 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7491 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7492 (mod:DI (match_dup 2) (match_dup 3)))
8bc527af 7493 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
7494 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7495 "#"
7496 [(set_attr "type" "multi")])
7497
7498(define_insn "*divmoddi4_cltd_rex64"
7499 [(set (match_operand:DI 0 "register_operand" "=a")
7500 (div:DI (match_operand:DI 2 "register_operand" "a")
7501 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7502 (set (match_operand:DI 1 "register_operand" "=&d")
7503 (mod:DI (match_dup 2) (match_dup 3)))
8bc527af 7504 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
7505 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7506 "#"
7507 [(set_attr "type" "multi")])
7508
7509(define_insn "*divmoddi_noext_rex64"
7510 [(set (match_operand:DI 0 "register_operand" "=a")
7511 (div:DI (match_operand:DI 1 "register_operand" "0")
7512 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7513 (set (match_operand:DI 3 "register_operand" "=d")
7514 (mod:DI (match_dup 1) (match_dup 2)))
7515 (use (match_operand:DI 4 "register_operand" "3"))
8bc527af 7516 (clobber (reg:CC FLAGS_REG))]
9b70259d 7517 "TARGET_64BIT"
0f40f9f7 7518 "idiv{q}\t%2"
9b70259d 7519 [(set_attr "type" "idiv")
56bab446 7520 (set_attr "mode" "DI")])
9b70259d
JH
7521
7522(define_split
7523 [(set (match_operand:DI 0 "register_operand" "")
7524 (div:DI (match_operand:DI 1 "register_operand" "")
7525 (match_operand:DI 2 "nonimmediate_operand" "")))
7526 (set (match_operand:DI 3 "register_operand" "")
7527 (mod:DI (match_dup 1) (match_dup 2)))
8bc527af 7528 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
7529 "TARGET_64BIT && reload_completed"
7530 [(parallel [(set (match_dup 3)
7531 (ashiftrt:DI (match_dup 4) (const_int 63)))
8bc527af 7532 (clobber (reg:CC FLAGS_REG))])
9b70259d
JH
7533 (parallel [(set (match_dup 0)
7534 (div:DI (reg:DI 0) (match_dup 2)))
7535 (set (match_dup 3)
7536 (mod:DI (reg:DI 0) (match_dup 2)))
7537 (use (match_dup 3))
8bc527af 7538 (clobber (reg:CC FLAGS_REG))])]
9b70259d 7539{
9cd10576 7540 /* Avoid use of cltd in favor of a mov+shift. */
9b70259d
JH
7541 if (!TARGET_USE_CLTD && !optimize_size)
7542 {
7543 if (true_regnum (operands[1]))
7544 emit_move_insn (operands[0], operands[1]);
7545 else
7546 emit_move_insn (operands[3], operands[1]);
7547 operands[4] = operands[3];
7548 }
7549 else
7550 {
7551 if (true_regnum (operands[1]))
7552 abort();
7553 operands[4] = operands[1];
7554 }
0f40f9f7 7555})
9b70259d
JH
7556
7557
40745eec
JH
7558(define_expand "divmodsi4"
7559 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7560 (div:SI (match_operand:SI 1 "register_operand" "")
7561 (match_operand:SI 2 "nonimmediate_operand" "")))
7562 (set (match_operand:SI 3 "register_operand" "")
7563 (mod:SI (match_dup 1) (match_dup 2)))
8bc527af 7564 (clobber (reg:CC FLAGS_REG))])]
40745eec
JH
7565 ""
7566 "")
7567
7568;; Allow to come the parameter in eax or edx to avoid extra moves.
d1f87653 7569;; Penalize eax case slightly because it results in worse scheduling
40745eec
JH
7570;; of code.
7571(define_insn "*divmodsi4_nocltd"
7572 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7573 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7574 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7575 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7576 (mod:SI (match_dup 2) (match_dup 3)))
8bc527af 7577 (clobber (reg:CC FLAGS_REG))]
40745eec
JH
7578 "!optimize_size && !TARGET_USE_CLTD"
7579 "#"
7580 [(set_attr "type" "multi")])
886c62d1 7581
40745eec 7582(define_insn "*divmodsi4_cltd"
2bb7a0f5 7583 [(set (match_operand:SI 0 "register_operand" "=a")
40745eec
JH
7584 (div:SI (match_operand:SI 2 "register_operand" "a")
7585 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7586 (set (match_operand:SI 1 "register_operand" "=&d")
7587 (mod:SI (match_dup 2) (match_dup 3)))
8bc527af 7588 (clobber (reg:CC FLAGS_REG))]
40745eec
JH
7589 "optimize_size || TARGET_USE_CLTD"
7590 "#"
e075ae69
RH
7591 [(set_attr "type" "multi")])
7592
6343a50e 7593(define_insn "*divmodsi_noext"
e075ae69 7594 [(set (match_operand:SI 0 "register_operand" "=a")
40745eec 7595 (div:SI (match_operand:SI 1 "register_operand" "0")
e075ae69
RH
7596 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7597 (set (match_operand:SI 3 "register_operand" "=d")
7598 (mod:SI (match_dup 1) (match_dup 2)))
40745eec 7599 (use (match_operand:SI 4 "register_operand" "3"))
8bc527af 7600 (clobber (reg:CC FLAGS_REG))]
e075ae69 7601 ""
0f40f9f7 7602 "idiv{l}\t%2"
e075ae69 7603 [(set_attr "type" "idiv")
56bab446 7604 (set_attr "mode" "SI")])
e075ae69
RH
7605
7606(define_split
7607 [(set (match_operand:SI 0 "register_operand" "")
7608 (div:SI (match_operand:SI 1 "register_operand" "")
7609 (match_operand:SI 2 "nonimmediate_operand" "")))
7610 (set (match_operand:SI 3 "register_operand" "")
7611 (mod:SI (match_dup 1) (match_dup 2)))
8bc527af 7612 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
7613 "reload_completed"
7614 [(parallel [(set (match_dup 3)
7615 (ashiftrt:SI (match_dup 4) (const_int 31)))
8bc527af 7616 (clobber (reg:CC FLAGS_REG))])
e075ae69 7617 (parallel [(set (match_dup 0)
40745eec 7618 (div:SI (reg:SI 0) (match_dup 2)))
e075ae69 7619 (set (match_dup 3)
40745eec 7620 (mod:SI (reg:SI 0) (match_dup 2)))
e075ae69 7621 (use (match_dup 3))
8bc527af 7622 (clobber (reg:CC FLAGS_REG))])]
886c62d1 7623{
9cd10576 7624 /* Avoid use of cltd in favor of a mov+shift. */
40745eec 7625 if (!TARGET_USE_CLTD && !optimize_size)
e075ae69 7626 {
40745eec
JH
7627 if (true_regnum (operands[1]))
7628 emit_move_insn (operands[0], operands[1]);
7629 else
7630 emit_move_insn (operands[3], operands[1]);
e075ae69
RH
7631 operands[4] = operands[3];
7632 }
7633 else
40745eec
JH
7634 {
7635 if (true_regnum (operands[1]))
7636 abort();
7637 operands[4] = operands[1];
7638 }
0f40f9f7 7639})
e075ae69 7640;; %%% Split me.
886c62d1 7641(define_insn "divmodhi4"
2bb7a0f5
RS
7642 [(set (match_operand:HI 0 "register_operand" "=a")
7643 (div:HI (match_operand:HI 1 "register_operand" "0")
2ae0f82c 7644 (match_operand:HI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 7645 (set (match_operand:HI 3 "register_operand" "=&d")
e075ae69 7646 (mod:HI (match_dup 1) (match_dup 2)))
8bc527af 7647 (clobber (reg:CC FLAGS_REG))]
d9f32422 7648 "TARGET_HIMODE_MATH"
0f40f9f7 7649 "cwtd\;idiv{w}\t%2"
6ef67412
JH
7650 [(set_attr "type" "multi")
7651 (set_attr "length_immediate" "0")
7652 (set_attr "mode" "SI")])
886c62d1 7653
9b70259d
JH
7654(define_insn "udivmoddi4"
7655 [(set (match_operand:DI 0 "register_operand" "=a")
7656 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7657 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7658 (set (match_operand:DI 3 "register_operand" "=&d")
7659 (umod:DI (match_dup 1) (match_dup 2)))
8bc527af 7660 (clobber (reg:CC FLAGS_REG))]
9b70259d 7661 "TARGET_64BIT"
0f40f9f7 7662 "xor{q}\t%3, %3\;div{q}\t%2"
9b70259d
JH
7663 [(set_attr "type" "multi")
7664 (set_attr "length_immediate" "0")
7665 (set_attr "mode" "DI")])
7666
7667(define_insn "*udivmoddi4_noext"
7668 [(set (match_operand:DI 0 "register_operand" "=a")
7669 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7670 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7671 (set (match_operand:DI 3 "register_operand" "=d")
7672 (umod:DI (match_dup 1) (match_dup 2)))
7673 (use (match_dup 3))
8bc527af 7674 (clobber (reg:CC FLAGS_REG))]
9b70259d 7675 "TARGET_64BIT"
0f40f9f7 7676 "div{q}\t%2"
9b70259d 7677 [(set_attr "type" "idiv")
9b70259d
JH
7678 (set_attr "mode" "DI")])
7679
7680(define_split
7681 [(set (match_operand:DI 0 "register_operand" "")
7682 (udiv:DI (match_operand:DI 1 "register_operand" "")
7683 (match_operand:DI 2 "nonimmediate_operand" "")))
7684 (set (match_operand:DI 3 "register_operand" "")
7685 (umod:DI (match_dup 1) (match_dup 2)))
8bc527af 7686 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 7687 "TARGET_64BIT && reload_completed"
9b70259d
JH
7688 [(set (match_dup 3) (const_int 0))
7689 (parallel [(set (match_dup 0)
7690 (udiv:DI (match_dup 1) (match_dup 2)))
7691 (set (match_dup 3)
7692 (umod:DI (match_dup 1) (match_dup 2)))
7693 (use (match_dup 3))
8bc527af 7694 (clobber (reg:CC FLAGS_REG))])]
9b70259d
JH
7695 "")
7696
886c62d1 7697(define_insn "udivmodsi4"
2bb7a0f5
RS
7698 [(set (match_operand:SI 0 "register_operand" "=a")
7699 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 7700 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 7701 (set (match_operand:SI 3 "register_operand" "=&d")
e075ae69 7702 (umod:SI (match_dup 1) (match_dup 2)))
8bc527af 7703 (clobber (reg:CC FLAGS_REG))]
886c62d1 7704 ""
0f40f9f7 7705 "xor{l}\t%3, %3\;div{l}\t%2"
6ef67412
JH
7706 [(set_attr "type" "multi")
7707 (set_attr "length_immediate" "0")
7708 (set_attr "mode" "SI")])
886c62d1 7709
6343a50e 7710(define_insn "*udivmodsi4_noext"
2bb7a0f5 7711 [(set (match_operand:SI 0 "register_operand" "=a")
e075ae69 7712 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 7713 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 7714 (set (match_operand:SI 3 "register_operand" "=d")
e075ae69
RH
7715 (umod:SI (match_dup 1) (match_dup 2)))
7716 (use (match_dup 3))
8bc527af 7717 (clobber (reg:CC FLAGS_REG))]
886c62d1 7718 ""
0f40f9f7 7719 "div{l}\t%2"
e075ae69 7720 [(set_attr "type" "idiv")
6ef67412 7721 (set_attr "mode" "SI")])
886c62d1 7722
e075ae69
RH
7723(define_split
7724 [(set (match_operand:SI 0 "register_operand" "")
7725 (udiv:SI (match_operand:SI 1 "register_operand" "")
7726 (match_operand:SI 2 "nonimmediate_operand" "")))
7727 (set (match_operand:SI 3 "register_operand" "")
7728 (umod:SI (match_dup 1) (match_dup 2)))
8bc527af 7729 (clobber (reg:CC FLAGS_REG))]
e075ae69 7730 "reload_completed"
591702de 7731 [(set (match_dup 3) (const_int 0))
e075ae69
RH
7732 (parallel [(set (match_dup 0)
7733 (udiv:SI (match_dup 1) (match_dup 2)))
7734 (set (match_dup 3)
7735 (umod:SI (match_dup 1) (match_dup 2)))
7736 (use (match_dup 3))
8bc527af 7737 (clobber (reg:CC FLAGS_REG))])]
e075ae69 7738 "")
886c62d1 7739
e075ae69 7740(define_expand "udivmodhi4"
591702de 7741 [(set (match_dup 4) (const_int 0))
40745eec
JH
7742 (parallel [(set (match_operand:HI 0 "register_operand" "")
7743 (udiv:HI (match_operand:HI 1 "register_operand" "")
7744 (match_operand:HI 2 "nonimmediate_operand" "")))
7745 (set (match_operand:HI 3 "register_operand" "")
e075ae69
RH
7746 (umod:HI (match_dup 1) (match_dup 2)))
7747 (use (match_dup 4))
8bc527af 7748 (clobber (reg:CC FLAGS_REG))])]
d9f32422 7749 "TARGET_HIMODE_MATH"
e075ae69 7750 "operands[4] = gen_reg_rtx (HImode);")
886c62d1 7751
6343a50e 7752(define_insn "*udivmodhi_noext"
e075ae69
RH
7753 [(set (match_operand:HI 0 "register_operand" "=a")
7754 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7755 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7756 (set (match_operand:HI 3 "register_operand" "=d")
7757 (umod:HI (match_dup 1) (match_dup 2)))
7758 (use (match_operand:HI 4 "register_operand" "3"))
8bc527af 7759 (clobber (reg:CC FLAGS_REG))]
e075ae69 7760 ""
0f40f9f7 7761 "div{w}\t%2"
e075ae69 7762 [(set_attr "type" "idiv")
56bab446 7763 (set_attr "mode" "HI")])
e075ae69 7764
1e5f1716 7765;; We cannot use div/idiv for double division, because it causes
e075ae69
RH
7766;; "division by zero" on the overflow and that's not what we expect
7767;; from truncate. Because true (non truncating) double division is
7768;; never generated, we can't create this insn anyway.
7769;
7770;(define_insn ""
7771; [(set (match_operand:SI 0 "register_operand" "=a")
7772; (truncate:SI
7773; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7774; (zero_extend:DI
7775; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7776; (set (match_operand:SI 3 "register_operand" "=d")
7777; (truncate:SI
7778; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8bc527af 7779; (clobber (reg:CC FLAGS_REG))]
e075ae69 7780; ""
0f40f9f7 7781; "div{l}\t{%2, %0|%0, %2}"
56bab446 7782; [(set_attr "type" "idiv")])
886c62d1 7783\f
e075ae69
RH
7784;;- Logical AND instructions
7785
7786;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7787;; Note that this excludes ah.
7788
9b70259d 7789(define_insn "*testdi_1_rex64"
42fabf21 7790 [(set (reg FLAGS_REG)
9b70259d 7791 (compare
2bac97f7 7792 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
e1fea6ee 7793 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
9b70259d 7794 (const_int 0)))]
e1fea6ee
JH
7795 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7796 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9b70259d 7797 "@
5a0855a0
JJ
7798 test{l}\t{%k1, %k0|%k0, %k1}
7799 test{l}\t{%k1, %k0|%k0, %k1}
7800 test{q}\t{%1, %0|%0, %1}
7801 test{q}\t{%1, %0|%0, %1}
0f40f9f7 7802 test{q}\t{%1, %0|%0, %1}"
9b70259d
JH
7803 [(set_attr "type" "test")
7804 (set_attr "modrm" "0,1,0,1,1")
7805 (set_attr "mode" "SI,SI,DI,DI,DI")
7806 (set_attr "pent_pair" "uv,np,uv,np,uv")])
9076b9c1
JH
7807
7808(define_insn "testsi_1"
42fabf21 7809 [(set (reg FLAGS_REG)
9076b9c1 7810 (compare
2bac97f7 7811 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
e1fea6ee 7812 (match_operand:SI 1 "general_operand" "in,in,rin"))
16189740 7813 (const_int 0)))]
e1fea6ee
JH
7814 "ix86_match_ccmode (insn, CCNOmode)
7815 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 7816 "test{l}\t{%1, %0|%0, %1}"
6ef67412
JH
7817 [(set_attr "type" "test")
7818 (set_attr "modrm" "0,1,1")
7819 (set_attr "mode" "SI")
e075ae69
RH
7820 (set_attr "pent_pair" "uv,np,uv")])
7821
9076b9c1 7822(define_expand "testsi_ccno_1"
8bc527af 7823 [(set (reg:CCNO FLAGS_REG)
16189740 7824 (compare:CCNO
9076b9c1
JH
7825 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7826 (match_operand:SI 1 "nonmemory_operand" ""))
16189740 7827 (const_int 0)))]
a1cbdd7f 7828 ""
9076b9c1 7829 "")
16189740
RH
7830
7831(define_insn "*testhi_1"
42fabf21 7832 [(set (reg FLAGS_REG)
2bac97f7 7833 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
e1fea6ee 7834 (match_operand:HI 1 "general_operand" "n,n,rn"))
16189740 7835 (const_int 0)))]
e1fea6ee
JH
7836 "ix86_match_ccmode (insn, CCNOmode)
7837 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 7838 "test{w}\t{%1, %0|%0, %1}"
6ef67412
JH
7839 [(set_attr "type" "test")
7840 (set_attr "modrm" "0,1,1")
7841 (set_attr "mode" "HI")
e075ae69
RH
7842 (set_attr "pent_pair" "uv,np,uv")])
7843
9076b9c1 7844(define_expand "testqi_ccz_1"
8bc527af 7845 [(set (reg:CCZ FLAGS_REG)
9076b9c1
JH
7846 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7847 (match_operand:QI 1 "nonmemory_operand" ""))
7848 (const_int 0)))]
16189740 7849 ""
9076b9c1 7850 "")
16189740 7851
88d60956 7852(define_insn "*testqi_1_maybe_si"
93330ea1 7853 [(set (reg FLAGS_REG)
88d60956
RH
7854 (compare
7855 (and:QI
7856 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7857 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7858 (const_int 0)))]
7859 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7860 && ix86_match_ccmode (insn,
7861 GET_CODE (operands[1]) == CONST_INT
7862 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
adc88131
JJ
7863{
7864 if (which_alternative == 3)
7865 {
88d60956 7866 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
adc88131 7867 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
0f40f9f7 7868 return "test{l}\t{%1, %k0|%k0, %1}";
adc88131 7869 }
0f40f9f7
ZW
7870 return "test{b}\t{%1, %0|%0, %1}";
7871}
6ef67412
JH
7872 [(set_attr "type" "test")
7873 (set_attr "modrm" "0,1,1,1")
7874 (set_attr "mode" "QI,QI,QI,SI")
7875 (set_attr "pent_pair" "uv,np,uv,np")])
e075ae69 7876
88d60956
RH
7877(define_insn "*testqi_1"
7878 [(set (reg FLAGS_REG)
7879 (compare
7880 (and:QI
7881 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7882 (match_operand:QI 1 "general_operand" "n,n,qn"))
7883 (const_int 0)))]
7884 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7885 && ix86_match_ccmode (insn, CCNOmode)"
7886 "test{b}\t{%1, %0|%0, %1}"
7887 [(set_attr "type" "test")
7888 (set_attr "modrm" "0,1,1")
7889 (set_attr "mode" "QI")
7890 (set_attr "pent_pair" "uv,np,uv")])
7891
9076b9c1 7892(define_expand "testqi_ext_ccno_0"
8bc527af 7893 [(set (reg:CCNO FLAGS_REG)
9076b9c1 7894 (compare:CCNO
16189740
RH
7895 (and:SI
7896 (zero_extract:SI
9076b9c1 7897 (match_operand 0 "ext_register_operand" "")
16189740
RH
7898 (const_int 8)
7899 (const_int 8))
9076b9c1 7900 (match_operand 1 "const_int_operand" ""))
16189740 7901 (const_int 0)))]
9076b9c1
JH
7902 ""
7903 "")
e075ae69 7904
9076b9c1 7905(define_insn "*testqi_ext_0"
42fabf21 7906 [(set (reg FLAGS_REG)
9076b9c1 7907 (compare
e075ae69
RH
7908 (and:SI
7909 (zero_extract:SI
d2836273 7910 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
7911 (const_int 8)
7912 (const_int 8))
7913 (match_operand 1 "const_int_operand" "n"))
7914 (const_int 0)))]
2f41793e 7915 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7916 "test{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
7917 [(set_attr "type" "test")
7918 (set_attr "mode" "QI")
7919 (set_attr "length_immediate" "1")
e075ae69
RH
7920 (set_attr "pent_pair" "np")])
7921
7922(define_insn "*testqi_ext_1"
42fabf21 7923 [(set (reg FLAGS_REG)
16189740 7924 (compare
e075ae69
RH
7925 (and:SI
7926 (zero_extract:SI
d2836273 7927 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
7928 (const_int 8)
7929 (const_int 8))
7930 (zero_extend:SI
e1fea6ee 7931 (match_operand:QI 1 "general_operand" "Qm")))
e075ae69 7932 (const_int 0)))]
e1fea6ee
JH
7933 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7934 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 7935 "test{b}\t{%1, %h0|%h0, %1}"
d2836273
JH
7936 [(set_attr "type" "test")
7937 (set_attr "mode" "QI")])
7938
7939(define_insn "*testqi_ext_1_rex64"
42fabf21 7940 [(set (reg FLAGS_REG)
d2836273
JH
7941 (compare
7942 (and:SI
7943 (zero_extract:SI
7944 (match_operand 0 "ext_register_operand" "Q")
7945 (const_int 8)
7946 (const_int 8))
7947 (zero_extend:SI
3522082b 7948 (match_operand:QI 1 "register_operand" "Q")))
d2836273
JH
7949 (const_int 0)))]
7950 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7951 "test{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
7952 [(set_attr "type" "test")
7953 (set_attr "mode" "QI")])
e075ae69
RH
7954
7955(define_insn "*testqi_ext_2"
42fabf21 7956 [(set (reg FLAGS_REG)
16189740 7957 (compare
e075ae69
RH
7958 (and:SI
7959 (zero_extract:SI
d2836273 7960 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
7961 (const_int 8)
7962 (const_int 8))
7963 (zero_extract:SI
d2836273 7964 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
7965 (const_int 8)
7966 (const_int 8)))
7967 (const_int 0)))]
16189740 7968 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7969 "test{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
7970 [(set_attr "type" "test")
7971 (set_attr "mode" "QI")])
e075ae69
RH
7972
7973;; Combine likes to form bit extractions for some tests. Humor it.
6343a50e 7974(define_insn "*testqi_ext_3"
42fabf21 7975 [(set (reg FLAGS_REG)
16189740
RH
7976 (compare (zero_extract:SI
7977 (match_operand 0 "nonimmediate_operand" "rm")
7978 (match_operand:SI 1 "const_int_operand" "")
7979 (match_operand:SI 2 "const_int_operand" ""))
7980 (const_int 0)))]
7981 "ix86_match_ccmode (insn, CCNOmode)
7982 && (GET_MODE (operands[0]) == SImode
9b70259d
JH
7983 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7984 || GET_MODE (operands[0]) == HImode
7985 || GET_MODE (operands[0]) == QImode)"
7986 "#")
7987
7988(define_insn "*testqi_ext_3_rex64"
42fabf21 7989 [(set (reg FLAGS_REG)
9b70259d
JH
7990 (compare (zero_extract:DI
7991 (match_operand 0 "nonimmediate_operand" "rm")
7992 (match_operand:DI 1 "const_int_operand" "")
7993 (match_operand:DI 2 "const_int_operand" ""))
7994 (const_int 0)))]
1b0c37d7
ZW
7995 "TARGET_64BIT
7996 && ix86_match_ccmode (insn, CCNOmode)
f5143c46 7997 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
44cf5b6a
JH
7998 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7999 /* Ensure that resulting mask is zero or sign extended operand. */
8000 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8001 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8002 && INTVAL (operands[1]) > 32))
9b70259d
JH
8003 && (GET_MODE (operands[0]) == SImode
8004 || GET_MODE (operands[0]) == DImode
16189740
RH
8005 || GET_MODE (operands[0]) == HImode
8006 || GET_MODE (operands[0]) == QImode)"
e075ae69 8007 "#")
4fce8e83 8008
e075ae69 8009(define_split
25da5dc7
RH
8010 [(set (match_operand 0 "flags_reg_operand" "")
8011 (match_operator 1 "compare_operator"
8012 [(zero_extract
8013 (match_operand 2 "nonimmediate_operand" "")
8014 (match_operand 3 "const_int_operand" "")
8015 (match_operand 4 "const_int_operand" ""))
8016 (const_int 0)]))]
16189740 8017 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7 8018 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
e075ae69 8019{
25da5dc7
RH
8020 rtx val = operands[2];
8021 HOST_WIDE_INT len = INTVAL (operands[3]);
8022 HOST_WIDE_INT pos = INTVAL (operands[4]);
e075ae69 8023 HOST_WIDE_INT mask;
592188a5 8024 enum machine_mode mode, submode;
886c62d1 8025
25da5dc7
RH
8026 mode = GET_MODE (val);
8027 if (GET_CODE (val) == MEM)
5bc7cd8e 8028 {
e075ae69
RH
8029 /* ??? Combine likes to put non-volatile mem extractions in QImode
8030 no matter the size of the test. So find a mode that works. */
25da5dc7 8031 if (! MEM_VOLATILE_P (val))
e075ae69
RH
8032 {
8033 mode = smallest_mode_for_size (pos + len, MODE_INT);
25da5dc7 8034 val = adjust_address (val, mode, 0);
e075ae69 8035 }
5bc7cd8e 8036 }
25da5dc7
RH
8037 else if (GET_CODE (val) == SUBREG
8038 && (submode = GET_MODE (SUBREG_REG (val)),
592188a5
RH
8039 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8040 && pos + len <= GET_MODE_BITSIZE (submode))
8041 {
8042 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8043 mode = submode;
25da5dc7 8044 val = SUBREG_REG (val);
592188a5 8045 }
e075ae69 8046 else if (mode == HImode && pos + len <= 8)
5bc7cd8e 8047 {
e075ae69
RH
8048 /* Small HImode tests can be converted to QImode. */
8049 mode = QImode;
25da5dc7 8050 val = gen_lowpart (QImode, val);
5bc7cd8e
SC
8051 }
8052
e075ae69
RH
8053 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8054 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
886c62d1 8055
25da5dc7 8056 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
0f40f9f7 8057})
886c62d1 8058
6c81a490
JH
8059;; Convert HImode/SImode test instructions with immediate to QImode ones.
8060;; i386 does not allow to encode test with 8bit sign extended immediate, so
8061;; this is relatively important trick.
d1f87653 8062;; Do the conversion only post-reload to avoid limiting of the register class
6c81a490
JH
8063;; to QI regs.
8064(define_split
25da5dc7
RH
8065 [(set (match_operand 0 "flags_reg_operand" "")
8066 (match_operator 1 "compare_operator"
8067 [(and (match_operand 2 "register_operand" "")
8068 (match_operand 3 "const_int_operand" ""))
8069 (const_int 0)]))]
2f41793e 8070 "reload_completed
25da5dc7
RH
8071 && QI_REG_P (operands[2])
8072 && GET_MODE (operands[2]) != QImode
6c81a490 8073 && ((ix86_match_ccmode (insn, CCZmode)
25da5dc7 8074 && !(INTVAL (operands[3]) & ~(255 << 8)))
6c81a490 8075 || (ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
8076 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8077 [(set (match_dup 0)
8078 (match_op_dup 1
8079 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8080 (match_dup 3))
8081 (const_int 0)]))]
8082 "operands[2] = gen_lowpart (SImode, operands[2]);
8083 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
6c81a490
JH
8084
8085(define_split
25da5dc7
RH
8086 [(set (match_operand 0 "flags_reg_operand" "")
8087 (match_operator 1 "compare_operator"
8088 [(and (match_operand 2 "nonimmediate_operand" "")
8089 (match_operand 3 "const_int_operand" ""))
8090 (const_int 0)]))]
2f41793e 8091 "reload_completed
25da5dc7
RH
8092 && GET_MODE (operands[2]) != QImode
8093 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
6c81a490 8094 && ((ix86_match_ccmode (insn, CCZmode)
25da5dc7 8095 && !(INTVAL (operands[3]) & ~255))
6c81a490 8096 || (ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
8097 && !(INTVAL (operands[3]) & ~127)))"
8098 [(set (match_dup 0)
8099 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8100 (const_int 0)]))]
8101 "operands[2] = gen_lowpart (QImode, operands[2]);
8102 operands[3] = gen_lowpart (QImode, operands[3]);")
6c81a490
JH
8103
8104
e075ae69
RH
8105;; %%% This used to optimize known byte-wide and operations to memory,
8106;; and sometimes to QImode registers. If this is considered useful,
8107;; it should be done with splitters.
8108
9b70259d
JH
8109(define_expand "anddi3"
8110 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8111 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8112 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8bc527af 8113 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8114 "TARGET_64BIT"
8115 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8116
8117(define_insn "*anddi_1_rex64"
8118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8119 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8120 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8bc527af 8121 (clobber (reg:CC FLAGS_REG))]
9b70259d 8122 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9b70259d
JH
8123{
8124 switch (get_attr_type (insn))
8125 {
8126 case TYPE_IMOVX:
8127 {
8128 enum machine_mode mode;
8129
8130 if (GET_CODE (operands[2]) != CONST_INT)
8131 abort ();
8132 if (INTVAL (operands[2]) == 0xff)
8133 mode = QImode;
8134 else if (INTVAL (operands[2]) == 0xffff)
8135 mode = HImode;
8136 else
8137 abort ();
8138
8139 operands[1] = gen_lowpart (mode, operands[1]);
8140 if (mode == QImode)
0f40f9f7 8141 return "movz{bq|x}\t{%1,%0|%0, %1}";
9b70259d 8142 else
0f40f9f7 8143 return "movz{wq|x}\t{%1,%0|%0, %1}";
9b70259d
JH
8144 }
8145
8146 default:
8147 if (! rtx_equal_p (operands[0], operands[1]))
8148 abort ();
8149 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 8150 return "and{l}\t{%k2, %k0|%k0, %k2}";
9b70259d 8151 else
0f40f9f7 8152 return "and{q}\t{%2, %0|%0, %2}";
9b70259d 8153 }
0f40f9f7 8154}
9b70259d
JH
8155 [(set_attr "type" "alu,alu,alu,imovx")
8156 (set_attr "length_immediate" "*,*,*,0")
8157 (set_attr "mode" "SI,DI,DI,DI")])
8158
8159(define_insn "*anddi_2"
42fabf21 8160 [(set (reg FLAGS_REG)
9b70259d
JH
8161 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8162 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8163 (const_int 0)))
8164 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8165 (and:DI (match_dup 1) (match_dup 2)))]
8166 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8167 && ix86_binary_operator_ok (AND, DImode, operands)"
8168 "@
5a0855a0
JJ
8169 and{l}\t{%k2, %k0|%k0, %k2}
8170 and{q}\t{%2, %0|%0, %2}
0f40f9f7 8171 and{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8172 [(set_attr "type" "alu")
8173 (set_attr "mode" "SI,DI,DI")])
8174
e075ae69
RH
8175(define_expand "andsi3"
8176 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8177 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8178 (match_operand:SI 2 "general_operand" "")))
8bc527af 8179 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
8180 ""
8181 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8182
8183(define_insn "*andsi_1"
8184 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8185 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8186 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8bc527af 8187 (clobber (reg:CC FLAGS_REG))]
e075ae69 8188 "ix86_binary_operator_ok (AND, SImode, operands)"
886c62d1 8189{
e075ae69 8190 switch (get_attr_type (insn))
886c62d1 8191 {
e075ae69
RH
8192 case TYPE_IMOVX:
8193 {
8194 enum machine_mode mode;
5bc7cd8e 8195
e075ae69
RH
8196 if (GET_CODE (operands[2]) != CONST_INT)
8197 abort ();
8198 if (INTVAL (operands[2]) == 0xff)
8199 mode = QImode;
8200 else if (INTVAL (operands[2]) == 0xffff)
8201 mode = HImode;
8202 else
8203 abort ();
8204
8205 operands[1] = gen_lowpart (mode, operands[1]);
8206 if (mode == QImode)
0f40f9f7 8207 return "movz{bl|x}\t{%1,%0|%0, %1}";
e075ae69 8208 else
0f40f9f7 8209 return "movz{wl|x}\t{%1,%0|%0, %1}";
e075ae69 8210 }
5bc7cd8e 8211
e075ae69
RH
8212 default:
8213 if (! rtx_equal_p (operands[0], operands[1]))
8214 abort ();
0f40f9f7 8215 return "and{l}\t{%2, %0|%0, %2}";
886c62d1 8216 }
0f40f9f7 8217}
6ef67412
JH
8218 [(set_attr "type" "alu,alu,imovx")
8219 (set_attr "length_immediate" "*,*,0")
8220 (set_attr "mode" "SI")])
8221
8222(define_split
05b432db 8223 [(set (match_operand 0 "register_operand" "")
9b70259d
JH
8224 (and (match_dup 0)
8225 (const_int -65536)))
8bc527af 8226 (clobber (reg:CC FLAGS_REG))]
285464d0 8227 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
6ef67412
JH
8228 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8229 "operands[1] = gen_lowpart (HImode, operands[0]);")
8230
8231(define_split
3522082b 8232 [(set (match_operand 0 "ext_register_operand" "")
5e1a2fc7 8233 (and (match_dup 0)
9b70259d 8234 (const_int -256)))
8bc527af 8235 (clobber (reg:CC FLAGS_REG))]
05b432db 8236 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
6ef67412
JH
8237 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8238 "operands[1] = gen_lowpart (QImode, operands[0]);")
8239
8240(define_split
3522082b 8241 [(set (match_operand 0 "ext_register_operand" "")
6ef67412
JH
8242 (and (match_dup 0)
8243 (const_int -65281)))
8bc527af 8244 (clobber (reg:CC FLAGS_REG))]
05b432db 8245 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
6ef67412
JH
8246 [(parallel [(set (zero_extract:SI (match_dup 0)
8247 (const_int 8)
8248 (const_int 8))
8249 (xor:SI
8250 (zero_extract:SI (match_dup 0)
8251 (const_int 8)
8252 (const_int 8))
8253 (zero_extract:SI (match_dup 0)
8254 (const_int 8)
8255 (const_int 8))))
8bc527af 8256 (clobber (reg:CC FLAGS_REG))])]
6ef67412 8257 "operands[0] = gen_lowpart (SImode, operands[0]);")
e075ae69 8258
9b70259d
JH
8259;; See comment for addsi_1_zext why we do use nonimmediate_operand
8260(define_insn "*andsi_1_zext"
8261 [(set (match_operand:DI 0 "register_operand" "=r")
8262 (zero_extend:DI
8263 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8264 (match_operand:SI 2 "general_operand" "rim"))))
8bc527af 8265 (clobber (reg:CC FLAGS_REG))]
9b70259d 8266 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 8267 "and{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8268 [(set_attr "type" "alu")
8269 (set_attr "mode" "SI")])
8270
e075ae69 8271(define_insn "*andsi_2"
42fabf21 8272 [(set (reg FLAGS_REG)
16189740
RH
8273 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8274 (match_operand:SI 2 "general_operand" "rim,ri"))
8275 (const_int 0)))
e075ae69
RH
8276 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8277 (and:SI (match_dup 1) (match_dup 2)))]
16189740
RH
8278 "ix86_match_ccmode (insn, CCNOmode)
8279 && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 8280 "and{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8281 [(set_attr "type" "alu")
8282 (set_attr "mode" "SI")])
e075ae69 8283
9b70259d
JH
8284;; See comment for addsi_1_zext why we do use nonimmediate_operand
8285(define_insn "*andsi_2_zext"
42fabf21 8286 [(set (reg FLAGS_REG)
9b70259d
JH
8287 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8288 (match_operand:SI 2 "general_operand" "rim"))
8289 (const_int 0)))
8290 (set (match_operand:DI 0 "register_operand" "=r")
8291 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8292 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8293 && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 8294 "and{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8295 [(set_attr "type" "alu")
8296 (set_attr "mode" "SI")])
8297
e075ae69
RH
8298(define_expand "andhi3"
8299 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8300 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8301 (match_operand:HI 2 "general_operand" "")))
8bc527af 8302 (clobber (reg:CC FLAGS_REG))]
d9f32422 8303 "TARGET_HIMODE_MATH"
e075ae69
RH
8304 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8305
8306(define_insn "*andhi_1"
8307 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8308 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8309 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8bc527af 8310 (clobber (reg:CC FLAGS_REG))]
e075ae69 8311 "ix86_binary_operator_ok (AND, HImode, operands)"
886c62d1 8312{
e075ae69 8313 switch (get_attr_type (insn))
886c62d1 8314 {
e075ae69
RH
8315 case TYPE_IMOVX:
8316 if (GET_CODE (operands[2]) != CONST_INT)
8317 abort ();
8318 if (INTVAL (operands[2]) == 0xff)
0f40f9f7 8319 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
e075ae69 8320 abort ();
886c62d1 8321
e075ae69
RH
8322 default:
8323 if (! rtx_equal_p (operands[0], operands[1]))
8324 abort ();
886c62d1 8325
0f40f9f7 8326 return "and{w}\t{%2, %0|%0, %2}";
5bc7cd8e 8327 }
0f40f9f7 8328}
6ef67412
JH
8329 [(set_attr "type" "alu,alu,imovx")
8330 (set_attr "length_immediate" "*,*,0")
8331 (set_attr "mode" "HI,HI,SI")])
5bc7cd8e 8332
e075ae69 8333(define_insn "*andhi_2"
42fabf21 8334 [(set (reg FLAGS_REG)
16189740
RH
8335 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8336 (match_operand:HI 2 "general_operand" "rim,ri"))
8337 (const_int 0)))
e075ae69
RH
8338 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8339 (and:HI (match_dup 1) (match_dup 2)))]
16189740
RH
8340 "ix86_match_ccmode (insn, CCNOmode)
8341 && ix86_binary_operator_ok (AND, HImode, operands)"
0f40f9f7 8342 "and{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8343 [(set_attr "type" "alu")
8344 (set_attr "mode" "HI")])
5bc7cd8e 8345
e075ae69
RH
8346(define_expand "andqi3"
8347 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8348 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8349 (match_operand:QI 2 "general_operand" "")))
8bc527af 8350 (clobber (reg:CC FLAGS_REG))]
d9f32422 8351 "TARGET_QIMODE_MATH"
e075ae69
RH
8352 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8353
8354;; %%% Potential partial reg stall on alternative 2. What to do?
8355(define_insn "*andqi_1"
7c6b971d 8356 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 8357 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 8358 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8bc527af 8359 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
8360 "ix86_binary_operator_ok (AND, QImode, operands)"
8361 "@
0f40f9f7
ZW
8362 and{b}\t{%2, %0|%0, %2}
8363 and{b}\t{%2, %0|%0, %2}
8364 and{l}\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
8365 [(set_attr "type" "alu")
8366 (set_attr "mode" "QI,QI,SI")])
e075ae69 8367
a1b8572c
JH
8368(define_insn "*andqi_1_slp"
8369 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8370 (and:QI (match_dup 0)
8371 (match_operand:QI 1 "general_operand" "qi,qmi")))
8bc527af 8372 (clobber (reg:CC FLAGS_REG))]
1b245ade
JH
8373 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8374 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 8375 "and{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8376 [(set_attr "type" "alu1")
8377 (set_attr "mode" "QI")])
8378
88d60956 8379(define_insn "*andqi_2_maybe_si"
42fabf21 8380 [(set (reg FLAGS_REG)
16189740 8381 (compare (and:QI
88d60956
RH
8382 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8383 (match_operand:QI 2 "general_operand" "qim,qi,i"))
16189740 8384 (const_int 0)))
e075ae69
RH
8385 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8386 (and:QI (match_dup 1) (match_dup 2)))]
88d60956
RH
8387 "ix86_binary_operator_ok (AND, QImode, operands)
8388 && ix86_match_ccmode (insn,
8389 GET_CODE (operands[2]) == CONST_INT
8390 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
adc88131
JJ
8391{
8392 if (which_alternative == 2)
8393 {
88d60956 8394 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
adc88131 8395 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
0f40f9f7 8396 return "and{l}\t{%2, %k0|%k0, %2}";
adc88131 8397 }
0f40f9f7
ZW
8398 return "and{b}\t{%2, %0|%0, %2}";
8399}
6ef67412
JH
8400 [(set_attr "type" "alu")
8401 (set_attr "mode" "QI,QI,SI")])
e075ae69 8402
88d60956
RH
8403(define_insn "*andqi_2"
8404 [(set (reg FLAGS_REG)
8405 (compare (and:QI
8406 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8407 (match_operand:QI 2 "general_operand" "qim,qi"))
8408 (const_int 0)))
8409 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8410 (and:QI (match_dup 1) (match_dup 2)))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && ix86_binary_operator_ok (AND, QImode, operands)"
8413 "and{b}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "QI")])
8416
a1b8572c 8417(define_insn "*andqi_2_slp"
42fabf21 8418 [(set (reg FLAGS_REG)
a1b8572c
JH
8419 (compare (and:QI
8420 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8421 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8422 (const_int 0)))
8423 (set (strict_low_part (match_dup 0))
8424 (and:QI (match_dup 0) (match_dup 1)))]
2f41793e 8425 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade
JH
8426 && ix86_match_ccmode (insn, CCNOmode)
8427 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 8428 "and{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8429 [(set_attr "type" "alu1")
8430 (set_attr "mode" "QI")])
8431
e075ae69
RH
8432;; ??? A bug in recog prevents it from recognizing a const_int as an
8433;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8434;; for a QImode operand, which of course failed.
8435
8436(define_insn "andqi_ext_0"
d2836273 8437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8438 (const_int 8)
8439 (const_int 8))
8440 (and:SI
8441 (zero_extract:SI
8442 (match_operand 1 "ext_register_operand" "0")
8443 (const_int 8)
8444 (const_int 8))
8445 (match_operand 2 "const_int_operand" "n")))
8bc527af 8446 (clobber (reg:CC FLAGS_REG))]
2f41793e 8447 ""
0f40f9f7 8448 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8449 [(set_attr "type" "alu")
8450 (set_attr "length_immediate" "1")
8451 (set_attr "mode" "QI")])
e075ae69
RH
8452
8453;; Generated by peephole translating test to and. This shows up
8454;; often in fp comparisons.
8455
8456(define_insn "*andqi_ext_0_cc"
42fabf21 8457 [(set (reg FLAGS_REG)
16189740 8458 (compare
e075ae69
RH
8459 (and:SI
8460 (zero_extract:SI
084e679a 8461 (match_operand 1 "ext_register_operand" "0")
3522082b 8462 (const_int 8)
e075ae69
RH
8463 (const_int 8))
8464 (match_operand 2 "const_int_operand" "n"))
8465 (const_int 0)))
d2836273 8466 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8467 (const_int 8)
8468 (const_int 8))
8469 (and:SI
8470 (zero_extract:SI
8471 (match_dup 1)
8472 (const_int 8)
8473 (const_int 8))
8474 (match_dup 2)))]
2f41793e 8475 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8476 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8477 [(set_attr "type" "alu")
8478 (set_attr "length_immediate" "1")
8479 (set_attr "mode" "QI")])
e075ae69
RH
8480
8481(define_insn "*andqi_ext_1"
d2836273 8482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8483 (const_int 8)
8484 (const_int 8))
8485 (and:SI
8486 (zero_extract:SI
8487 (match_operand 1 "ext_register_operand" "0")
8488 (const_int 8)
8489 (const_int 8))
8490 (zero_extend:SI
d2836273 8491 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 8492 (clobber (reg:CC FLAGS_REG))]
d2836273 8493 "!TARGET_64BIT"
0f40f9f7 8494 "and{b}\t{%2, %h0|%h0, %2}"
d2836273
JH
8495 [(set_attr "type" "alu")
8496 (set_attr "length_immediate" "0")
8497 (set_attr "mode" "QI")])
8498
8499(define_insn "*andqi_ext_1_rex64"
8500 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8501 (const_int 8)
8502 (const_int 8))
8503 (and:SI
8504 (zero_extract:SI
8505 (match_operand 1 "ext_register_operand" "0")
8506 (const_int 8)
8507 (const_int 8))
8508 (zero_extend:SI
3522082b 8509 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 8510 (clobber (reg:CC FLAGS_REG))]
d2836273 8511 "TARGET_64BIT"
0f40f9f7 8512 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8513 [(set_attr "type" "alu")
8514 (set_attr "length_immediate" "0")
8515 (set_attr "mode" "QI")])
e075ae69
RH
8516
8517(define_insn "*andqi_ext_2"
d2836273 8518 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8519 (const_int 8)
8520 (const_int 8))
8521 (and:SI
8522 (zero_extract:SI
8523 (match_operand 1 "ext_register_operand" "%0")
8524 (const_int 8)
8525 (const_int 8))
8526 (zero_extract:SI
d2836273 8527 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
8528 (const_int 8)
8529 (const_int 8))))
8bc527af 8530 (clobber (reg:CC FLAGS_REG))]
e075ae69 8531 ""
0f40f9f7 8532 "and{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
8533 [(set_attr "type" "alu")
8534 (set_attr "length_immediate" "0")
8535 (set_attr "mode" "QI")])
2f41793e
JH
8536
8537;; Convert wide AND instructions with immediate operand to shorter QImode
8538;; equivalents when possible.
d1f87653 8539;; Don't do the splitting with memory operands, since it introduces risk
2f41793e
JH
8540;; of memory mismatch stalls. We may want to do the splitting for optimizing
8541;; for size, but that can (should?) be handled by generic code instead.
8542(define_split
8543 [(set (match_operand 0 "register_operand" "")
8544 (and (match_operand 1 "register_operand" "")
8545 (match_operand 2 "const_int_operand" "")))
8bc527af 8546 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8547 "reload_completed
8548 && QI_REG_P (operands[0])
8549 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8550 && !(~INTVAL (operands[2]) & ~(255 << 8))
8551 && GET_MODE (operands[0]) != QImode"
8552 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8553 (and:SI (zero_extract:SI (match_dup 1)
8554 (const_int 8) (const_int 8))
8555 (match_dup 2)))
8bc527af 8556 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8557 "operands[0] = gen_lowpart (SImode, operands[0]);
8558 operands[1] = gen_lowpart (SImode, operands[1]);
8559 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8560
8561;; Since AND can be encoded with sign extended immediate, this is only
8562;; profitable when 7th bit is not set.
8563(define_split
8564 [(set (match_operand 0 "register_operand" "")
8565 (and (match_operand 1 "general_operand" "")
8566 (match_operand 2 "const_int_operand" "")))
8bc527af 8567 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8568 "reload_completed
8569 && ANY_QI_REG_P (operands[0])
8570 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571 && !(~INTVAL (operands[2]) & ~255)
8572 && !(INTVAL (operands[2]) & 128)
8573 && GET_MODE (operands[0]) != QImode"
8574 [(parallel [(set (strict_low_part (match_dup 0))
8575 (and:QI (match_dup 1)
8576 (match_dup 2)))
8bc527af 8577 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8578 "operands[0] = gen_lowpart (QImode, operands[0]);
8579 operands[1] = gen_lowpart (QImode, operands[1]);
8580 operands[2] = gen_lowpart (QImode, operands[2]);")
886c62d1 8581\f
e075ae69 8582;; Logical inclusive OR instructions
57dbca5e 8583
e075ae69
RH
8584;; %%% This used to optimize known byte-wide and operations to memory.
8585;; If this is considered useful, it should be done with splitters.
8586
9b70259d
JH
8587(define_expand "iordi3"
8588 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8589 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8590 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 8591 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8592 "TARGET_64BIT"
8593 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8594
8595(define_insn "*iordi_1_rex64"
8596 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8597 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8598 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8bc527af 8599 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8600 "TARGET_64BIT
8601 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 8602 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8603 [(set_attr "type" "alu")
8604 (set_attr "mode" "DI")])
8605
8606(define_insn "*iordi_2_rex64"
42fabf21 8607 [(set (reg FLAGS_REG)
9b70259d
JH
8608 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8609 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8610 (const_int 0)))
8611 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8612 (ior:DI (match_dup 1) (match_dup 2)))]
8613 "TARGET_64BIT
8614 && ix86_match_ccmode (insn, CCNOmode)
8615 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 8616 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8617 [(set_attr "type" "alu")
8618 (set_attr "mode" "DI")])
8619
8620(define_insn "*iordi_3_rex64"
42fabf21 8621 [(set (reg FLAGS_REG)
9b70259d
JH
8622 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8623 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8624 (const_int 0)))
8625 (clobber (match_scratch:DI 0 "=r"))]
8626 "TARGET_64BIT
8627 && ix86_match_ccmode (insn, CCNOmode)
8628 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 8629 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8630 [(set_attr "type" "alu")
8631 (set_attr "mode" "DI")])
8632
8633
e075ae69
RH
8634(define_expand "iorsi3"
8635 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8636 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8637 (match_operand:SI 2 "general_operand" "")))
8bc527af 8638 (clobber (reg:CC FLAGS_REG))]
57dbca5e 8639 ""
e075ae69
RH
8640 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8641
8642(define_insn "*iorsi_1"
8643 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8644 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8645 (match_operand:SI 2 "general_operand" "ri,rmi")))
8bc527af 8646 (clobber (reg:CC FLAGS_REG))]
e075ae69 8647 "ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8648 "or{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
e075ae69 8651
9b70259d
JH
8652;; See comment for addsi_1_zext why we do use nonimmediate_operand
8653(define_insn "*iorsi_1_zext"
8654 [(set (match_operand:DI 0 "register_operand" "=rm")
8655 (zero_extend:DI
8656 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8657 (match_operand:SI 2 "general_operand" "rim"))))
8bc527af 8658 (clobber (reg:CC FLAGS_REG))]
9b70259d 8659 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8660 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8663
8664(define_insn "*iorsi_1_zext_imm"
8665 [(set (match_operand:DI 0 "register_operand" "=rm")
8666 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8667 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8bc527af 8668 (clobber (reg:CC FLAGS_REG))]
9b70259d 8669 "TARGET_64BIT"
0f40f9f7 8670 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8671 [(set_attr "type" "alu")
8672 (set_attr "mode" "SI")])
8673
e075ae69 8674(define_insn "*iorsi_2"
42fabf21 8675 [(set (reg FLAGS_REG)
16189740
RH
8676 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8677 (match_operand:SI 2 "general_operand" "rim,ri"))
8678 (const_int 0)))
e075ae69
RH
8679 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8680 (ior:SI (match_dup 1) (match_dup 2)))]
16189740
RH
8681 "ix86_match_ccmode (insn, CCNOmode)
8682 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8683 "or{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8684 [(set_attr "type" "alu")
8685 (set_attr "mode" "SI")])
e075ae69 8686
9b70259d
JH
8687;; See comment for addsi_1_zext why we do use nonimmediate_operand
8688;; ??? Special case for immediate operand is missing - it is tricky.
8689(define_insn "*iorsi_2_zext"
42fabf21 8690 [(set (reg FLAGS_REG)
9b70259d
JH
8691 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8692 (match_operand:SI 2 "general_operand" "rim"))
8693 (const_int 0)))
8694 (set (match_operand:DI 0 "register_operand" "=r")
8695 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8696 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8697 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8698 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8699 [(set_attr "type" "alu")
8700 (set_attr "mode" "SI")])
8701
8702(define_insn "*iorsi_2_zext_imm"
42fabf21 8703 [(set (reg FLAGS_REG)
9b70259d
JH
8704 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8705 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8706 (const_int 0)))
8707 (set (match_operand:DI 0 "register_operand" "=r")
8708 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8709 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8710 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8711 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8712 [(set_attr "type" "alu")
8713 (set_attr "mode" "SI")])
8714
d90ffc8d 8715(define_insn "*iorsi_3"
42fabf21 8716 [(set (reg FLAGS_REG)
d90ffc8d
JH
8717 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8718 (match_operand:SI 2 "general_operand" "rim"))
8719 (const_int 0)))
8720 (clobber (match_scratch:SI 0 "=r"))]
8721 "ix86_match_ccmode (insn, CCNOmode)
8722 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 8723 "or{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8724 [(set_attr "type" "alu")
8725 (set_attr "mode" "SI")])
8726
e075ae69
RH
8727(define_expand "iorhi3"
8728 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8729 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8730 (match_operand:HI 2 "general_operand" "")))
8bc527af 8731 (clobber (reg:CC FLAGS_REG))]
d9f32422 8732 "TARGET_HIMODE_MATH"
e075ae69
RH
8733 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8734
8735(define_insn "*iorhi_1"
8736 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8737 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8738 (match_operand:HI 2 "general_operand" "rmi,ri")))
8bc527af 8739 (clobber (reg:CC FLAGS_REG))]
e075ae69 8740 "ix86_binary_operator_ok (IOR, HImode, operands)"
0f40f9f7 8741 "or{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8742 [(set_attr "type" "alu")
8743 (set_attr "mode" "HI")])
e075ae69 8744
e075ae69 8745(define_insn "*iorhi_2"
42fabf21 8746 [(set (reg FLAGS_REG)
16189740
RH
8747 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8748 (match_operand:HI 2 "general_operand" "rim,ri"))
8749 (const_int 0)))
e075ae69
RH
8750 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8751 (ior:HI (match_dup 1) (match_dup 2)))]
16189740
RH
8752 "ix86_match_ccmode (insn, CCNOmode)
8753 && ix86_binary_operator_ok (IOR, HImode, operands)"
0f40f9f7 8754 "or{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8755 [(set_attr "type" "alu")
8756 (set_attr "mode" "HI")])
e075ae69 8757
d90ffc8d 8758(define_insn "*iorhi_3"
42fabf21 8759 [(set (reg FLAGS_REG)
d90ffc8d
JH
8760 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8761 (match_operand:HI 2 "general_operand" "rim"))
8762 (const_int 0)))
8763 (clobber (match_scratch:HI 0 "=r"))]
8764 "ix86_match_ccmode (insn, CCNOmode)
8765 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 8766 "or{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "HI")])
8769
e075ae69
RH
8770(define_expand "iorqi3"
8771 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8772 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8773 (match_operand:QI 2 "general_operand" "")))
8bc527af 8774 (clobber (reg:CC FLAGS_REG))]
d9f32422 8775 "TARGET_QIMODE_MATH"
e075ae69
RH
8776 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8777
8778;; %%% Potential partial reg stall on alternative 2. What to do?
8779(define_insn "*iorqi_1"
7c6b971d 8780 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
e075ae69 8781 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 8782 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8bc527af 8783 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
8784 "ix86_binary_operator_ok (IOR, QImode, operands)"
8785 "@
0f40f9f7
ZW
8786 or{b}\t{%2, %0|%0, %2}
8787 or{b}\t{%2, %0|%0, %2}
8788 or{l}\t{%k2, %k0|%k0, %k2}"
6ef67412 8789 [(set_attr "type" "alu")
a1b8572c
JH
8790 (set_attr "mode" "QI,QI,SI")])
8791
8792(define_insn "*iorqi_1_slp"
8793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8794 (ior:QI (match_dup 0)
8795 (match_operand:QI 1 "general_operand" "qmi,qi")))
8bc527af 8796 (clobber (reg:CC FLAGS_REG))]
1b245ade
JH
8797 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8798 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 8799 "or{b}\t{%1, %0|%0, %1}"
a1b8572c 8800 [(set_attr "type" "alu1")
6ef67412 8801 (set_attr "mode" "QI")])
e075ae69
RH
8802
8803(define_insn "*iorqi_2"
42fabf21 8804 [(set (reg FLAGS_REG)
16189740
RH
8805 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8806 (match_operand:QI 2 "general_operand" "qim,qi"))
8807 (const_int 0)))
e075ae69
RH
8808 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8809 (ior:QI (match_dup 1) (match_dup 2)))]
16189740
RH
8810 "ix86_match_ccmode (insn, CCNOmode)
8811 && ix86_binary_operator_ok (IOR, QImode, operands)"
0f40f9f7 8812 "or{b}\t{%2, %0|%0, %2}"
6ef67412
JH
8813 [(set_attr "type" "alu")
8814 (set_attr "mode" "QI")])
d90ffc8d 8815
a1b8572c 8816(define_insn "*iorqi_2_slp"
42fabf21 8817 [(set (reg FLAGS_REG)
a1b8572c
JH
8818 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8819 (match_operand:QI 1 "general_operand" "qim,qi"))
8820 (const_int 0)))
8821 (set (strict_low_part (match_dup 0))
8822 (ior:QI (match_dup 0) (match_dup 1)))]
2f41793e 8823 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade
JH
8824 && ix86_match_ccmode (insn, CCNOmode)
8825 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 8826 "or{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8827 [(set_attr "type" "alu1")
8828 (set_attr "mode" "QI")])
8829
d90ffc8d 8830(define_insn "*iorqi_3"
42fabf21 8831 [(set (reg FLAGS_REG)
d90ffc8d
JH
8832 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8833 (match_operand:QI 2 "general_operand" "qim"))
8834 (const_int 0)))
7e08e190 8835 (clobber (match_scratch:QI 0 "=q"))]
d90ffc8d
JH
8836 "ix86_match_ccmode (insn, CCNOmode)
8837 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 8838 "or{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8839 [(set_attr "type" "alu")
8840 (set_attr "mode" "QI")])
8841
2f41793e
JH
8842(define_insn "iorqi_ext_0"
8843 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8844 (const_int 8)
8845 (const_int 8))
8846 (ior:SI
8847 (zero_extract:SI
8848 (match_operand 1 "ext_register_operand" "0")
8849 (const_int 8)
8850 (const_int 8))
8851 (match_operand 2 "const_int_operand" "n")))
8bc527af 8852 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8853 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8854 "or{b}\t{%2, %h0|%h0, %2}"
8855 [(set_attr "type" "alu")
8856 (set_attr "length_immediate" "1")
8857 (set_attr "mode" "QI")])
8858
8859(define_insn "*iorqi_ext_1"
8860 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8861 (const_int 8)
8862 (const_int 8))
8863 (ior:SI
8864 (zero_extract:SI
8865 (match_operand 1 "ext_register_operand" "0")
8866 (const_int 8)
8867 (const_int 8))
8868 (zero_extend:SI
8869 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 8870 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8871 "!TARGET_64BIT
8872 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8873 "or{b}\t{%2, %h0|%h0, %2}"
8874 [(set_attr "type" "alu")
8875 (set_attr "length_immediate" "0")
8876 (set_attr "mode" "QI")])
8877
8878(define_insn "*iorqi_ext_1_rex64"
8879 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8880 (const_int 8)
8881 (const_int 8))
8882 (ior:SI
8883 (zero_extract:SI
8884 (match_operand 1 "ext_register_operand" "0")
8885 (const_int 8)
8886 (const_int 8))
8887 (zero_extend:SI
8888 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 8889 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8890 "TARGET_64BIT
8891 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8892 "or{b}\t{%2, %h0|%h0, %2}"
8893 [(set_attr "type" "alu")
8894 (set_attr "length_immediate" "0")
8895 (set_attr "mode" "QI")])
8896
8897(define_insn "*iorqi_ext_2"
8898 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8899 (const_int 8)
8900 (const_int 8))
8901 (ior:SI
8902 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8903 (const_int 8)
8904 (const_int 8))
8905 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8906 (const_int 8)
8907 (const_int 8))))
8bc527af 8908 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8909 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8910 "ior{b}\t{%h2, %h0|%h0, %h2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "length_immediate" "0")
8913 (set_attr "mode" "QI")])
8914
8915(define_split
8916 [(set (match_operand 0 "register_operand" "")
8917 (ior (match_operand 1 "register_operand" "")
8918 (match_operand 2 "const_int_operand" "")))
8bc527af 8919 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8920 "reload_completed
8921 && QI_REG_P (operands[0])
8922 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8923 && !(INTVAL (operands[2]) & ~(255 << 8))
8924 && GET_MODE (operands[0]) != QImode"
8925 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8926 (ior:SI (zero_extract:SI (match_dup 1)
8927 (const_int 8) (const_int 8))
8928 (match_dup 2)))
8bc527af 8929 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8930 "operands[0] = gen_lowpart (SImode, operands[0]);
8931 operands[1] = gen_lowpart (SImode, operands[1]);
8932 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8933
8934;; Since OR can be encoded with sign extended immediate, this is only
8935;; profitable when 7th bit is set.
8936(define_split
8937 [(set (match_operand 0 "register_operand" "")
8938 (ior (match_operand 1 "general_operand" "")
8939 (match_operand 2 "const_int_operand" "")))
8bc527af 8940 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
8941 "reload_completed
8942 && ANY_QI_REG_P (operands[0])
8943 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944 && !(INTVAL (operands[2]) & ~255)
8945 && (INTVAL (operands[2]) & 128)
8946 && GET_MODE (operands[0]) != QImode"
8947 [(parallel [(set (strict_low_part (match_dup 0))
8948 (ior:QI (match_dup 1)
8949 (match_dup 2)))
8bc527af 8950 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
8951 "operands[0] = gen_lowpart (QImode, operands[0]);
8952 operands[1] = gen_lowpart (QImode, operands[1]);
8953 operands[2] = gen_lowpart (QImode, operands[2]);")
e075ae69
RH
8954\f
8955;; Logical XOR instructions
a269a03c 8956
e075ae69
RH
8957;; %%% This used to optimize known byte-wide and operations to memory.
8958;; If this is considered useful, it should be done with splitters.
57dbca5e 8959
9b70259d
JH
8960(define_expand "xordi3"
8961 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8962 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8963 (match_operand:DI 2 "x86_64_general_operand" "")))
8bc527af 8964 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8965 "TARGET_64BIT"
8966 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8967
8968(define_insn "*xordi_1_rex64"
8969 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8970 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8971 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8bc527af 8972 (clobber (reg:CC FLAGS_REG))]
9b70259d
JH
8973 "TARGET_64BIT
8974 && ix86_binary_operator_ok (XOR, DImode, operands)"
8975 "@
5a0855a0 8976 xor{q}\t{%2, %0|%0, %2}
0f40f9f7 8977 xor{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "DI,DI")])
8980
8981(define_insn "*xordi_2_rex64"
42fabf21 8982 [(set (reg FLAGS_REG)
9b70259d
JH
8983 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8984 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8985 (const_int 0)))
8986 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8987 (xor:DI (match_dup 1) (match_dup 2)))]
8988 "TARGET_64BIT
8989 && ix86_match_ccmode (insn, CCNOmode)
8990 && ix86_binary_operator_ok (XOR, DImode, operands)"
8991 "@
5a0855a0 8992 xor{q}\t{%2, %0|%0, %2}
0f40f9f7 8993 xor{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8994 [(set_attr "type" "alu")
8995 (set_attr "mode" "DI,DI")])
8996
8997(define_insn "*xordi_3_rex64"
42fabf21 8998 [(set (reg FLAGS_REG)
9b70259d
JH
8999 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9000 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9001 (const_int 0)))
9002 (clobber (match_scratch:DI 0 "=r"))]
9003 "TARGET_64BIT
9004 && ix86_match_ccmode (insn, CCNOmode)
9005 && ix86_binary_operator_ok (XOR, DImode, operands)"
0f40f9f7 9006 "xor{q}\t{%2, %0|%0, %2}"
9b70259d
JH
9007 [(set_attr "type" "alu")
9008 (set_attr "mode" "DI")])
9009
e075ae69
RH
9010(define_expand "xorsi3"
9011 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9012 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9013 (match_operand:SI 2 "general_operand" "")))
8bc527af 9014 (clobber (reg:CC FLAGS_REG))]
57dbca5e 9015 ""
e075ae69 9016 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
a269a03c 9017
e075ae69
RH
9018(define_insn "*xorsi_1"
9019 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9020 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9021 (match_operand:SI 2 "general_operand" "ri,rm")))
8bc527af 9022 (clobber (reg:CC FLAGS_REG))]
e075ae69 9023 "ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9024 "xor{l}\t{%2, %0|%0, %2}"
6ef67412
JH
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "SI")])
e075ae69 9027
9b70259d
JH
9028;; See comment for addsi_1_zext why we do use nonimmediate_operand
9029;; Add speccase for immediates
9030(define_insn "*xorsi_1_zext"
9031 [(set (match_operand:DI 0 "register_operand" "=r")
9032 (zero_extend:DI
9033 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9034 (match_operand:SI 2 "general_operand" "rim"))))
8bc527af 9035 (clobber (reg:CC FLAGS_REG))]
9b70259d 9036 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9037 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9040
9041(define_insn "*xorsi_1_zext_imm"
9042 [(set (match_operand:DI 0 "register_operand" "=r")
9043 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9044 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8bc527af 9045 (clobber (reg:CC FLAGS_REG))]
9b70259d 9046 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9047 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
9048 [(set_attr "type" "alu")
9049 (set_attr "mode" "SI")])
9050
e075ae69 9051(define_insn "*xorsi_2"
42fabf21 9052 [(set (reg FLAGS_REG)
16189740
RH
9053 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9054 (match_operand:SI 2 "general_operand" "rim,ri"))
9055 (const_int 0)))
e075ae69
RH
9056 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9057 (xor:SI (match_dup 1) (match_dup 2)))]
16189740
RH
9058 "ix86_match_ccmode (insn, CCNOmode)
9059 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9060 "xor{l}\t{%2, %0|%0, %2}"
6ef67412
JH
9061 [(set_attr "type" "alu")
9062 (set_attr "mode" "SI")])
e075ae69 9063
9b70259d
JH
9064;; See comment for addsi_1_zext why we do use nonimmediate_operand
9065;; ??? Special case for immediate operand is missing - it is tricky.
9066(define_insn "*xorsi_2_zext"
42fabf21 9067 [(set (reg FLAGS_REG)
9b70259d
JH
9068 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9069 (match_operand:SI 2 "general_operand" "rim"))
9070 (const_int 0)))
9071 (set (match_operand:DI 0 "register_operand" "=r")
9072 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9073 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9074 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9075 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
9076 [(set_attr "type" "alu")
9077 (set_attr "mode" "SI")])
9078
9079(define_insn "*xorsi_2_zext_imm"
42fabf21 9080 [(set (reg FLAGS_REG)
9b70259d
JH
9081 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9082 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9083 (const_int 0)))
9084 (set (match_operand:DI 0 "register_operand" "=r")
9085 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9086 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9087 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 9088 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
9089 [(set_attr "type" "alu")
9090 (set_attr "mode" "SI")])
9091
d90ffc8d 9092(define_insn "*xorsi_3"
42fabf21 9093 [(set (reg FLAGS_REG)
d90ffc8d
JH
9094 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9095 (match_operand:SI 2 "general_operand" "rim"))
9096 (const_int 0)))
9097 (clobber (match_scratch:SI 0 "=r"))]
9098 "ix86_match_ccmode (insn, CCNOmode)
9099 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 9100 "xor{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
9101 [(set_attr "type" "alu")
9102 (set_attr "mode" "SI")])
9103
e075ae69
RH
9104(define_expand "xorhi3"
9105 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9106 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9107 (match_operand:HI 2 "general_operand" "")))
8bc527af 9108 (clobber (reg:CC FLAGS_REG))]
d9f32422 9109 "TARGET_HIMODE_MATH"
e075ae69
RH
9110 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9111
9112(define_insn "*xorhi_1"
9113 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9114 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9115 (match_operand:HI 2 "general_operand" "rmi,ri")))
8bc527af 9116 (clobber (reg:CC FLAGS_REG))]
e075ae69 9117 "ix86_binary_operator_ok (XOR, HImode, operands)"
0f40f9f7 9118 "xor{w}\t{%2, %0|%0, %2}"
6ef67412
JH
9119 [(set_attr "type" "alu")
9120 (set_attr "mode" "HI")])
57dbca5e 9121
e075ae69 9122(define_insn "*xorhi_2"
42fabf21 9123 [(set (reg FLAGS_REG)
16189740
RH
9124 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9125 (match_operand:HI 2 "general_operand" "rim,ri"))
9126 (const_int 0)))
e075ae69
RH
9127 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9128 (xor:HI (match_dup 1) (match_dup 2)))]
16189740
RH
9129 "ix86_match_ccmode (insn, CCNOmode)
9130 && ix86_binary_operator_ok (XOR, HImode, operands)"
0f40f9f7 9131 "xor{w}\t{%2, %0|%0, %2}"
6ef67412
JH
9132 [(set_attr "type" "alu")
9133 (set_attr "mode" "HI")])
e075ae69 9134
d90ffc8d 9135(define_insn "*xorhi_3"
42fabf21 9136 [(set (reg FLAGS_REG)
d90ffc8d
JH
9137 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9138 (match_operand:HI 2 "general_operand" "rim"))
9139 (const_int 0)))
9140 (clobber (match_scratch:HI 0 "=r"))]
9141 "ix86_match_ccmode (insn, CCNOmode)
9142 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 9143 "xor{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
9144 [(set_attr "type" "alu")
9145 (set_attr "mode" "HI")])
9146
e075ae69
RH
9147(define_expand "xorqi3"
9148 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9149 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9150 (match_operand:QI 2 "general_operand" "")))
8bc527af 9151 (clobber (reg:CC FLAGS_REG))]
d9f32422 9152 "TARGET_QIMODE_MATH"
e075ae69
RH
9153 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9154
9155;; %%% Potential partial reg stall on alternative 2. What to do?
9156(define_insn "*xorqi_1"
7c6b971d 9157 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
e075ae69 9158 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 9159 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8bc527af 9160 (clobber (reg:CC FLAGS_REG))]
e075ae69
RH
9161 "ix86_binary_operator_ok (XOR, QImode, operands)"
9162 "@
0f40f9f7
ZW
9163 xor{b}\t{%2, %0|%0, %2}
9164 xor{b}\t{%2, %0|%0, %2}
9165 xor{l}\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
9166 [(set_attr "type" "alu")
9167 (set_attr "mode" "QI,QI,SI")])
9168
b6bb1d56
JH
9169(define_insn "*xorqi_1_slp"
9170 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9171 (xor:QI (match_dup 0)
9172 (match_operand:QI 1 "general_operand" "qi,qmi")))
8bc527af 9173 (clobber (reg:CC FLAGS_REG))]
1b245ade
JH
9174 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9175 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
b6bb1d56
JH
9176 "xor{b}\t{%1, %0|%0, %1}"
9177 [(set_attr "type" "alu1")
9178 (set_attr "mode" "QI")])
9179
2f41793e
JH
9180(define_insn "xorqi_ext_0"
9181 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9182 (const_int 8)
9183 (const_int 8))
9184 (xor:SI
9185 (zero_extract:SI
9186 (match_operand 1 "ext_register_operand" "0")
9187 (const_int 8)
9188 (const_int 8))
9189 (match_operand 2 "const_int_operand" "n")))
8bc527af 9190 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
9191 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9192 "xor{b}\t{%2, %h0|%h0, %2}"
9193 [(set_attr "type" "alu")
9194 (set_attr "length_immediate" "1")
9195 (set_attr "mode" "QI")])
9196
a4414093 9197(define_insn "*xorqi_ext_1"
2f41793e
JH
9198 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9199 (const_int 8)
9200 (const_int 8))
9201 (xor:SI
9202 (zero_extract:SI
9203 (match_operand 1 "ext_register_operand" "0")
9204 (const_int 8)
9205 (const_int 8))
9206 (zero_extend:SI
9207 (match_operand:QI 2 "general_operand" "Qm"))))
8bc527af 9208 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
9209 "!TARGET_64BIT
9210 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9211 "xor{b}\t{%2, %h0|%h0, %2}"
9212 [(set_attr "type" "alu")
9213 (set_attr "length_immediate" "0")
9214 (set_attr "mode" "QI")])
9215
9216(define_insn "*xorqi_ext_1_rex64"
9217 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9218 (const_int 8)
9219 (const_int 8))
9220 (xor:SI
9221 (zero_extract:SI
9222 (match_operand 1 "ext_register_operand" "0")
9223 (const_int 8)
9224 (const_int 8))
9225 (zero_extend:SI
9226 (match_operand 2 "ext_register_operand" "Q"))))
8bc527af 9227 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
9228 "TARGET_64BIT
9229 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9230 "xor{b}\t{%2, %h0|%h0, %2}"
9231 [(set_attr "type" "alu")
9232 (set_attr "length_immediate" "0")
9233 (set_attr "mode" "QI")])
9234
9235(define_insn "*xorqi_ext_2"
d2836273 9236 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6ef67412
JH
9237 (const_int 8)
9238 (const_int 8))
9239 (xor:SI
9240 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9241 (const_int 8)
9242 (const_int 8))
d2836273 9243 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6ef67412
JH
9244 (const_int 8)
9245 (const_int 8))))
8bc527af 9246 (clobber (reg:CC FLAGS_REG))]
2f41793e 9247 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
0f40f9f7 9248 "xor{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
9249 [(set_attr "type" "alu")
9250 (set_attr "length_immediate" "0")
9251 (set_attr "mode" "QI")])
e075ae69 9252
7abd4e00 9253(define_insn "*xorqi_cc_1"
42fabf21 9254 [(set (reg FLAGS_REG)
16189740 9255 (compare
e075ae69
RH
9256 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9257 (match_operand:QI 2 "general_operand" "qim,qi"))
9258 (const_int 0)))
9259 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9260 (xor:QI (match_dup 1) (match_dup 2)))]
16189740
RH
9261 "ix86_match_ccmode (insn, CCNOmode)
9262 && ix86_binary_operator_ok (XOR, QImode, operands)"
0f40f9f7 9263 "xor{b}\t{%2, %0|%0, %2}"
6ef67412
JH
9264 [(set_attr "type" "alu")
9265 (set_attr "mode" "QI")])
e075ae69 9266
b6bb1d56 9267(define_insn "*xorqi_2_slp"
42fabf21 9268 [(set (reg FLAGS_REG)
b6bb1d56
JH
9269 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9270 (match_operand:QI 1 "general_operand" "qim,qi"))
9271 (const_int 0)))
9272 (set (strict_low_part (match_dup 0))
9273 (xor:QI (match_dup 0) (match_dup 1)))]
9274 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade
JH
9275 && ix86_match_ccmode (insn, CCNOmode)
9276 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
b6bb1d56
JH
9277 "xor{b}\t{%1, %0|%0, %1}"
9278 [(set_attr "type" "alu1")
9279 (set_attr "mode" "QI")])
9280
d90ffc8d 9281(define_insn "*xorqi_cc_2"
42fabf21 9282 [(set (reg FLAGS_REG)
d90ffc8d
JH
9283 (compare
9284 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9285 (match_operand:QI 2 "general_operand" "qim"))
9286 (const_int 0)))
7e08e190 9287 (clobber (match_scratch:QI 0 "=q"))]
d90ffc8d
JH
9288 "ix86_match_ccmode (insn, CCNOmode)
9289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 9290 "xor{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
9291 [(set_attr "type" "alu")
9292 (set_attr "mode" "QI")])
9293
9076b9c1 9294(define_insn "*xorqi_cc_ext_1"
42fabf21 9295 [(set (reg FLAGS_REG)
9076b9c1 9296 (compare
e075ae69
RH
9297 (xor:SI
9298 (zero_extract:SI
9299 (match_operand 1 "ext_register_operand" "0")
9300 (const_int 8)
9301 (const_int 8))
9302 (match_operand:QI 2 "general_operand" "qmn"))
9303 (const_int 0)))
9304 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9305 (const_int 8)
9306 (const_int 8))
9307 (xor:SI
9308 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9309 (match_dup 2)))]
d2836273 9310 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 9311 "xor{b}\t{%2, %h0|%h0, %2}"
d2836273
JH
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "QI")])
9314
9315(define_insn "*xorqi_cc_ext_1_rex64"
42fabf21 9316 [(set (reg FLAGS_REG)
d2836273
JH
9317 (compare
9318 (xor:SI
9319 (zero_extract:SI
9320 (match_operand 1 "ext_register_operand" "0")
9321 (const_int 8)
9322 (const_int 8))
9323 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9324 (const_int 0)))
9325 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9326 (const_int 8)
9327 (const_int 8))
9328 (xor:SI
9329 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9330 (match_dup 2)))]
9331 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 9332 "xor{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
9333 [(set_attr "type" "alu")
9334 (set_attr "mode" "QI")])
9076b9c1
JH
9335
9336(define_expand "xorqi_cc_ext_1"
9337 [(parallel [
8bc527af 9338 (set (reg:CCNO FLAGS_REG)
9076b9c1
JH
9339 (compare:CCNO
9340 (xor:SI
9341 (zero_extract:SI
9342 (match_operand 1 "ext_register_operand" "")
9343 (const_int 8)
9344 (const_int 8))
9345 (match_operand:QI 2 "general_operand" ""))
9346 (const_int 0)))
9347 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9348 (const_int 8)
9349 (const_int 8))
9350 (xor:SI
9351 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9352 (match_dup 2)))])]
9353 ""
9354 "")
2f41793e
JH
9355
9356(define_split
9357 [(set (match_operand 0 "register_operand" "")
9358 (xor (match_operand 1 "register_operand" "")
9359 (match_operand 2 "const_int_operand" "")))
8bc527af 9360 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
9361 "reload_completed
9362 && QI_REG_P (operands[0])
9363 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9364 && !(INTVAL (operands[2]) & ~(255 << 8))
9365 && GET_MODE (operands[0]) != QImode"
9366 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9367 (xor:SI (zero_extract:SI (match_dup 1)
9368 (const_int 8) (const_int 8))
9369 (match_dup 2)))
8bc527af 9370 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
9371 "operands[0] = gen_lowpart (SImode, operands[0]);
9372 operands[1] = gen_lowpart (SImode, operands[1]);
9373 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9374
9375;; Since XOR can be encoded with sign extended immediate, this is only
9376;; profitable when 7th bit is set.
9377(define_split
9378 [(set (match_operand 0 "register_operand" "")
9379 (xor (match_operand 1 "general_operand" "")
9380 (match_operand 2 "const_int_operand" "")))
8bc527af 9381 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
9382 "reload_completed
9383 && ANY_QI_REG_P (operands[0])
9384 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385 && !(INTVAL (operands[2]) & ~255)
9386 && (INTVAL (operands[2]) & 128)
9387 && GET_MODE (operands[0]) != QImode"
9388 [(parallel [(set (strict_low_part (match_dup 0))
9389 (xor:QI (match_dup 1)
9390 (match_dup 2)))
8bc527af 9391 (clobber (reg:CC FLAGS_REG))])]
2f41793e
JH
9392 "operands[0] = gen_lowpart (QImode, operands[0]);
9393 operands[1] = gen_lowpart (QImode, operands[1]);
9394 operands[2] = gen_lowpart (QImode, operands[2]);")
e075ae69
RH
9395\f
9396;; Negation instructions
57dbca5e 9397
06a964de
JH
9398(define_expand "negdi2"
9399 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2756c3d8 9400 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
8bc527af 9401 (clobber (reg:CC FLAGS_REG))])]
06a964de
JH
9402 ""
9403 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9404
9405(define_insn "*negdi2_1"
e075ae69
RH
9406 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9407 (neg:DI (match_operand:DI 1 "general_operand" "0")))
8bc527af 9408 (clobber (reg:CC FLAGS_REG))]
d2836273
JH
9409 "!TARGET_64BIT
9410 && ix86_unary_operator_ok (NEG, DImode, operands)"
e075ae69 9411 "#")
886c62d1 9412
e075ae69
RH
9413(define_split
9414 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9415 (neg:DI (match_operand:DI 1 "general_operand" "")))
8bc527af 9416 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 9417 "!TARGET_64BIT && reload_completed"
e075ae69 9418 [(parallel
8bc527af 9419 [(set (reg:CCZ FLAGS_REG)
16189740 9420 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
e075ae69
RH
9421 (set (match_dup 0) (neg:SI (match_dup 2)))])
9422 (parallel
9423 [(set (match_dup 1)
8bc527af 9424 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9dcbdc7e
JH
9425 (match_dup 3))
9426 (const_int 0)))
8bc527af 9427 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
9428 (parallel
9429 [(set (match_dup 1)
9430 (neg:SI (match_dup 1)))
8bc527af 9431 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
9432 "split_di (operands+1, 1, operands+2, operands+3);
9433 split_di (operands+0, 1, operands+0, operands+1);")
886c62d1 9434
9b70259d
JH
9435(define_insn "*negdi2_1_rex64"
9436 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9437 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
8bc527af 9438 (clobber (reg:CC FLAGS_REG))]
9b70259d 9439 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
0f40f9f7 9440 "neg{q}\t%0"
9b70259d
JH
9441 [(set_attr "type" "negnot")
9442 (set_attr "mode" "DI")])
9443
9444;; The problem with neg is that it does not perform (compare x 0),
9445;; it really performs (compare 0 x), which leaves us with the zero
9446;; flag being the only useful item.
9447
9448(define_insn "*negdi2_cmpz_rex64"
8bc527af 9449 [(set (reg:CCZ FLAGS_REG)
9b70259d
JH
9450 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9451 (const_int 0)))
9452 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9453 (neg:DI (match_dup 1)))]
9454 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
0f40f9f7 9455 "neg{q}\t%0"
9b70259d
JH
9456 [(set_attr "type" "negnot")
9457 (set_attr "mode" "DI")])
9458
9459
06a964de
JH
9460(define_expand "negsi2"
9461 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2756c3d8 9462 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
8bc527af 9463 (clobber (reg:CC FLAGS_REG))])]
06a964de
JH
9464 ""
9465 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9466
9467(define_insn "*negsi2_1"
2ae0f82c 9468 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 9469 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
8bc527af 9470 (clobber (reg:CC FLAGS_REG))]
06a964de 9471 "ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9472 "neg{l}\t%0"
6ef67412
JH
9473 [(set_attr "type" "negnot")
9474 (set_attr "mode" "SI")])
e075ae69 9475
9b70259d
JH
9476;; Combine is quite creative about this pattern.
9477(define_insn "*negsi2_1_zext"
9478 [(set (match_operand:DI 0 "register_operand" "=r")
9479 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9480 (const_int 32)))
9481 (const_int 32)))
8bc527af 9482 (clobber (reg:CC FLAGS_REG))]
9b70259d 9483 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9484 "neg{l}\t%k0"
9b70259d
JH
9485 [(set_attr "type" "negnot")
9486 (set_attr "mode" "SI")])
9487
16189740
RH
9488;; The problem with neg is that it does not perform (compare x 0),
9489;; it really performs (compare 0 x), which leaves us with the zero
9490;; flag being the only useful item.
e075ae69 9491
16189740 9492(define_insn "*negsi2_cmpz"
8bc527af 9493 [(set (reg:CCZ FLAGS_REG)
16189740
RH
9494 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9495 (const_int 0)))
e075ae69
RH
9496 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9497 (neg:SI (match_dup 1)))]
06a964de 9498 "ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9499 "neg{l}\t%0"
6ef67412
JH
9500 [(set_attr "type" "negnot")
9501 (set_attr "mode" "SI")])
886c62d1 9502
9b70259d 9503(define_insn "*negsi2_cmpz_zext"
8bc527af 9504 [(set (reg:CCZ FLAGS_REG)
9b70259d
JH
9505 (compare:CCZ (lshiftrt:DI
9506 (neg:DI (ashift:DI
9507 (match_operand:DI 1 "register_operand" "0")
9508 (const_int 32)))
9509 (const_int 32))
9510 (const_int 0)))
9511 (set (match_operand:DI 0 "register_operand" "=r")
9512 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9513 (const_int 32)))
9514 (const_int 32)))]
9515 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9516 "neg{l}\t%k0"
9b70259d
JH
9517 [(set_attr "type" "negnot")
9518 (set_attr "mode" "SI")])
9519
06a964de
JH
9520(define_expand "neghi2"
9521 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
2756c3d8 9522 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
8bc527af 9523 (clobber (reg:CC FLAGS_REG))])]
d9f32422 9524 "TARGET_HIMODE_MATH"
06a964de
JH
9525 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9526
9527(define_insn "*neghi2_1"
2ae0f82c 9528 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 9529 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
8bc527af 9530 (clobber (reg:CC FLAGS_REG))]
06a964de 9531 "ix86_unary_operator_ok (NEG, HImode, operands)"
0f40f9f7 9532 "neg{w}\t%0"
6ef67412
JH
9533 [(set_attr "type" "negnot")
9534 (set_attr "mode" "HI")])
e075ae69 9535
16189740 9536(define_insn "*neghi2_cmpz"
8bc527af 9537 [(set (reg:CCZ FLAGS_REG)
16189740
RH
9538 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9539 (const_int 0)))
e075ae69
RH
9540 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9541 (neg:HI (match_dup 1)))]
06a964de 9542 "ix86_unary_operator_ok (NEG, HImode, operands)"
0f40f9f7 9543 "neg{w}\t%0"
6ef67412
JH
9544 [(set_attr "type" "negnot")
9545 (set_attr "mode" "HI")])
886c62d1 9546
06a964de
JH
9547(define_expand "negqi2"
9548 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
2756c3d8 9549 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
8bc527af 9550 (clobber (reg:CC FLAGS_REG))])]
d9f32422 9551 "TARGET_QIMODE_MATH"
06a964de
JH
9552 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9553
9554(define_insn "*negqi2_1"
2ae0f82c 9555 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 9556 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
8bc527af 9557 (clobber (reg:CC FLAGS_REG))]
06a964de 9558 "ix86_unary_operator_ok (NEG, QImode, operands)"
0f40f9f7 9559 "neg{b}\t%0"
6ef67412
JH
9560 [(set_attr "type" "negnot")
9561 (set_attr "mode" "QI")])
e075ae69 9562
16189740 9563(define_insn "*negqi2_cmpz"
8bc527af 9564 [(set (reg:CCZ FLAGS_REG)
16189740
RH
9565 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9566 (const_int 0)))
e075ae69
RH
9567 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9568 (neg:QI (match_dup 1)))]
06a964de 9569 "ix86_unary_operator_ok (NEG, QImode, operands)"
0f40f9f7 9570 "neg{b}\t%0"
6ef67412
JH
9571 [(set_attr "type" "negnot")
9572 (set_attr "mode" "QI")])
886c62d1 9573
06a964de 9574;; Changing of sign for FP values is doable using integer unit too.
1ce485ec 9575
06a964de 9576(define_expand "negsf2"
7cacf53e
RH
9577 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9578 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9579 "TARGET_80387 || TARGET_SSE_MATH"
9580 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
b3298882 9581
7cacf53e
RH
9582(define_expand "abssf2"
9583 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9584 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9585 "TARGET_80387 || TARGET_SSE_MATH"
9586 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
b3298882 9587
7cacf53e
RH
9588(define_insn "*absnegsf2_mixed"
9589 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9590 (match_operator:SF 3 "absneg_operator"
9591 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#fr,0 ,0")]))
9592 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
8bc527af 9593 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9594 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9595 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
b3298882
JH
9596 "#")
9597
7cacf53e
RH
9598(define_insn "*absnegsf2_sse"
9599 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#r,x#r,rm#x")
9600 (match_operator:SF 3 "absneg_operator"
9601 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#r,0")]))
9602 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X"))
8bc527af 9603 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9604 "TARGET_SSE_MATH
9605 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9606 "#")
06a964de 9607
7cacf53e 9608(define_insn "*absnegsf2_i387"
e20440c1 9609 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
7cacf53e
RH
9610 (match_operator:SF 3 "absneg_operator"
9611 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9612 (use (match_operand 2 "" ""))
8bc527af 9613 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9614 "TARGET_80387 && !TARGET_SSE_MATH
9615 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
1ce485ec
JH
9616 "#")
9617
06a964de 9618(define_expand "negdf2"
7cacf53e
RH
9619 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9620 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9621 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9622 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
b3298882 9623
7cacf53e
RH
9624(define_expand "absdf2"
9625 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9626 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9627 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9628 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9629
9630(define_insn "*absnegdf2_mixed"
9631 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9632 (match_operator:DF 3 "absneg_operator"
9633 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#fr,0 ,0")]))
9634 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
8bc527af 9635 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9636 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9637 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
b3298882
JH
9638 "#")
9639
7cacf53e
RH
9640(define_insn "*absnegdf2_sse"
9641 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#r,Y#r,rm#Y")
9642 (match_operator:DF 3 "absneg_operator"
9643 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#r,0")]))
9644 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X"))
8bc527af 9645 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9646 "TARGET_SSE2 && TARGET_SSE_MATH
9647 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
141e454b
JH
9648 "#")
9649
7cacf53e
RH
9650(define_insn "*absnegdf2_i387"
9651 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9652 (match_operator:DF 3 "absneg_operator"
9653 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9654 (use (match_operand 2 "" ""))
8bc527af 9655 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9656 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9657 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
b3298882
JH
9658 "#")
9659
7cacf53e
RH
9660(define_expand "negxf2"
9661 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9662 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9663 "TARGET_80387"
9664 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
b3298882 9665
7cacf53e
RH
9666(define_expand "absxf2"
9667 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9668 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9669 "TARGET_80387"
9670 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9671
9672(define_insn "*absnegxf2_i387"
9673 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9674 (match_operator:XF 3 "absneg_operator"
9675 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9676 (use (match_operand 2 "" ""))
8bc527af 9677 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9678 "TARGET_80387
9679 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9680 "#")
9681
9682;; Splitters for fp abs and neg.
b3298882 9683
141e454b 9684(define_split
7cacf53e
RH
9685 [(set (match_operand 0 "fp_register_operand" "")
9686 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9687 (use (match_operand 2 "" ""))
8bc527af 9688 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9689 "reload_completed"
9690 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
141e454b 9691
b3298882 9692(define_split
7cacf53e
RH
9693 [(set (match_operand 0 "register_operand" "")
9694 (match_operator 3 "absneg_operator"
9695 [(match_operand 1 "register_operand" "")]))
9696 (use (match_operand 2 "nonimmediate_operand" ""))
8bc527af 9697 (clobber (reg:CC FLAGS_REG))]
b3298882 9698 "reload_completed && SSE_REG_P (operands[0])"
7cacf53e 9699 [(set (match_dup 0) (match_dup 3))]
b3298882 9700{
7cacf53e
RH
9701 enum machine_mode mode = GET_MODE (operands[0]);
9702 enum machine_mode vmode = GET_MODE (operands[2]);
9703 rtx tmp;
9704
9705 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9706 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
b3298882
JH
9707 if (operands_match_p (operands[0], operands[2]))
9708 {
b3298882
JH
9709 tmp = operands[1];
9710 operands[1] = operands[2];
9711 operands[2] = tmp;
9712 }
7cacf53e
RH
9713 if (GET_CODE (operands[3]) == ABS)
9714 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9715 else
9716 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9717 operands[3] = tmp;
0f40f9f7 9718})
06a964de 9719
1ce485ec 9720(define_split
7cacf53e
RH
9721 [(set (match_operand:SF 0 "register_operand" "")
9722 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9723 (use (match_operand:V4SF 2 "" ""))
8bc527af 9724 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9725 "reload_completed"
9726 [(parallel [(set (match_dup 0) (match_dup 1))
9727 (clobber (reg:CC FLAGS_REG))])]
9728{
9729 rtx tmp;
9730 operands[0] = gen_lowpart (SImode, operands[0]);
9731 if (GET_CODE (operands[1]) == ABS)
9732 {
9733 tmp = gen_int_mode (0x7fffffff, SImode);
9734 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9735 }
9736 else
9737 {
9738 tmp = gen_int_mode (0x80000000, SImode);
9739 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9740 }
9741 operands[1] = tmp;
9742})
1ce485ec
JH
9743
9744(define_split
7cacf53e
RH
9745 [(set (match_operand:DF 0 "register_operand" "")
9746 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9747 (use (match_operand 2 "" ""))
8bc527af 9748 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9749 "reload_completed"
9750 [(parallel [(set (match_dup 0) (match_dup 1))
8bc527af 9751 (clobber (reg:CC FLAGS_REG))])]
7cacf53e
RH
9752{
9753 rtx tmp;
9754 if (TARGET_64BIT)
9755 {
9756 tmp = gen_lowpart (DImode, operands[0]);
9757 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9758 operands[0] = tmp;
2b589241 9759
7cacf53e
RH
9760 if (GET_CODE (operands[1]) == ABS)
9761 tmp = const0_rtx;
9762 else
9763 tmp = gen_rtx_NOT (DImode, tmp);
9764 }
9765 else
9766 {
9767 operands[0] = gen_highpart (SImode, operands[0]);
9768 if (GET_CODE (operands[1]) == ABS)
9769 {
9770 tmp = gen_int_mode (0x7fffffff, SImode);
9771 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9772 }
9773 else
9774 {
9775 tmp = gen_int_mode (0x80000000, SImode);
9776 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9777 }
9778 }
9779 operands[1] = tmp;
9780})
1ce485ec
JH
9781
9782(define_split
7cacf53e
RH
9783 [(set (match_operand:XF 0 "register_operand" "")
9784 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9785 (use (match_operand 2 "" ""))
8bc527af 9786 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9787 "reload_completed"
9788 [(parallel [(set (match_dup 0) (match_dup 1))
9789 (clobber (reg:CC FLAGS_REG))])]
9790{
9791 rtx tmp;
9792 operands[0] = gen_rtx_REG (SImode,
9793 true_regnum (operands[0])
9794 + (TARGET_64BIT ? 1 : 2));
9795 if (GET_CODE (operands[1]) == ABS)
9796 {
9797 tmp = GEN_INT (0x7fff);
9798 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9799 }
9800 else
9801 {
9802 tmp = GEN_INT (0x8000);
9803 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9804 }
9805 operands[1] = tmp;
9806})
1ce485ec
JH
9807
9808(define_split
7cacf53e
RH
9809 [(set (match_operand 0 "memory_operand" "")
9810 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9811 (use (match_operand 2 "" ""))
8bc527af 9812 (clobber (reg:CC FLAGS_REG))]
7cacf53e
RH
9813 "reload_completed"
9814 [(parallel [(set (match_dup 0) (match_dup 1))
8bc527af 9815 (clobber (reg:CC FLAGS_REG))])]
7cacf53e
RH
9816{
9817 enum machine_mode mode = GET_MODE (operands[0]);
9818 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9819 rtx tmp;
9820
9821 operands[0] = adjust_address (operands[0], QImode, size - 1);
9822 if (GET_CODE (operands[1]) == ABS)
9823 {
9824 tmp = gen_int_mode (0x7f, QImode);
9825 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9826 }
9827 else
9828 {
9829 tmp = gen_int_mode (0x80, QImode);
9830 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9831 }
9832 operands[1] = tmp;
9833})
1ce485ec 9834
7cacf53e 9835;; Conditionalize these after reload. If they match before reload, we
1ce485ec
JH
9836;; lose the clobber and ability to use integer instructions.
9837
9838(define_insn "*negsf2_1"
886c62d1 9839 [(set (match_operand:SF 0 "register_operand" "=f")
2ae0f82c 9840 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1ce485ec 9841 "TARGET_80387 && reload_completed"
10195bd8 9842 "fchs"
e075ae69 9843 [(set_attr "type" "fsgn")
56bab446 9844 (set_attr "mode" "SF")])
886c62d1 9845
1ce485ec 9846(define_insn "*negdf2_1"
886c62d1 9847 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 9848 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
1ce485ec 9849 "TARGET_80387 && reload_completed"
10195bd8 9850 "fchs"
e075ae69 9851 [(set_attr "type" "fsgn")
56bab446 9852 (set_attr "mode" "DF")])
886c62d1 9853
7cacf53e
RH
9854(define_insn "*negxf2_1"
9855 [(set (match_operand:XF 0 "register_operand" "=f")
9856 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9857 "TARGET_80387 && reload_completed"
10195bd8 9858 "fchs"
7cacf53e
RH
9859 [(set_attr "type" "fsgn")
9860 (set_attr "mode" "XF")])
9861
9862(define_insn "*abssf2_1"
9863 [(set (match_operand:SF 0 "register_operand" "=f")
9864 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9865 "TARGET_80387 && reload_completed"
9866 "fabs"
9867 [(set_attr "type" "fsgn")
9868 (set_attr "mode" "SF")])
9869
9870(define_insn "*absdf2_1"
9871 [(set (match_operand:DF 0 "register_operand" "=f")
9872 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9873 "TARGET_80387 && reload_completed"
9874 "fabs"
e075ae69 9875 [(set_attr "type" "fsgn")
56bab446 9876 (set_attr "mode" "DF")])
4fb21e90 9877
7cacf53e 9878(define_insn "*absxf2_1"
4fb21e90 9879 [(set (match_operand:XF 0 "register_operand" "=f")
7cacf53e 9880 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
f8a1ebc6 9881 "TARGET_80387 && reload_completed"
7cacf53e
RH
9882 "fabs"
9883 [(set_attr "type" "fsgn")
9884 (set_attr "mode" "DF")])
9885
9886(define_insn "*negextendsfdf2"
9887 [(set (match_operand:DF 0 "register_operand" "=f")
9888 (neg:DF (float_extend:DF
9889 (match_operand:SF 1 "register_operand" "0"))))]
9890 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10195bd8 9891 "fchs"
e075ae69 9892 [(set_attr "type" "fsgn")
7cacf53e 9893 (set_attr "mode" "DF")])
e075ae69 9894
6343a50e 9895(define_insn "*negextenddfxf2"
e075ae69
RH
9896 [(set (match_operand:XF 0 "register_operand" "=f")
9897 (neg:XF (float_extend:XF
9898 (match_operand:DF 1 "register_operand" "0"))))]
f8a1ebc6 9899 "TARGET_80387"
e075ae69
RH
9900 "fchs"
9901 [(set_attr "type" "fsgn")
56bab446 9902 (set_attr "mode" "XF")])
4fb21e90 9903
6343a50e 9904(define_insn "*negextendsfxf2"
4fb21e90 9905 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
9906 (neg:XF (float_extend:XF
9907 (match_operand:SF 1 "register_operand" "0"))))]
2b589241
JH
9908 "TARGET_80387"
9909 "fchs"
9910 [(set_attr "type" "fsgn")
56bab446 9911 (set_attr "mode" "XF")])
886c62d1 9912
6343a50e 9913(define_insn "*absextendsfdf2"
886c62d1 9914 [(set (match_operand:DF 0 "register_operand" "=f")
e075ae69
RH
9915 (abs:DF (float_extend:DF
9916 (match_operand:SF 1 "register_operand" "0"))))]
7cacf53e 9917 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
2ae0f82c 9918 "fabs"
6ef67412
JH
9919 [(set_attr "type" "fsgn")
9920 (set_attr "mode" "DF")])
4fb21e90 9921
6343a50e 9922(define_insn "*absextenddfxf2"
4fb21e90 9923 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
9924 (abs:XF (float_extend:XF
9925 (match_operand:DF 1 "register_operand" "0"))))]
f8a1ebc6 9926 "TARGET_80387"
2ae0f82c 9927 "fabs"
6ef67412
JH
9928 [(set_attr "type" "fsgn")
9929 (set_attr "mode" "XF")])
a199fdd6 9930
6343a50e 9931(define_insn "*absextendsfxf2"
58733f96 9932 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
9933 (abs:XF (float_extend:XF
9934 (match_operand:SF 1 "register_operand" "0"))))]
2b589241
JH
9935 "TARGET_80387"
9936 "fabs"
9937 [(set_attr "type" "fsgn")
9938 (set_attr "mode" "XF")])
886c62d1 9939\f
e075ae69 9940;; One complement instructions
886c62d1 9941
9b70259d
JH
9942(define_expand "one_cmpldi2"
9943 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9944 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9945 "TARGET_64BIT"
9946 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9947
9948(define_insn "*one_cmpldi2_1_rex64"
9949 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9950 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9951 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
0f40f9f7 9952 "not{q}\t%0"
9b70259d
JH
9953 [(set_attr "type" "negnot")
9954 (set_attr "mode" "DI")])
9955
9956(define_insn "*one_cmpldi2_2_rex64"
42fabf21 9957 [(set (reg FLAGS_REG)
9b70259d
JH
9958 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9959 (const_int 0)))
9960 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9961 (not:DI (match_dup 1)))]
9962 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9963 && ix86_unary_operator_ok (NOT, DImode, operands)"
9964 "#"
9965 [(set_attr "type" "alu1")
9966 (set_attr "mode" "DI")])
9967
9968(define_split
25da5dc7
RH
9969 [(set (match_operand 0 "flags_reg_operand" "")
9970 (match_operator 2 "compare_operator"
9971 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9972 (const_int 0)]))
9973 (set (match_operand:DI 1 "nonimmediate_operand" "")
9974 (not:DI (match_dup 3)))]
9b70259d 9975 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
9976 [(parallel [(set (match_dup 0)
9977 (match_op_dup 2
9978 [(xor:DI (match_dup 3) (const_int -1))
9979 (const_int 0)]))
9980 (set (match_dup 1)
9981 (xor:DI (match_dup 3) (const_int -1)))])]
9b70259d
JH
9982 "")
9983
06a964de 9984(define_expand "one_cmplsi2"
a1cbdd7f
JH
9985 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9986 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
06a964de
JH
9987 ""
9988 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9989
9990(define_insn "*one_cmplsi2_1"
2ae0f82c
SC
9991 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9992 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
a1cbdd7f 9993 "ix86_unary_operator_ok (NOT, SImode, operands)"
0f40f9f7 9994 "not{l}\t%0"
6ef67412
JH
9995 [(set_attr "type" "negnot")
9996 (set_attr "mode" "SI")])
bb524860 9997
9b70259d
JH
9998;; ??? Currently never generated - xor is used instead.
9999(define_insn "*one_cmplsi2_1_zext"
10000 [(set (match_operand:DI 0 "register_operand" "=r")
10001 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10002 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
0f40f9f7 10003 "not{l}\t%k0"
9b70259d
JH
10004 [(set_attr "type" "negnot")
10005 (set_attr "mode" "SI")])
10006
06a964de 10007(define_insn "*one_cmplsi2_2"
42fabf21 10008 [(set (reg FLAGS_REG)
16189740
RH
10009 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10010 (const_int 0)))
e075ae69
RH
10011 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10012 (not:SI (match_dup 1)))]
16189740
RH
10013 "ix86_match_ccmode (insn, CCNOmode)
10014 && ix86_unary_operator_ok (NOT, SImode, operands)"
e075ae69 10015 "#"
6ef67412
JH
10016 [(set_attr "type" "alu1")
10017 (set_attr "mode" "SI")])
e075ae69
RH
10018
10019(define_split
25da5dc7
RH
10020 [(set (match_operand 0 "flags_reg_operand" "")
10021 (match_operator 2 "compare_operator"
10022 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10023 (const_int 0)]))
10024 (set (match_operand:SI 1 "nonimmediate_operand" "")
10025 (not:SI (match_dup 3)))]
16189740 10026 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
10027 [(parallel [(set (match_dup 0)
10028 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10029 (const_int 0)]))
10030 (set (match_dup 1)
10031 (xor:SI (match_dup 3) (const_int -1)))])]
e075ae69 10032 "")
886c62d1 10033
9b70259d
JH
10034;; ??? Currently never generated - xor is used instead.
10035(define_insn "*one_cmplsi2_2_zext"
42fabf21 10036 [(set (reg FLAGS_REG)
9b70259d
JH
10037 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10038 (const_int 0)))
10039 (set (match_operand:DI 0 "register_operand" "=r")
10040 (zero_extend:DI (not:SI (match_dup 1))))]
10041 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10042 && ix86_unary_operator_ok (NOT, SImode, operands)"
10043 "#"
10044 [(set_attr "type" "alu1")
10045 (set_attr "mode" "SI")])
10046
10047(define_split
25da5dc7
RH
10048 [(set (match_operand 0 "flags_reg_operand" "")
10049 (match_operator 2 "compare_operator"
10050 [(not:SI (match_operand:SI 3 "register_operand" ""))
10051 (const_int 0)]))
10052 (set (match_operand:DI 1 "register_operand" "")
10053 (zero_extend:DI (not:SI (match_dup 3))))]
9b70259d 10054 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
10055 [(parallel [(set (match_dup 0)
10056 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10057 (const_int 0)]))
10058 (set (match_dup 1)
10059 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9b70259d
JH
10060 "")
10061
06a964de 10062(define_expand "one_cmplhi2"
a1cbdd7f
JH
10063 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10064 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
d9f32422 10065 "TARGET_HIMODE_MATH"
06a964de
JH
10066 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10067
10068(define_insn "*one_cmplhi2_1"
2ae0f82c
SC
10069 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10070 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
a1cbdd7f 10071 "ix86_unary_operator_ok (NOT, HImode, operands)"
0f40f9f7 10072 "not{w}\t%0"
6ef67412
JH
10073 [(set_attr "type" "negnot")
10074 (set_attr "mode" "HI")])
bb524860 10075
06a964de 10076(define_insn "*one_cmplhi2_2"
42fabf21 10077 [(set (reg FLAGS_REG)
16189740
RH
10078 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10079 (const_int 0)))
e075ae69
RH
10080 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10081 (not:HI (match_dup 1)))]
16189740
RH
10082 "ix86_match_ccmode (insn, CCNOmode)
10083 && ix86_unary_operator_ok (NEG, HImode, operands)"
e075ae69 10084 "#"
6ef67412
JH
10085 [(set_attr "type" "alu1")
10086 (set_attr "mode" "HI")])
e075ae69
RH
10087
10088(define_split
25da5dc7
RH
10089 [(set (match_operand 0 "flags_reg_operand" "")
10090 (match_operator 2 "compare_operator"
10091 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10092 (const_int 0)]))
10093 (set (match_operand:HI 1 "nonimmediate_operand" "")
10094 (not:HI (match_dup 3)))]
16189740 10095 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
10096 [(parallel [(set (match_dup 0)
10097 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10098 (const_int 0)]))
10099 (set (match_dup 1)
10100 (xor:HI (match_dup 3) (const_int -1)))])]
e075ae69 10101 "")
886c62d1 10102
e075ae69 10103;; %%% Potential partial reg stall on alternative 1. What to do?
06a964de 10104(define_expand "one_cmplqi2"
a1cbdd7f
JH
10105 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10106 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
d9f32422 10107 "TARGET_QIMODE_MATH"
06a964de
JH
10108 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10109
10110(define_insn "*one_cmplqi2_1"
7c6b971d 10111 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
e075ae69 10112 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
a1cbdd7f 10113 "ix86_unary_operator_ok (NOT, QImode, operands)"
e075ae69 10114 "@
0f40f9f7
ZW
10115 not{b}\t%0
10116 not{l}\t%k0"
6ef67412
JH
10117 [(set_attr "type" "negnot")
10118 (set_attr "mode" "QI,SI")])
bb524860 10119
06a964de 10120(define_insn "*one_cmplqi2_2"
42fabf21 10121 [(set (reg FLAGS_REG)
16189740
RH
10122 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10123 (const_int 0)))
e075ae69
RH
10124 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10125 (not:QI (match_dup 1)))]
16189740
RH
10126 "ix86_match_ccmode (insn, CCNOmode)
10127 && ix86_unary_operator_ok (NOT, QImode, operands)"
e075ae69 10128 "#"
6ef67412
JH
10129 [(set_attr "type" "alu1")
10130 (set_attr "mode" "QI")])
e075ae69
RH
10131
10132(define_split
25da5dc7
RH
10133 [(set (match_operand 0 "flags_reg_operand" "")
10134 (match_operator 2 "compare_operator"
10135 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10136 (const_int 0)]))
10137 (set (match_operand:QI 1 "nonimmediate_operand" "")
10138 (not:QI (match_dup 3)))]
16189740 10139 "ix86_match_ccmode (insn, CCNOmode)"
25da5dc7
RH
10140 [(parallel [(set (match_dup 0)
10141 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10142 (const_int 0)]))
10143 (set (match_dup 1)
10144 (xor:QI (match_dup 3) (const_int -1)))])]
e075ae69 10145 "")
886c62d1 10146\f
e075ae69 10147;; Arithmetic shift instructions
886c62d1
JVA
10148
10149;; DImode shifts are implemented using the i386 "shift double" opcode,
10150;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10151;; is variable, then the count is in %cl and the "imm" operand is dropped
10152;; from the assembler input.
e075ae69 10153;;
886c62d1
JVA
10154;; This instruction shifts the target reg/mem as usual, but instead of
10155;; shifting in zeros, bits are shifted in from reg operand. If the insn
10156;; is a left shift double, bits are taken from the high order bits of
10157;; reg, else if the insn is a shift right double, bits are taken from the
10158;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10159;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
e075ae69 10160;;
886c62d1
JVA
10161;; Since sh[lr]d does not change the `reg' operand, that is done
10162;; separately, making all shifts emit pairs of shift double and normal
10163;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10164;; support a 63 bit shift, each shift where the count is in a reg expands
f58acb67 10165;; to a pair of shifts, a branch, a shift by 32 and a label.
e075ae69 10166;;
886c62d1
JVA
10167;; If the shift count is a constant, we need never emit more than one
10168;; shift pair, instead using moves and sign extension for counts greater
10169;; than 31.
10170
56c0e8fa 10171(define_expand "ashldi3"
93330ea1
RH
10172 [(set (match_operand:DI 0 "shiftdi_operand" "")
10173 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10174 (match_operand:QI 2 "nonmemory_operand" "")))]
56c0e8fa 10175 ""
93330ea1 10176 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
56c0e8fa 10177
371bc54b
JH
10178(define_insn "*ashldi3_1_rex64"
10179 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9a9286af 10180 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
7c17f553 10181 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
8bc527af 10182 (clobber (reg:CC FLAGS_REG))]
371bc54b 10183 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
371bc54b
JH
10184{
10185 switch (get_attr_type (insn))
10186 {
10187 case TYPE_ALU:
10188 if (operands[2] != const1_rtx)
10189 abort ();
10190 if (!rtx_equal_p (operands[0], operands[1]))
10191 abort ();
0f40f9f7 10192 return "add{q}\t{%0, %0|%0, %0}";
371bc54b
JH
10193
10194 case TYPE_LEA:
10195 if (GET_CODE (operands[2]) != CONST_INT
10196 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10197 abort ();
10198 operands[1] = gen_rtx_MULT (DImode, operands[1],
10199 GEN_INT (1 << INTVAL (operands[2])));
0f40f9f7 10200 return "lea{q}\t{%a1, %0|%0, %a1}";
371bc54b
JH
10201
10202 default:
10203 if (REG_P (operands[2]))
0f40f9f7 10204 return "sal{q}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10205 else if (operands[2] == const1_rtx
495333a6 10206 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10207 return "sal{q}\t%0";
371bc54b 10208 else
0f40f9f7 10209 return "sal{q}\t{%2, %0|%0, %2}";
371bc54b 10210 }
0f40f9f7 10211}
371bc54b
JH
10212 [(set (attr "type")
10213 (cond [(eq_attr "alternative" "1")
10214 (const_string "lea")
10215 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10216 (const_int 0))
10217 (match_operand 0 "register_operand" ""))
10218 (match_operand 2 "const1_operand" ""))
10219 (const_string "alu")
10220 ]
10221 (const_string "ishift")))
10222 (set_attr "mode" "DI")])
10223
10224;; Convert lea to the lea pattern to avoid flags dependency.
10225(define_split
10226 [(set (match_operand:DI 0 "register_operand" "")
9a9286af 10227 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
371bc54b 10228 (match_operand:QI 2 "immediate_operand" "")))
8bc527af 10229 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 10230 "TARGET_64BIT && reload_completed
371bc54b
JH
10231 && true_regnum (operands[0]) != true_regnum (operands[1])"
10232 [(set (match_dup 0)
10233 (mult:DI (match_dup 1)
10234 (match_dup 2)))]
d8bf17f9 10235 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
371bc54b
JH
10236
10237;; This pattern can't accept a variable shift count, since shifts by
10238;; zero don't affect the flags. We assume that shifts by constant
10239;; zero are optimized away.
10240(define_insn "*ashldi3_cmp_rex64"
42fabf21 10241 [(set (reg FLAGS_REG)
371bc54b
JH
10242 (compare
10243 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10244 (match_operand:QI 2 "immediate_operand" "e"))
10245 (const_int 0)))
10246 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10247 (ashift:DI (match_dup 1) (match_dup 2)))]
10248 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10249 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
371bc54b
JH
10250{
10251 switch (get_attr_type (insn))
10252 {
10253 case TYPE_ALU:
10254 if (operands[2] != const1_rtx)
10255 abort ();
0f40f9f7 10256 return "add{q}\t{%0, %0|%0, %0}";
371bc54b
JH
10257
10258 default:
10259 if (REG_P (operands[2]))
0f40f9f7 10260 return "sal{q}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10261 else if (operands[2] == const1_rtx
495333a6 10262 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10263 return "sal{q}\t%0";
371bc54b 10264 else
0f40f9f7 10265 return "sal{q}\t{%2, %0|%0, %2}";
371bc54b 10266 }
0f40f9f7 10267}
371bc54b
JH
10268 [(set (attr "type")
10269 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10270 (const_int 0))
10271 (match_operand 0 "register_operand" ""))
10272 (match_operand 2 "const1_operand" ""))
10273 (const_string "alu")
10274 ]
10275 (const_string "ishift")))
10276 (set_attr "mode" "DI")])
10277
93330ea1
RH
10278(define_insn "*ashldi3_1"
10279 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10280 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10281 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
8bc527af 10282 (clobber (reg:CC FLAGS_REG))]
371bc54b 10283 "!TARGET_64BIT"
e075ae69
RH
10284 "#"
10285 [(set_attr "type" "multi")])
886c62d1 10286
93330ea1
RH
10287;; By default we don't ask for a scratch register, because when DImode
10288;; values are manipulated, registers are already at a premium. But if
10289;; we have one handy, we won't turn it away.
10290(define_peephole2
10291 [(match_scratch:SI 3 "r")
10292 (parallel [(set (match_operand:DI 0 "register_operand" "")
10293 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10294 (match_operand:QI 2 "nonmemory_operand" "")))
10295 (clobber (reg:CC FLAGS_REG))])
10296 (match_dup 3)]
10297 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69
RH
10298 [(const_int 0)]
10299 "ix86_split_ashldi (operands, operands[3]); DONE;")
47f59fd4 10300
e075ae69
RH
10301(define_split
10302 [(set (match_operand:DI 0 "register_operand" "")
93330ea1 10303 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
e075ae69 10304 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 10305 (clobber (reg:CC FLAGS_REG))]
93330ea1 10306 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
e075ae69
RH
10307 [(const_int 0)]
10308 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
6ec6d558 10309
e075ae69
RH
10310(define_insn "x86_shld_1"
10311 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10312 (ior:SI (ashift:SI (match_dup 0)
10313 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10314 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10315 (minus:QI (const_int 32) (match_dup 2)))))
8bc527af 10316 (clobber (reg:CC FLAGS_REG))]
6ec6d558 10317 ""
e075ae69 10318 "@
0f40f9f7
ZW
10319 shld{l}\t{%2, %1, %0|%0, %1, %2}
10320 shld{l}\t{%s2%1, %0|%0, %1, %2}"
e075ae69 10321 [(set_attr "type" "ishift")
6ef67412
JH
10322 (set_attr "prefix_0f" "1")
10323 (set_attr "mode" "SI")
e075ae69 10324 (set_attr "pent_pair" "np")
56bab446 10325 (set_attr "athlon_decode" "vector")])
e075ae69
RH
10326
10327(define_expand "x86_shift_adj_1"
8bc527af 10328 [(set (reg:CCZ FLAGS_REG)
16189740
RH
10329 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10330 (const_int 32))
10331 (const_int 0)))
e075ae69 10332 (set (match_operand:SI 0 "register_operand" "")
8bc527af 10333 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
e075ae69
RH
10334 (match_operand:SI 1 "register_operand" "")
10335 (match_dup 0)))
10336 (set (match_dup 1)
8bc527af 10337 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
e075ae69
RH
10338 (match_operand:SI 3 "register_operand" "r")
10339 (match_dup 1)))]
10340 "TARGET_CMOVE"
6ec6d558
JH
10341 "")
10342
e075ae69
RH
10343(define_expand "x86_shift_adj_2"
10344 [(use (match_operand:SI 0 "register_operand" ""))
10345 (use (match_operand:SI 1 "register_operand" ""))
10346 (use (match_operand:QI 2 "register_operand" ""))]
886c62d1 10347 ""
e075ae69
RH
10348{
10349 rtx label = gen_label_rtx ();
10350 rtx tmp;
886c62d1 10351
16189740 10352 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
886c62d1 10353
16189740 10354 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
10355 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10356 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10357 gen_rtx_LABEL_REF (VOIDmode, label),
10358 pc_rtx);
10359 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10360 JUMP_LABEL (tmp) = label;
886c62d1 10361
e075ae69 10362 emit_move_insn (operands[0], operands[1]);
93330ea1 10363 ix86_expand_clear (operands[1]);
886c62d1 10364
e075ae69
RH
10365 emit_label (label);
10366 LABEL_NUSES (label) = 1;
56c0e8fa
JVA
10367
10368 DONE;
0f40f9f7 10369})
56c0e8fa 10370
d525dfdf
JH
10371(define_expand "ashlsi3"
10372 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10373 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10374 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 10375 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
10376 ""
10377 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10378
10379(define_insn "*ashlsi3_1"
e075ae69 10380 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9a9286af 10381 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
e075ae69 10382 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8bc527af 10383 (clobber (reg:CC FLAGS_REG))]
d525dfdf 10384 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
2ae0f82c 10385{
e075ae69
RH
10386 switch (get_attr_type (insn))
10387 {
10388 case TYPE_ALU:
10389 if (operands[2] != const1_rtx)
10390 abort ();
10391 if (!rtx_equal_p (operands[0], operands[1]))
10392 abort ();
0f40f9f7 10393 return "add{l}\t{%0, %0|%0, %0}";
2ae0f82c 10394
e075ae69 10395 case TYPE_LEA:
0f40f9f7 10396 return "#";
2ae0f82c 10397
e075ae69
RH
10398 default:
10399 if (REG_P (operands[2]))
0f40f9f7 10400 return "sal{l}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10401 else if (operands[2] == const1_rtx
495333a6 10402 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10403 return "sal{l}\t%0";
e075ae69 10404 else
0f40f9f7 10405 return "sal{l}\t{%2, %0|%0, %2}";
e075ae69 10406 }
0f40f9f7 10407}
e075ae69
RH
10408 [(set (attr "type")
10409 (cond [(eq_attr "alternative" "1")
10410 (const_string "lea")
10411 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10412 (const_int 0))
10413 (match_operand 0 "register_operand" ""))
10414 (match_operand 2 "const1_operand" ""))
10415 (const_string "alu")
10416 ]
6ef67412
JH
10417 (const_string "ishift")))
10418 (set_attr "mode" "SI")])
e075ae69 10419
1c27d4b2
JH
10420;; Convert lea to the lea pattern to avoid flags dependency.
10421(define_split
58787064 10422 [(set (match_operand 0 "register_operand" "")
7ec70495 10423 (ashift (match_operand 1 "index_register_operand" "")
ca4ae08d 10424 (match_operand:QI 2 "const_int_operand" "")))
8bc527af 10425 (clobber (reg:CC FLAGS_REG))]
abe24fb3 10426 "reload_completed
9a9286af
RH
10427 && true_regnum (operands[0]) != true_regnum (operands[1])
10428 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
58787064 10429 [(const_int 0)]
58787064
JH
10430{
10431 rtx pat;
9a9286af
RH
10432 enum machine_mode mode = GET_MODE (operands[0]);
10433
10434 if (GET_MODE_SIZE (mode) < 4)
10435 operands[0] = gen_lowpart (SImode, operands[0]);
10436 if (mode != Pmode)
10437 operands[1] = gen_lowpart (Pmode, operands[1]);
d8bf17f9 10438 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9a9286af 10439
58787064
JH
10440 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10441 if (Pmode != SImode)
10442 pat = gen_rtx_SUBREG (SImode, pat, 0);
10443 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10444 DONE;
0f40f9f7 10445})
1c27d4b2 10446
7ec70495
JH
10447;; Rare case of shifting RSP is handled by generating move and shift
10448(define_split
10449 [(set (match_operand 0 "register_operand" "")
10450 (ashift (match_operand 1 "register_operand" "")
10451 (match_operand:QI 2 "const_int_operand" "")))
8bc527af 10452 (clobber (reg:CC FLAGS_REG))]
7ec70495
JH
10453 "reload_completed
10454 && true_regnum (operands[0]) != true_regnum (operands[1])"
10455 [(const_int 0)]
10456{
10457 rtx pat, clob;
10458 emit_move_insn (operands[1], operands[0]);
10459 pat = gen_rtx_SET (VOIDmode, operands[0],
10460 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10461 operands[0], operands[2]));
10462 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10463 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10464 DONE;
10465})
10466
371bc54b
JH
10467(define_insn "*ashlsi3_1_zext"
10468 [(set (match_operand:DI 0 "register_operand" "=r,r")
9a9286af 10469 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
371bc54b 10470 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
8bc527af 10471 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 10472 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
371bc54b
JH
10473{
10474 switch (get_attr_type (insn))
10475 {
10476 case TYPE_ALU:
10477 if (operands[2] != const1_rtx)
10478 abort ();
0f40f9f7 10479 return "add{l}\t{%k0, %k0|%k0, %k0}";
371bc54b
JH
10480
10481 case TYPE_LEA:
0f40f9f7 10482 return "#";
371bc54b
JH
10483
10484 default:
10485 if (REG_P (operands[2]))
0f40f9f7 10486 return "sal{l}\t{%b2, %k0|%k0, %b2}";
b4e0dd8e 10487 else if (operands[2] == const1_rtx
495333a6 10488 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10489 return "sal{l}\t%k0";
371bc54b 10490 else
0f40f9f7 10491 return "sal{l}\t{%2, %k0|%k0, %2}";
371bc54b 10492 }
0f40f9f7 10493}
371bc54b
JH
10494 [(set (attr "type")
10495 (cond [(eq_attr "alternative" "1")
10496 (const_string "lea")
10497 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10498 (const_int 0))
10499 (match_operand 2 "const1_operand" ""))
10500 (const_string "alu")
10501 ]
10502 (const_string "ishift")))
10503 (set_attr "mode" "SI")])
10504
10505;; Convert lea to the lea pattern to avoid flags dependency.
10506(define_split
10507 [(set (match_operand:DI 0 "register_operand" "")
10508 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10509 (match_operand:QI 2 "const_int_operand" ""))))
8bc527af 10510 (clobber (reg:CC FLAGS_REG))]
bc8a6d63 10511 "TARGET_64BIT && reload_completed
371bc54b 10512 && true_regnum (operands[0]) != true_regnum (operands[1])"
bc8a6d63
RH
10513 [(set (match_dup 0) (zero_extend:DI
10514 (subreg:SI (mult:SI (match_dup 1)
10515 (match_dup 2)) 0)))]
371bc54b
JH
10516{
10517 operands[1] = gen_lowpart (Pmode, operands[1]);
d8bf17f9 10518 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
0f40f9f7 10519})
371bc54b 10520
28cefcd2
BS
10521;; This pattern can't accept a variable shift count, since shifts by
10522;; zero don't affect the flags. We assume that shifts by constant
10523;; zero are optimized away.
2c873473 10524(define_insn "*ashlsi3_cmp"
42fabf21 10525 [(set (reg FLAGS_REG)
16189740 10526 (compare
e075ae69 10527 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
ef719a44 10528 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69
RH
10529 (const_int 0)))
10530 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10531 (ashift:SI (match_dup 1) (match_dup 2)))]
9076b9c1 10532 "ix86_match_ccmode (insn, CCGOCmode)
16189740 10533 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
886c62d1 10534{
e075ae69 10535 switch (get_attr_type (insn))
886c62d1 10536 {
e075ae69
RH
10537 case TYPE_ALU:
10538 if (operands[2] != const1_rtx)
10539 abort ();
0f40f9f7 10540 return "add{l}\t{%0, %0|%0, %0}";
886c62d1 10541
e075ae69
RH
10542 default:
10543 if (REG_P (operands[2]))
0f40f9f7 10544 return "sal{l}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10545 else if (operands[2] == const1_rtx
495333a6 10546 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10547 return "sal{l}\t%0";
e075ae69 10548 else
0f40f9f7 10549 return "sal{l}\t{%2, %0|%0, %2}";
56c0e8fa 10550 }
0f40f9f7 10551}
e075ae69
RH
10552 [(set (attr "type")
10553 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10554 (const_int 0))
10555 (match_operand 0 "register_operand" ""))
10556 (match_operand 2 "const1_operand" ""))
10557 (const_string "alu")
10558 ]
6ef67412
JH
10559 (const_string "ishift")))
10560 (set_attr "mode" "SI")])
e075ae69 10561
371bc54b 10562(define_insn "*ashlsi3_cmp_zext"
42fabf21 10563 [(set (reg FLAGS_REG)
371bc54b
JH
10564 (compare
10565 (ashift:SI (match_operand:SI 1 "register_operand" "0")
ef719a44 10566 (match_operand:QI 2 "const_1_to_31_operand" "I"))
371bc54b
JH
10567 (const_int 0)))
10568 (set (match_operand:DI 0 "register_operand" "=r")
10569 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10570 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10571 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
371bc54b
JH
10572{
10573 switch (get_attr_type (insn))
10574 {
10575 case TYPE_ALU:
10576 if (operands[2] != const1_rtx)
10577 abort ();
0f40f9f7 10578 return "add{l}\t{%k0, %k0|%k0, %k0}";
371bc54b
JH
10579
10580 default:
10581 if (REG_P (operands[2]))
0f40f9f7 10582 return "sal{l}\t{%b2, %k0|%k0, %b2}";
b4e0dd8e 10583 else if (operands[2] == const1_rtx
495333a6 10584 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10585 return "sal{l}\t%k0";
371bc54b 10586 else
0f40f9f7 10587 return "sal{l}\t{%2, %k0|%k0, %2}";
371bc54b 10588 }
0f40f9f7 10589}
371bc54b
JH
10590 [(set (attr "type")
10591 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10592 (const_int 0))
10593 (match_operand 2 "const1_operand" ""))
10594 (const_string "alu")
10595 ]
10596 (const_string "ishift")))
10597 (set_attr "mode" "SI")])
10598
d525dfdf
JH
10599(define_expand "ashlhi3"
10600 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10601 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10602 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 10603 (clobber (reg:CC FLAGS_REG))]
d9f32422 10604 "TARGET_HIMODE_MATH"
d525dfdf
JH
10605 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10606
58787064
JH
10607(define_insn "*ashlhi3_1_lea"
10608 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9a9286af 10609 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
58787064 10610 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8bc527af 10611 (clobber (reg:CC FLAGS_REG))]
58787064
JH
10612 "!TARGET_PARTIAL_REG_STALL
10613 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
58787064
JH
10614{
10615 switch (get_attr_type (insn))
10616 {
10617 case TYPE_LEA:
0f40f9f7 10618 return "#";
58787064
JH
10619 case TYPE_ALU:
10620 if (operands[2] != const1_rtx)
10621 abort ();
0f40f9f7 10622 return "add{w}\t{%0, %0|%0, %0}";
58787064
JH
10623
10624 default:
10625 if (REG_P (operands[2]))
0f40f9f7 10626 return "sal{w}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10627 else if (operands[2] == const1_rtx
495333a6 10628 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10629 return "sal{w}\t%0";
58787064 10630 else
0f40f9f7 10631 return "sal{w}\t{%2, %0|%0, %2}";
58787064 10632 }
0f40f9f7 10633}
58787064
JH
10634 [(set (attr "type")
10635 (cond [(eq_attr "alternative" "1")
10636 (const_string "lea")
10637 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10638 (const_int 0))
10639 (match_operand 0 "register_operand" ""))
10640 (match_operand 2 "const1_operand" ""))
10641 (const_string "alu")
10642 ]
10643 (const_string "ishift")))
10644 (set_attr "mode" "HI,SI")])
10645
d525dfdf 10646(define_insn "*ashlhi3_1"
e075ae69
RH
10647 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10648 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10649 (match_operand:QI 2 "nonmemory_operand" "cI")))
8bc527af 10650 (clobber (reg:CC FLAGS_REG))]
58787064
JH
10651 "TARGET_PARTIAL_REG_STALL
10652 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
56c0e8fa 10653{
e075ae69
RH
10654 switch (get_attr_type (insn))
10655 {
10656 case TYPE_ALU:
10657 if (operands[2] != const1_rtx)
10658 abort ();
0f40f9f7 10659 return "add{w}\t{%0, %0|%0, %0}";
886c62d1 10660
e075ae69
RH
10661 default:
10662 if (REG_P (operands[2]))
0f40f9f7 10663 return "sal{w}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10664 else if (operands[2] == const1_rtx
495333a6 10665 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10666 return "sal{w}\t%0";
e075ae69 10667 else
0f40f9f7 10668 return "sal{w}\t{%2, %0|%0, %2}";
e075ae69 10669 }
0f40f9f7 10670}
e075ae69
RH
10671 [(set (attr "type")
10672 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10673 (const_int 0))
10674 (match_operand 0 "register_operand" ""))
10675 (match_operand 2 "const1_operand" ""))
10676 (const_string "alu")
10677 ]
6ef67412
JH
10678 (const_string "ishift")))
10679 (set_attr "mode" "HI")])
bb62e19a 10680
28cefcd2
BS
10681;; This pattern can't accept a variable shift count, since shifts by
10682;; zero don't affect the flags. We assume that shifts by constant
10683;; zero are optimized away.
2c873473 10684(define_insn "*ashlhi3_cmp"
42fabf21 10685 [(set (reg FLAGS_REG)
16189740 10686 (compare
e075ae69 10687 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
ef719a44 10688 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69
RH
10689 (const_int 0)))
10690 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10691 (ashift:HI (match_dup 1) (match_dup 2)))]
9076b9c1 10692 "ix86_match_ccmode (insn, CCGOCmode)
16189740 10693 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
886c62d1 10694{
e075ae69
RH
10695 switch (get_attr_type (insn))
10696 {
10697 case TYPE_ALU:
10698 if (operands[2] != const1_rtx)
10699 abort ();
0f40f9f7 10700 return "add{w}\t{%0, %0|%0, %0}";
886c62d1 10701
e075ae69
RH
10702 default:
10703 if (REG_P (operands[2]))
0f40f9f7 10704 return "sal{w}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10705 else if (operands[2] == const1_rtx
495333a6 10706 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10707 return "sal{w}\t%0";
e075ae69 10708 else
0f40f9f7 10709 return "sal{w}\t{%2, %0|%0, %2}";
e075ae69 10710 }
0f40f9f7 10711}
e075ae69
RH
10712 [(set (attr "type")
10713 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10714 (const_int 0))
10715 (match_operand 0 "register_operand" ""))
10716 (match_operand 2 "const1_operand" ""))
10717 (const_string "alu")
10718 ]
6ef67412
JH
10719 (const_string "ishift")))
10720 (set_attr "mode" "HI")])
e075ae69 10721
d525dfdf
JH
10722(define_expand "ashlqi3"
10723 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10724 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10725 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 10726 (clobber (reg:CC FLAGS_REG))]
d9f32422 10727 "TARGET_QIMODE_MATH"
d525dfdf
JH
10728 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10729
e075ae69 10730;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
10731
10732(define_insn "*ashlqi3_1_lea"
10733 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9a9286af 10734 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
91f9a498 10735 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8bc527af 10736 (clobber (reg:CC FLAGS_REG))]
58787064
JH
10737 "!TARGET_PARTIAL_REG_STALL
10738 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
58787064
JH
10739{
10740 switch (get_attr_type (insn))
10741 {
10742 case TYPE_LEA:
0f40f9f7 10743 return "#";
58787064
JH
10744 case TYPE_ALU:
10745 if (operands[2] != const1_rtx)
10746 abort ();
1a06f5fe 10747 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
0f40f9f7 10748 return "add{l}\t{%k0, %k0|%k0, %k0}";
58787064 10749 else
0f40f9f7 10750 return "add{b}\t{%0, %0|%0, %0}";
58787064
JH
10751
10752 default:
10753 if (REG_P (operands[2]))
10754 {
10755 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10756 return "sal{l}\t{%b2, %k0|%k0, %b2}";
58787064 10757 else
0f40f9f7 10758 return "sal{b}\t{%b2, %0|%0, %b2}";
58787064 10759 }
b4e0dd8e 10760 else if (operands[2] == const1_rtx
495333a6 10761 && (TARGET_SHIFT1 || optimize_size))
58787064
JH
10762 {
10763 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10764 return "sal{l}\t%0";
58787064 10765 else
0f40f9f7 10766 return "sal{b}\t%0";
58787064
JH
10767 }
10768 else
10769 {
10770 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10771 return "sal{l}\t{%2, %k0|%k0, %2}";
58787064 10772 else
0f40f9f7 10773 return "sal{b}\t{%2, %0|%0, %2}";
58787064
JH
10774 }
10775 }
0f40f9f7 10776}
58787064
JH
10777 [(set (attr "type")
10778 (cond [(eq_attr "alternative" "2")
10779 (const_string "lea")
10780 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10781 (const_int 0))
10782 (match_operand 0 "register_operand" ""))
10783 (match_operand 2 "const1_operand" ""))
10784 (const_string "alu")
10785 ]
10786 (const_string "ishift")))
10787 (set_attr "mode" "QI,SI,SI")])
10788
d525dfdf
JH
10789(define_insn "*ashlqi3_1"
10790 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
e075ae69
RH
10791 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10792 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
8bc527af 10793 (clobber (reg:CC FLAGS_REG))]
58787064
JH
10794 "TARGET_PARTIAL_REG_STALL
10795 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
886c62d1 10796{
e075ae69
RH
10797 switch (get_attr_type (insn))
10798 {
10799 case TYPE_ALU:
10800 if (operands[2] != const1_rtx)
10801 abort ();
1a06f5fe 10802 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
0f40f9f7 10803 return "add{l}\t{%k0, %k0|%k0, %k0}";
e075ae69 10804 else
0f40f9f7 10805 return "add{b}\t{%0, %0|%0, %0}";
886c62d1 10806
e075ae69
RH
10807 default:
10808 if (REG_P (operands[2]))
10809 {
1a06f5fe 10810 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10811 return "sal{l}\t{%b2, %k0|%k0, %b2}";
e075ae69 10812 else
0f40f9f7 10813 return "sal{b}\t{%b2, %0|%0, %b2}";
e075ae69 10814 }
b4e0dd8e 10815 else if (operands[2] == const1_rtx
495333a6 10816 && (TARGET_SHIFT1 || optimize_size))
8bad7136 10817 {
1a06f5fe 10818 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10819 return "sal{l}\t%0";
8bad7136 10820 else
0f40f9f7 10821 return "sal{b}\t%0";
8bad7136 10822 }
e075ae69
RH
10823 else
10824 {
1a06f5fe 10825 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 10826 return "sal{l}\t{%2, %k0|%k0, %2}";
e075ae69 10827 else
0f40f9f7 10828 return "sal{b}\t{%2, %0|%0, %2}";
e075ae69
RH
10829 }
10830 }
0f40f9f7 10831}
e075ae69
RH
10832 [(set (attr "type")
10833 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10834 (const_int 0))
10835 (match_operand 0 "register_operand" ""))
10836 (match_operand 2 "const1_operand" ""))
10837 (const_string "alu")
10838 ]
6ef67412
JH
10839 (const_string "ishift")))
10840 (set_attr "mode" "QI,SI")])
e075ae69 10841
28cefcd2
BS
10842;; This pattern can't accept a variable shift count, since shifts by
10843;; zero don't affect the flags. We assume that shifts by constant
10844;; zero are optimized away.
2c873473 10845(define_insn "*ashlqi3_cmp"
42fabf21 10846 [(set (reg FLAGS_REG)
16189740 10847 (compare
e075ae69 10848 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
ef719a44 10849 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69
RH
10850 (const_int 0)))
10851 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10852 (ashift:QI (match_dup 1) (match_dup 2)))]
9076b9c1 10853 "ix86_match_ccmode (insn, CCGOCmode)
16189740 10854 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
886c62d1 10855{
e075ae69
RH
10856 switch (get_attr_type (insn))
10857 {
10858 case TYPE_ALU:
10859 if (operands[2] != const1_rtx)
10860 abort ();
0f40f9f7 10861 return "add{b}\t{%0, %0|%0, %0}";
e075ae69
RH
10862
10863 default:
10864 if (REG_P (operands[2]))
0f40f9f7 10865 return "sal{b}\t{%b2, %0|%0, %b2}";
b4e0dd8e 10866 else if (operands[2] == const1_rtx
495333a6 10867 && (TARGET_SHIFT1 || optimize_size))
0f40f9f7 10868 return "sal{b}\t%0";
e075ae69 10869 else
0f40f9f7 10870 return "sal{b}\t{%2, %0|%0, %2}";
e075ae69 10871 }
0f40f9f7 10872}
e075ae69
RH
10873 [(set (attr "type")
10874 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10875 (const_int 0))
10876 (match_operand 0 "register_operand" ""))
10877 (match_operand 2 "const1_operand" ""))
10878 (const_string "alu")
10879 ]
6ef67412
JH
10880 (const_string "ishift")))
10881 (set_attr "mode" "QI")])
886c62d1
JVA
10882
10883;; See comment above `ashldi3' about how this works.
10884
e075ae69 10885(define_expand "ashrdi3"
93330ea1
RH
10886 [(set (match_operand:DI 0 "shiftdi_operand" "")
10887 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10888 (match_operand:QI 2 "nonmemory_operand" "")))]
56c0e8fa 10889 ""
93330ea1 10890 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
2ae0f82c 10891
93330ea1 10892(define_insn "*ashrdi3_63_rex64"
371bc54b
JH
10893 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10894 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10895 (match_operand:DI 2 "const_int_operand" "i,i")))
8bc527af 10896 (clobber (reg:CC FLAGS_REG))]
93330ea1
RH
10897 "TARGET_64BIT && INTVAL (operands[2]) == 63
10898 && (TARGET_USE_CLTD || optimize_size)
371bc54b
JH
10899 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10900 "@
10901 {cqto|cqo}
0f40f9f7 10902 sar{q}\t{%2, %0|%0, %2}"
371bc54b
JH
10903 [(set_attr "type" "imovx,ishift")
10904 (set_attr "prefix_0f" "0,*")
10905 (set_attr "length_immediate" "0,*")
10906 (set_attr "modrm" "0,1")
10907 (set_attr "mode" "DI")])
10908
10909(define_insn "*ashrdi3_1_one_bit_rex64"
10910 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10911 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 10912 (match_operand:QI 2 "const1_operand" "")))
8bc527af 10913 (clobber (reg:CC FLAGS_REG))]
371bc54b 10914 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
495333a6 10915 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 10916 "sar{q}\t%0"
371bc54b
JH
10917 [(set_attr "type" "ishift")
10918 (set (attr "length")
10919 (if_then_else (match_operand:DI 0 "register_operand" "")
10920 (const_string "2")
10921 (const_string "*")))])
10922
10923(define_insn "*ashrdi3_1_rex64"
10924 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10925 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7c17f553 10926 (match_operand:QI 2 "nonmemory_operand" "J,c")))
8bc527af 10927 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
10928 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10929 "@
0f40f9f7
ZW
10930 sar{q}\t{%2, %0|%0, %2}
10931 sar{q}\t{%b2, %0|%0, %b2}"
371bc54b
JH
10932 [(set_attr "type" "ishift")
10933 (set_attr "mode" "DI")])
10934
10935;; This pattern can't accept a variable shift count, since shifts by
10936;; zero don't affect the flags. We assume that shifts by constant
10937;; zero are optimized away.
10938(define_insn "*ashrdi3_one_bit_cmp_rex64"
42fabf21 10939 [(set (reg FLAGS_REG)
371bc54b
JH
10940 (compare
10941 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 10942 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
10943 (const_int 0)))
10944 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10945 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10946 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
495333a6 10947 && (TARGET_SHIFT1 || optimize_size)
371bc54b 10948 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
0f40f9f7 10949 "sar{q}\t%0"
371bc54b
JH
10950 [(set_attr "type" "ishift")
10951 (set (attr "length")
10952 (if_then_else (match_operand:DI 0 "register_operand" "")
10953 (const_string "2")
10954 (const_string "*")))])
10955
10956;; This pattern can't accept a variable shift count, since shifts by
10957;; zero don't affect the flags. We assume that shifts by constant
10958;; zero are optimized away.
10959(define_insn "*ashrdi3_cmp_rex64"
42fabf21 10960 [(set (reg FLAGS_REG)
371bc54b
JH
10961 (compare
10962 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10963 (match_operand:QI 2 "const_int_operand" "n"))
10964 (const_int 0)))
10965 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10966 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10967 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10968 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
0f40f9f7 10969 "sar{q}\t{%2, %0|%0, %2}"
371bc54b
JH
10970 [(set_attr "type" "ishift")
10971 (set_attr "mode" "DI")])
10972
93330ea1 10973(define_insn "*ashrdi3_1"
e075ae69
RH
10974 [(set (match_operand:DI 0 "register_operand" "=r")
10975 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10976 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8bc527af 10977 (clobber (reg:CC FLAGS_REG))]
371bc54b 10978 "!TARGET_64BIT"
e075ae69
RH
10979 "#"
10980 [(set_attr "type" "multi")])
886c62d1 10981
93330ea1
RH
10982;; By default we don't ask for a scratch register, because when DImode
10983;; values are manipulated, registers are already at a premium. But if
10984;; we have one handy, we won't turn it away.
10985(define_peephole2
10986 [(match_scratch:SI 3 "r")
10987 (parallel [(set (match_operand:DI 0 "register_operand" "")
10988 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10989 (match_operand:QI 2 "nonmemory_operand" "")))
10990 (clobber (reg:CC FLAGS_REG))])
10991 (match_dup 3)]
10992 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69
RH
10993 [(const_int 0)]
10994 "ix86_split_ashrdi (operands, operands[3]); DONE;")
886c62d1 10995
e075ae69
RH
10996(define_split
10997 [(set (match_operand:DI 0 "register_operand" "")
10998 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10999 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11000 (clobber (reg:CC FLAGS_REG))]
93330ea1 11001 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
e075ae69
RH
11002 [(const_int 0)]
11003 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
886c62d1 11004
e075ae69
RH
11005(define_insn "x86_shrd_1"
11006 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11007 (ior:SI (ashiftrt:SI (match_dup 0)
11008 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11009 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11010 (minus:QI (const_int 32) (match_dup 2)))))
8bc527af 11011 (clobber (reg:CC FLAGS_REG))]
886c62d1 11012 ""
e075ae69 11013 "@
0f40f9f7
ZW
11014 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11015 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
e075ae69 11016 [(set_attr "type" "ishift")
6ef67412 11017 (set_attr "prefix_0f" "1")
e075ae69 11018 (set_attr "pent_pair" "np")
6ef67412 11019 (set_attr "mode" "SI")])
e075ae69
RH
11020
11021(define_expand "x86_shift_adj_3"
11022 [(use (match_operand:SI 0 "register_operand" ""))
11023 (use (match_operand:SI 1 "register_operand" ""))
11024 (use (match_operand:QI 2 "register_operand" ""))]
11025 ""
886c62d1 11026{
e075ae69
RH
11027 rtx label = gen_label_rtx ();
11028 rtx tmp;
11029
16189740 11030 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
e075ae69 11031
16189740 11032 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
11033 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11034 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11035 gen_rtx_LABEL_REF (VOIDmode, label),
11036 pc_rtx);
11037 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11038 JUMP_LABEL (tmp) = label;
11039
11040 emit_move_insn (operands[0], operands[1]);
11041 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11042
11043 emit_label (label);
11044 LABEL_NUSES (label) = 1;
11045
11046 DONE;
0f40f9f7 11047})
886c62d1 11048
e075ae69
RH
11049(define_insn "ashrsi3_31"
11050 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11051 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11052 (match_operand:SI 2 "const_int_operand" "i,i")))
8bc527af 11053 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
11054 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11055 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
e075ae69
RH
11056 "@
11057 {cltd|cdq}
0f40f9f7 11058 sar{l}\t{%2, %0|%0, %2}"
6ef67412
JH
11059 [(set_attr "type" "imovx,ishift")
11060 (set_attr "prefix_0f" "0,*")
11061 (set_attr "length_immediate" "0,*")
11062 (set_attr "modrm" "0,1")
11063 (set_attr "mode" "SI")])
e075ae69 11064
371bc54b
JH
11065(define_insn "*ashrsi3_31_zext"
11066 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11067 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11068 (match_operand:SI 2 "const_int_operand" "i,i"))))
8bc527af 11069 (clobber (reg:CC FLAGS_REG))]
1b0c37d7
ZW
11070 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11071 && INTVAL (operands[2]) == 31
11072 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
371bc54b
JH
11073 "@
11074 {cltd|cdq}
0f40f9f7 11075 sar{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
11076 [(set_attr "type" "imovx,ishift")
11077 (set_attr "prefix_0f" "0,*")
11078 (set_attr "length_immediate" "0,*")
11079 (set_attr "modrm" "0,1")
11080 (set_attr "mode" "SI")])
11081
d525dfdf
JH
11082(define_expand "ashrsi3"
11083 [(set (match_operand:SI 0 "nonimmediate_operand" "")
155d8a47 11084 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
d525dfdf 11085 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11086 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
11087 ""
11088 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11089
8bad7136
JL
11090(define_insn "*ashrsi3_1_one_bit"
11091 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11092 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 11093 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11094 (clobber (reg:CC FLAGS_REG))]
8bad7136 11095 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
495333a6 11096 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11097 "sar{l}\t%0"
8bad7136
JL
11098 [(set_attr "type" "ishift")
11099 (set (attr "length")
11100 (if_then_else (match_operand:SI 0 "register_operand" "")
11101 (const_string "2")
11102 (const_string "*")))])
11103
371bc54b
JH
11104(define_insn "*ashrsi3_1_one_bit_zext"
11105 [(set (match_operand:DI 0 "register_operand" "=r")
11106 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
630eef90 11107 (match_operand:QI 2 "const1_operand" ""))))
8bc527af 11108 (clobber (reg:CC FLAGS_REG))]
371bc54b 11109 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
495333a6 11110 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11111 "sar{l}\t%k0"
371bc54b
JH
11112 [(set_attr "type" "ishift")
11113 (set_attr "length" "2")])
11114
d525dfdf 11115(define_insn "*ashrsi3_1"
e075ae69
RH
11116 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11117 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11118 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11119 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11120 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
e075ae69 11121 "@
0f40f9f7
ZW
11122 sar{l}\t{%2, %0|%0, %2}
11123 sar{l}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11124 [(set_attr "type" "ishift")
11125 (set_attr "mode" "SI")])
886c62d1 11126
371bc54b
JH
11127(define_insn "*ashrsi3_1_zext"
11128 [(set (match_operand:DI 0 "register_operand" "=r,r")
11129 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11130 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 11131 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11132 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11133 "@
0f40f9f7
ZW
11134 sar{l}\t{%2, %k0|%k0, %2}
11135 sar{l}\t{%b2, %k0|%k0, %b2}"
371bc54b
JH
11136 [(set_attr "type" "ishift")
11137 (set_attr "mode" "SI")])
11138
8bad7136
JL
11139;; This pattern can't accept a variable shift count, since shifts by
11140;; zero don't affect the flags. We assume that shifts by constant
11141;; zero are optimized away.
2c873473 11142(define_insn "*ashrsi3_one_bit_cmp"
42fabf21 11143 [(set (reg FLAGS_REG)
8bad7136
JL
11144 (compare
11145 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 11146 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
11147 (const_int 0)))
11148 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11149 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2c873473 11150 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11151 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11152 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11153 "sar{l}\t%0"
8bad7136
JL
11154 [(set_attr "type" "ishift")
11155 (set (attr "length")
11156 (if_then_else (match_operand:SI 0 "register_operand" "")
11157 (const_string "2")
11158 (const_string "*")))])
11159
371bc54b 11160(define_insn "*ashrsi3_one_bit_cmp_zext"
42fabf21 11161 [(set (reg FLAGS_REG)
371bc54b
JH
11162 (compare
11163 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
630eef90 11164 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
11165 (const_int 0)))
11166 (set (match_operand:DI 0 "register_operand" "=r")
11167 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11168 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
495333a6 11169 && (TARGET_SHIFT1 || optimize_size)
371bc54b 11170 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11171 "sar{l}\t%k0"
371bc54b
JH
11172 [(set_attr "type" "ishift")
11173 (set_attr "length" "2")])
11174
28cefcd2
BS
11175;; This pattern can't accept a variable shift count, since shifts by
11176;; zero don't affect the flags. We assume that shifts by constant
11177;; zero are optimized away.
2c873473 11178(define_insn "*ashrsi3_cmp"
42fabf21 11179 [(set (reg FLAGS_REG)
16189740 11180 (compare
28cefcd2 11181 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
ef719a44 11182 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 11183 (const_int 0)))
28cefcd2 11184 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 11185 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2c873473 11186 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11187 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11188 "sar{l}\t{%2, %0|%0, %2}"
6ef67412
JH
11189 [(set_attr "type" "ishift")
11190 (set_attr "mode" "SI")])
886c62d1 11191
371bc54b 11192(define_insn "*ashrsi3_cmp_zext"
42fabf21 11193 [(set (reg FLAGS_REG)
371bc54b
JH
11194 (compare
11195 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
ef719a44 11196 (match_operand:QI 2 "const_1_to_31_operand" "I"))
371bc54b
JH
11197 (const_int 0)))
11198 (set (match_operand:DI 0 "register_operand" "=r")
11199 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11200 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11201 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11202 "sar{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
11203 [(set_attr "type" "ishift")
11204 (set_attr "mode" "SI")])
11205
d525dfdf
JH
11206(define_expand "ashrhi3"
11207 [(set (match_operand:HI 0 "nonimmediate_operand" "")
155d8a47 11208 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
d525dfdf 11209 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11210 (clobber (reg:CC FLAGS_REG))]
d9f32422 11211 "TARGET_HIMODE_MATH"
d525dfdf
JH
11212 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11213
8bad7136
JL
11214(define_insn "*ashrhi3_1_one_bit"
11215 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11216 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 11217 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11218 (clobber (reg:CC FLAGS_REG))]
8bad7136 11219 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
495333a6 11220 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11221 "sar{w}\t%0"
8bad7136
JL
11222 [(set_attr "type" "ishift")
11223 (set (attr "length")
3d117b30 11224 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11225 (const_string "2")
11226 (const_string "*")))])
11227
d525dfdf 11228(define_insn "*ashrhi3_1"
e075ae69
RH
11229 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11230 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11231 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11232 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11233 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
e075ae69 11234 "@
0f40f9f7
ZW
11235 sar{w}\t{%2, %0|%0, %2}
11236 sar{w}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11237 [(set_attr "type" "ishift")
11238 (set_attr "mode" "HI")])
886c62d1 11239
8bad7136
JL
11240;; This pattern can't accept a variable shift count, since shifts by
11241;; zero don't affect the flags. We assume that shifts by constant
11242;; zero are optimized away.
2c873473 11243(define_insn "*ashrhi3_one_bit_cmp"
42fabf21 11244 [(set (reg FLAGS_REG)
8bad7136
JL
11245 (compare
11246 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 11247 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
11248 (const_int 0)))
11249 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11250 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
2c873473 11251 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11252 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11253 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
0f40f9f7 11254 "sar{w}\t%0"
8bad7136
JL
11255 [(set_attr "type" "ishift")
11256 (set (attr "length")
3d117b30 11257 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11258 (const_string "2")
11259 (const_string "*")))])
11260
28cefcd2
BS
11261;; This pattern can't accept a variable shift count, since shifts by
11262;; zero don't affect the flags. We assume that shifts by constant
11263;; zero are optimized away.
2c873473 11264(define_insn "*ashrhi3_cmp"
42fabf21 11265 [(set (reg FLAGS_REG)
16189740 11266 (compare
28cefcd2 11267 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
ef719a44 11268 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 11269 (const_int 0)))
28cefcd2 11270 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 11271 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
2c873473 11272 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11273 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
0f40f9f7 11274 "sar{w}\t{%2, %0|%0, %2}"
6ef67412
JH
11275 [(set_attr "type" "ishift")
11276 (set_attr "mode" "HI")])
886c62d1 11277
d525dfdf
JH
11278(define_expand "ashrqi3"
11279 [(set (match_operand:QI 0 "nonimmediate_operand" "")
155d8a47 11280 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
d525dfdf 11281 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11282 (clobber (reg:CC FLAGS_REG))]
d9f32422 11283 "TARGET_QIMODE_MATH"
d525dfdf
JH
11284 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11285
8bad7136
JL
11286(define_insn "*ashrqi3_1_one_bit"
11287 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11288 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 11289 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11290 (clobber (reg:CC FLAGS_REG))]
8bad7136 11291 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
495333a6 11292 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11293 "sar{b}\t%0"
8bad7136
JL
11294 [(set_attr "type" "ishift")
11295 (set (attr "length")
3d117b30 11296 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11297 (const_string "2")
11298 (const_string "*")))])
11299
2f41793e
JH
11300(define_insn "*ashrqi3_1_one_bit_slp"
11301 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 11302 (ashiftrt:QI (match_dup 0)
630eef90 11303 (match_operand:QI 1 "const1_operand" "")))
8bc527af 11304 (clobber (reg:CC FLAGS_REG))]
2f41793e
JH
11305 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11306 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
495333a6 11307 && (TARGET_SHIFT1 || optimize_size)"
2f41793e 11308 "sar{b}\t%0"
1b245ade 11309 [(set_attr "type" "ishift1")
2f41793e
JH
11310 (set (attr "length")
11311 (if_then_else (match_operand 0 "register_operand" "")
11312 (const_string "2")
11313 (const_string "*")))])
11314
d525dfdf 11315(define_insn "*ashrqi3_1"
e075ae69
RH
11316 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11317 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11318 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11319 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11320 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
e075ae69 11321 "@
0f40f9f7
ZW
11322 sar{b}\t{%2, %0|%0, %2}
11323 sar{b}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11324 [(set_attr "type" "ishift")
11325 (set_attr "mode" "QI")])
886c62d1 11326
2f41793e
JH
11327(define_insn "*ashrqi3_1_slp"
11328 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
11329 (ashiftrt:QI (match_dup 0)
11330 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 11331 (clobber (reg:CC FLAGS_REG))]
2f41793e 11332 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade 11333 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f41793e 11334 "@
1b245ade
JH
11335 sar{b}\t{%1, %0|%0, %1}
11336 sar{b}\t{%b1, %0|%0, %b1}"
11337 [(set_attr "type" "ishift1")
2f41793e
JH
11338 (set_attr "mode" "QI")])
11339
8bad7136
JL
11340;; This pattern can't accept a variable shift count, since shifts by
11341;; zero don't affect the flags. We assume that shifts by constant
11342;; zero are optimized away.
2c873473 11343(define_insn "*ashrqi3_one_bit_cmp"
42fabf21 11344 [(set (reg FLAGS_REG)
8bad7136
JL
11345 (compare
11346 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 11347 (match_operand:QI 2 "const1_operand" "I"))
8bad7136 11348 (const_int 0)))
5f90a099 11349 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8bad7136 11350 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
2c873473 11351 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11352 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11353 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
0f40f9f7 11354 "sar{b}\t%0"
8bad7136
JL
11355 [(set_attr "type" "ishift")
11356 (set (attr "length")
3d117b30 11357 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11358 (const_string "2")
11359 (const_string "*")))])
11360
28cefcd2
BS
11361;; This pattern can't accept a variable shift count, since shifts by
11362;; zero don't affect the flags. We assume that shifts by constant
11363;; zero are optimized away.
2c873473 11364(define_insn "*ashrqi3_cmp"
42fabf21 11365 [(set (reg FLAGS_REG)
16189740 11366 (compare
28cefcd2 11367 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
ef719a44 11368 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 11369 (const_int 0)))
5f90a099 11370 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 11371 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
2c873473 11372 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11373 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
0f40f9f7 11374 "sar{b}\t{%2, %0|%0, %2}"
6ef67412
JH
11375 [(set_attr "type" "ishift")
11376 (set_attr "mode" "QI")])
886c62d1 11377\f
e075ae69
RH
11378;; Logical shift instructions
11379
11380;; See comment above `ashldi3' about how this works.
11381
11382(define_expand "lshrdi3"
93330ea1
RH
11383 [(set (match_operand:DI 0 "shiftdi_operand" "")
11384 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11385 (match_operand:QI 2 "nonmemory_operand" "")))]
886c62d1 11386 ""
93330ea1 11387 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
886c62d1 11388
371bc54b
JH
11389(define_insn "*lshrdi3_1_one_bit_rex64"
11390 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11391 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 11392 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11393 (clobber (reg:CC FLAGS_REG))]
371bc54b 11394 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
495333a6 11395 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11396 "shr{q}\t%0"
371bc54b
JH
11397 [(set_attr "type" "ishift")
11398 (set (attr "length")
11399 (if_then_else (match_operand:DI 0 "register_operand" "")
11400 (const_string "2")
11401 (const_string "*")))])
11402
11403(define_insn "*lshrdi3_1_rex64"
11404 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11405 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11406 (match_operand:QI 2 "nonmemory_operand" "J,c")))
8bc527af 11407 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11408 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11409 "@
0f40f9f7
ZW
11410 shr{q}\t{%2, %0|%0, %2}
11411 shr{q}\t{%b2, %0|%0, %b2}"
371bc54b
JH
11412 [(set_attr "type" "ishift")
11413 (set_attr "mode" "DI")])
11414
11415;; This pattern can't accept a variable shift count, since shifts by
11416;; zero don't affect the flags. We assume that shifts by constant
11417;; zero are optimized away.
11418(define_insn "*lshrdi3_cmp_one_bit_rex64"
42fabf21 11419 [(set (reg FLAGS_REG)
371bc54b
JH
11420 (compare
11421 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 11422 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
11423 (const_int 0)))
11424 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11425 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11426 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
495333a6 11427 && (TARGET_SHIFT1 || optimize_size)
371bc54b 11428 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11429 "shr{q}\t%0"
371bc54b
JH
11430 [(set_attr "type" "ishift")
11431 (set (attr "length")
11432 (if_then_else (match_operand:DI 0 "register_operand" "")
11433 (const_string "2")
11434 (const_string "*")))])
11435
11436;; This pattern can't accept a variable shift count, since shifts by
11437;; zero don't affect the flags. We assume that shifts by constant
11438;; zero are optimized away.
11439(define_insn "*lshrdi3_cmp_rex64"
42fabf21 11440 [(set (reg FLAGS_REG)
371bc54b
JH
11441 (compare
11442 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11443 (match_operand:QI 2 "const_int_operand" "e"))
11444 (const_int 0)))
11445 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11446 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11447 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11448 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11449 "shr{q}\t{%2, %0|%0, %2}"
371bc54b
JH
11450 [(set_attr "type" "ishift")
11451 (set_attr "mode" "DI")])
11452
93330ea1 11453(define_insn "*lshrdi3_1"
e075ae69
RH
11454 [(set (match_operand:DI 0 "register_operand" "=r")
11455 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11456 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8bc527af 11457 (clobber (reg:CC FLAGS_REG))]
1e07edd3 11458 "!TARGET_64BIT"
e075ae69
RH
11459 "#"
11460 [(set_attr "type" "multi")])
886c62d1 11461
93330ea1
RH
11462;; By default we don't ask for a scratch register, because when DImode
11463;; values are manipulated, registers are already at a premium. But if
11464;; we have one handy, we won't turn it away.
11465(define_peephole2
11466 [(match_scratch:SI 3 "r")
11467 (parallel [(set (match_operand:DI 0 "register_operand" "")
11468 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11469 (match_operand:QI 2 "nonmemory_operand" "")))
11470 (clobber (reg:CC FLAGS_REG))])
11471 (match_dup 3)]
11472 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69
RH
11473 [(const_int 0)]
11474 "ix86_split_lshrdi (operands, operands[3]); DONE;")
886c62d1 11475
e075ae69
RH
11476(define_split
11477 [(set (match_operand:DI 0 "register_operand" "")
11478 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11479 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11480 (clobber (reg:CC FLAGS_REG))]
93330ea1 11481 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
e075ae69
RH
11482 [(const_int 0)]
11483 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
886c62d1 11484
d525dfdf
JH
11485(define_expand "lshrsi3"
11486 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11487 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11488 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11489 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
11490 ""
11491 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11492
8bad7136
JL
11493(define_insn "*lshrsi3_1_one_bit"
11494 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11495 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 11496 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11497 (clobber (reg:CC FLAGS_REG))]
8bad7136 11498 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
495333a6 11499 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11500 "shr{l}\t%0"
8bad7136
JL
11501 [(set_attr "type" "ishift")
11502 (set (attr "length")
11503 (if_then_else (match_operand:SI 0 "register_operand" "")
11504 (const_string "2")
11505 (const_string "*")))])
11506
371bc54b
JH
11507(define_insn "*lshrsi3_1_one_bit_zext"
11508 [(set (match_operand:DI 0 "register_operand" "=r")
11509 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
630eef90 11510 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11511 (clobber (reg:CC FLAGS_REG))]
371bc54b 11512 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
495333a6 11513 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11514 "shr{l}\t%k0"
371bc54b
JH
11515 [(set_attr "type" "ishift")
11516 (set_attr "length" "2")])
11517
d525dfdf 11518(define_insn "*lshrsi3_1"
e075ae69
RH
11519 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11520 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11521 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11522 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11523 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
e075ae69 11524 "@
0f40f9f7
ZW
11525 shr{l}\t{%2, %0|%0, %2}
11526 shr{l}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11527 [(set_attr "type" "ishift")
11528 (set_attr "mode" "SI")])
886c62d1 11529
371bc54b
JH
11530(define_insn "*lshrsi3_1_zext"
11531 [(set (match_operand:DI 0 "register_operand" "=r,r")
11532 (zero_extend:DI
11533 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11534 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 11535 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11536 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11537 "@
0f40f9f7
ZW
11538 shr{l}\t{%2, %k0|%k0, %2}
11539 shr{l}\t{%b2, %k0|%k0, %b2}"
371bc54b
JH
11540 [(set_attr "type" "ishift")
11541 (set_attr "mode" "SI")])
11542
8bad7136
JL
11543;; This pattern can't accept a variable shift count, since shifts by
11544;; zero don't affect the flags. We assume that shifts by constant
11545;; zero are optimized away.
2c873473 11546(define_insn "*lshrsi3_one_bit_cmp"
42fabf21 11547 [(set (reg FLAGS_REG)
8bad7136
JL
11548 (compare
11549 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 11550 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
11551 (const_int 0)))
11552 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11553 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
9076b9c1 11554 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11555 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11556 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11557 "shr{l}\t%0"
8bad7136
JL
11558 [(set_attr "type" "ishift")
11559 (set (attr "length")
11560 (if_then_else (match_operand:SI 0 "register_operand" "")
11561 (const_string "2")
11562 (const_string "*")))])
11563
371bc54b 11564(define_insn "*lshrsi3_cmp_one_bit_zext"
42fabf21 11565 [(set (reg FLAGS_REG)
371bc54b
JH
11566 (compare
11567 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
630eef90 11568 (match_operand:QI 2 "const1_operand" ""))
371bc54b
JH
11569 (const_int 0)))
11570 (set (match_operand:DI 0 "register_operand" "=r")
11571 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11572 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
495333a6 11573 && (TARGET_SHIFT1 || optimize_size)
371bc54b 11574 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11575 "shr{l}\t%k0"
371bc54b
JH
11576 [(set_attr "type" "ishift")
11577 (set_attr "length" "2")])
11578
28cefcd2
BS
11579;; This pattern can't accept a variable shift count, since shifts by
11580;; zero don't affect the flags. We assume that shifts by constant
11581;; zero are optimized away.
2c873473 11582(define_insn "*lshrsi3_cmp"
42fabf21 11583 [(set (reg FLAGS_REG)
16189740 11584 (compare
28cefcd2 11585 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
ef719a44 11586 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 11587 (const_int 0)))
28cefcd2 11588 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 11589 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
9076b9c1 11590 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11591 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11592 "shr{l}\t{%2, %0|%0, %2}"
6ef67412
JH
11593 [(set_attr "type" "ishift")
11594 (set_attr "mode" "SI")])
886c62d1 11595
371bc54b 11596(define_insn "*lshrsi3_cmp_zext"
42fabf21 11597 [(set (reg FLAGS_REG)
371bc54b
JH
11598 (compare
11599 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
ef719a44 11600 (match_operand:QI 2 "const_1_to_31_operand" "I"))
371bc54b
JH
11601 (const_int 0)))
11602 (set (match_operand:DI 0 "register_operand" "=r")
11603 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11604 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11605 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11606 "shr{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
11607 [(set_attr "type" "ishift")
11608 (set_attr "mode" "SI")])
11609
d525dfdf
JH
11610(define_expand "lshrhi3"
11611 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11612 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11613 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11614 (clobber (reg:CC FLAGS_REG))]
d9f32422 11615 "TARGET_HIMODE_MATH"
d525dfdf
JH
11616 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11617
8bad7136
JL
11618(define_insn "*lshrhi3_1_one_bit"
11619 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11620 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 11621 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11622 (clobber (reg:CC FLAGS_REG))]
8bad7136 11623 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
495333a6 11624 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11625 "shr{w}\t%0"
8bad7136
JL
11626 [(set_attr "type" "ishift")
11627 (set (attr "length")
3d117b30 11628 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11629 (const_string "2")
11630 (const_string "*")))])
11631
d525dfdf 11632(define_insn "*lshrhi3_1"
e075ae69
RH
11633 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11634 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11635 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11636 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11637 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
e075ae69 11638 "@
0f40f9f7
ZW
11639 shr{w}\t{%2, %0|%0, %2}
11640 shr{w}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11641 [(set_attr "type" "ishift")
11642 (set_attr "mode" "HI")])
886c62d1 11643
8bad7136
JL
11644;; This pattern can't accept a variable shift count, since shifts by
11645;; zero don't affect the flags. We assume that shifts by constant
11646;; zero are optimized away.
2c873473 11647(define_insn "*lshrhi3_one_bit_cmp"
42fabf21 11648 [(set (reg FLAGS_REG)
8bad7136
JL
11649 (compare
11650 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 11651 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
11652 (const_int 0)))
11653 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11654 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
9076b9c1 11655 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11656 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11657 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11658 "shr{w}\t%0"
8bad7136
JL
11659 [(set_attr "type" "ishift")
11660 (set (attr "length")
11661 (if_then_else (match_operand:SI 0 "register_operand" "")
11662 (const_string "2")
11663 (const_string "*")))])
11664
28cefcd2
BS
11665;; This pattern can't accept a variable shift count, since shifts by
11666;; zero don't affect the flags. We assume that shifts by constant
11667;; zero are optimized away.
2c873473 11668(define_insn "*lshrhi3_cmp"
42fabf21 11669 [(set (reg FLAGS_REG)
16189740 11670 (compare
28cefcd2 11671 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
ef719a44 11672 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 11673 (const_int 0)))
28cefcd2 11674 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 11675 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
9076b9c1 11676 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11677 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11678 "shr{w}\t{%2, %0|%0, %2}"
6ef67412
JH
11679 [(set_attr "type" "ishift")
11680 (set_attr "mode" "HI")])
886c62d1 11681
d525dfdf
JH
11682(define_expand "lshrqi3"
11683 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11684 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11685 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11686 (clobber (reg:CC FLAGS_REG))]
d9f32422 11687 "TARGET_QIMODE_MATH"
d525dfdf
JH
11688 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11689
8bad7136
JL
11690(define_insn "*lshrqi3_1_one_bit"
11691 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11692 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 11693 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11694 (clobber (reg:CC FLAGS_REG))]
8bad7136 11695 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
495333a6 11696 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11697 "shr{b}\t%0"
8bad7136
JL
11698 [(set_attr "type" "ishift")
11699 (set (attr "length")
3d117b30 11700 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11701 (const_string "2")
11702 (const_string "*")))])
11703
2f41793e
JH
11704(define_insn "*lshrqi3_1_one_bit_slp"
11705 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 11706 (lshiftrt:QI (match_dup 0)
630eef90 11707 (match_operand:QI 1 "const1_operand" "")))
8bc527af 11708 (clobber (reg:CC FLAGS_REG))]
2f41793e 11709 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
495333a6 11710 && (TARGET_SHIFT1 || optimize_size)"
2f41793e 11711 "shr{b}\t%0"
1b245ade 11712 [(set_attr "type" "ishift1")
2f41793e
JH
11713 (set (attr "length")
11714 (if_then_else (match_operand 0 "register_operand" "")
11715 (const_string "2")
11716 (const_string "*")))])
11717
d525dfdf 11718(define_insn "*lshrqi3_1"
e075ae69
RH
11719 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11720 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11721 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11722 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11723 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
e075ae69 11724 "@
0f40f9f7
ZW
11725 shr{b}\t{%2, %0|%0, %2}
11726 shr{b}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11727 [(set_attr "type" "ishift")
11728 (set_attr "mode" "QI")])
886c62d1 11729
2f41793e
JH
11730(define_insn "*lshrqi3_1_slp"
11731 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
11732 (lshiftrt:QI (match_dup 0)
11733 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 11734 (clobber (reg:CC FLAGS_REG))]
2f41793e 11735 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade 11736 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f41793e 11737 "@
1b245ade
JH
11738 shr{b}\t{%1, %0|%0, %1}
11739 shr{b}\t{%b1, %0|%0, %b1}"
11740 [(set_attr "type" "ishift1")
2f41793e
JH
11741 (set_attr "mode" "QI")])
11742
8bad7136
JL
11743;; This pattern can't accept a variable shift count, since shifts by
11744;; zero don't affect the flags. We assume that shifts by constant
11745;; zero are optimized away.
2c873473 11746(define_insn "*lshrqi2_one_bit_cmp"
42fabf21 11747 [(set (reg FLAGS_REG)
8bad7136
JL
11748 (compare
11749 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 11750 (match_operand:QI 2 "const1_operand" ""))
8bad7136
JL
11751 (const_int 0)))
11752 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11753 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
9076b9c1 11754 "ix86_match_ccmode (insn, CCGOCmode)
495333a6 11755 && (TARGET_SHIFT1 || optimize_size)
8bad7136 11756 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
0f40f9f7 11757 "shr{b}\t%0"
8bad7136
JL
11758 [(set_attr "type" "ishift")
11759 (set (attr "length")
11760 (if_then_else (match_operand:SI 0 "register_operand" "")
11761 (const_string "2")
11762 (const_string "*")))])
11763
28cefcd2
BS
11764;; This pattern can't accept a variable shift count, since shifts by
11765;; zero don't affect the flags. We assume that shifts by constant
11766;; zero are optimized away.
2c873473 11767(define_insn "*lshrqi2_cmp"
42fabf21 11768 [(set (reg FLAGS_REG)
16189740 11769 (compare
28cefcd2 11770 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
ef719a44 11771 (match_operand:QI 2 "const_1_to_31_operand" "I"))
e075ae69 11772 (const_int 0)))
122ddbf9 11773 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 11774 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
9076b9c1 11775 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11776 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
0f40f9f7 11777 "shr{b}\t{%2, %0|%0, %2}"
6ef67412
JH
11778 [(set_attr "type" "ishift")
11779 (set_attr "mode" "QI")])
886c62d1 11780\f
e075ae69 11781;; Rotate instructions
886c62d1 11782
371bc54b
JH
11783(define_expand "rotldi3"
11784 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11785 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11786 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11787 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11788 "TARGET_64BIT"
11789 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11790
11791(define_insn "*rotlsi3_1_one_bit_rex64"
11792 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11793 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 11794 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11795 (clobber (reg:CC FLAGS_REG))]
371bc54b 11796 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
495333a6 11797 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11798 "rol{q}\t%0"
890d52e8 11799 [(set_attr "type" "rotate")
371bc54b
JH
11800 (set (attr "length")
11801 (if_then_else (match_operand:DI 0 "register_operand" "")
11802 (const_string "2")
11803 (const_string "*")))])
11804
11805(define_insn "*rotldi3_1_rex64"
11806 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11807 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11808 (match_operand:QI 2 "nonmemory_operand" "e,c")))
8bc527af 11809 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11810 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11811 "@
0f40f9f7
ZW
11812 rol{q}\t{%2, %0|%0, %2}
11813 rol{q}\t{%b2, %0|%0, %b2}"
890d52e8 11814 [(set_attr "type" "rotate")
371bc54b
JH
11815 (set_attr "mode" "DI")])
11816
d525dfdf
JH
11817(define_expand "rotlsi3"
11818 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11819 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11820 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11821 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
11822 ""
11823 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11824
8bad7136
JL
11825(define_insn "*rotlsi3_1_one_bit"
11826 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11827 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 11828 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11829 (clobber (reg:CC FLAGS_REG))]
8bad7136 11830 "ix86_binary_operator_ok (ROTATE, SImode, operands)
495333a6 11831 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11832 "rol{l}\t%0"
890d52e8 11833 [(set_attr "type" "rotate")
8bad7136
JL
11834 (set (attr "length")
11835 (if_then_else (match_operand:SI 0 "register_operand" "")
11836 (const_string "2")
11837 (const_string "*")))])
11838
371bc54b
JH
11839(define_insn "*rotlsi3_1_one_bit_zext"
11840 [(set (match_operand:DI 0 "register_operand" "=r")
11841 (zero_extend:DI
11842 (rotate:SI (match_operand:SI 1 "register_operand" "0")
630eef90 11843 (match_operand:QI 2 "const1_operand" ""))))
8bc527af 11844 (clobber (reg:CC FLAGS_REG))]
371bc54b 11845 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
495333a6 11846 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11847 "rol{l}\t%k0"
890d52e8 11848 [(set_attr "type" "rotate")
371bc54b
JH
11849 (set_attr "length" "2")])
11850
d525dfdf 11851(define_insn "*rotlsi3_1"
e075ae69
RH
11852 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11853 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11854 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11855 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11856 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
e075ae69 11857 "@
0f40f9f7
ZW
11858 rol{l}\t{%2, %0|%0, %2}
11859 rol{l}\t{%b2, %0|%0, %b2}"
890d52e8 11860 [(set_attr "type" "rotate")
6ef67412 11861 (set_attr "mode" "SI")])
b4ac57ab 11862
371bc54b
JH
11863(define_insn "*rotlsi3_1_zext"
11864 [(set (match_operand:DI 0 "register_operand" "=r,r")
11865 (zero_extend:DI
11866 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11867 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 11868 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11869 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11870 "@
0f40f9f7
ZW
11871 rol{l}\t{%2, %k0|%k0, %2}
11872 rol{l}\t{%b2, %k0|%k0, %b2}"
890d52e8 11873 [(set_attr "type" "rotate")
371bc54b
JH
11874 (set_attr "mode" "SI")])
11875
d525dfdf
JH
11876(define_expand "rotlhi3"
11877 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11878 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11879 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11880 (clobber (reg:CC FLAGS_REG))]
d9f32422 11881 "TARGET_HIMODE_MATH"
d525dfdf
JH
11882 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11883
8bad7136
JL
11884(define_insn "*rotlhi3_1_one_bit"
11885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11886 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 11887 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11888 (clobber (reg:CC FLAGS_REG))]
8bad7136 11889 "ix86_binary_operator_ok (ROTATE, HImode, operands)
495333a6 11890 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11891 "rol{w}\t%0"
890d52e8 11892 [(set_attr "type" "rotate")
8bad7136 11893 (set (attr "length")
3d117b30 11894 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11895 (const_string "2")
11896 (const_string "*")))])
11897
d525dfdf 11898(define_insn "*rotlhi3_1"
e075ae69
RH
11899 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11900 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11901 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11902 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11903 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
e075ae69 11904 "@
0f40f9f7
ZW
11905 rol{w}\t{%2, %0|%0, %2}
11906 rol{w}\t{%b2, %0|%0, %b2}"
890d52e8 11907 [(set_attr "type" "rotate")
6ef67412 11908 (set_attr "mode" "HI")])
47af5d50 11909
d525dfdf
JH
11910(define_expand "rotlqi3"
11911 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11912 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11913 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11914 (clobber (reg:CC FLAGS_REG))]
d9f32422 11915 "TARGET_QIMODE_MATH"
d525dfdf
JH
11916 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11917
2f41793e
JH
11918(define_insn "*rotlqi3_1_one_bit_slp"
11919 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 11920 (rotate:QI (match_dup 0)
630eef90 11921 (match_operand:QI 1 "const1_operand" "")))
8bc527af 11922 (clobber (reg:CC FLAGS_REG))]
2f41793e 11923 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
495333a6 11924 && (TARGET_SHIFT1 || optimize_size)"
2f41793e 11925 "rol{b}\t%0"
1b245ade 11926 [(set_attr "type" "rotate1")
2f41793e
JH
11927 (set (attr "length")
11928 (if_then_else (match_operand 0 "register_operand" "")
11929 (const_string "2")
11930 (const_string "*")))])
11931
8bad7136
JL
11932(define_insn "*rotlqi3_1_one_bit"
11933 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 11935 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11936 (clobber (reg:CC FLAGS_REG))]
8bad7136 11937 "ix86_binary_operator_ok (ROTATE, QImode, operands)
495333a6 11938 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11939 "rol{b}\t%0"
890d52e8 11940 [(set_attr "type" "rotate")
8bad7136 11941 (set (attr "length")
3d117b30 11942 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11943 (const_string "2")
11944 (const_string "*")))])
11945
2f41793e
JH
11946(define_insn "*rotlqi3_1_slp"
11947 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
11948 (rotate:QI (match_dup 0)
11949 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 11950 (clobber (reg:CC FLAGS_REG))]
2f41793e 11951 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade 11952 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f41793e 11953 "@
1b245ade
JH
11954 rol{b}\t{%1, %0|%0, %1}
11955 rol{b}\t{%b1, %0|%0, %b1}"
11956 [(set_attr "type" "rotate1")
2f41793e
JH
11957 (set_attr "mode" "QI")])
11958
d525dfdf 11959(define_insn "*rotlqi3_1"
e075ae69
RH
11960 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11961 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11962 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 11963 (clobber (reg:CC FLAGS_REG))]
d525dfdf 11964 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
e075ae69 11965 "@
0f40f9f7
ZW
11966 rol{b}\t{%2, %0|%0, %2}
11967 rol{b}\t{%b2, %0|%0, %b2}"
890d52e8 11968 [(set_attr "type" "rotate")
6ef67412 11969 (set_attr "mode" "QI")])
47af5d50 11970
371bc54b
JH
11971(define_expand "rotrdi3"
11972 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11973 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11974 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 11975 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11976 "TARGET_64BIT"
11977 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11978
11979(define_insn "*rotrdi3_1_one_bit_rex64"
11980 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11981 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
630eef90 11982 (match_operand:QI 2 "const1_operand" "")))
8bc527af 11983 (clobber (reg:CC FLAGS_REG))]
371bc54b 11984 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
495333a6 11985 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 11986 "ror{q}\t%0"
890d52e8 11987 [(set_attr "type" "rotate")
371bc54b
JH
11988 (set (attr "length")
11989 (if_then_else (match_operand:DI 0 "register_operand" "")
11990 (const_string "2")
11991 (const_string "*")))])
11992
11993(define_insn "*rotrdi3_1_rex64"
11994 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11995 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11996 (match_operand:QI 2 "nonmemory_operand" "J,c")))
8bc527af 11997 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
11998 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11999 "@
0f40f9f7
ZW
12000 ror{q}\t{%2, %0|%0, %2}
12001 ror{q}\t{%b2, %0|%0, %b2}"
890d52e8 12002 [(set_attr "type" "rotate")
371bc54b
JH
12003 (set_attr "mode" "DI")])
12004
d525dfdf
JH
12005(define_expand "rotrsi3"
12006 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12007 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12008 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 12009 (clobber (reg:CC FLAGS_REG))]
d525dfdf
JH
12010 ""
12011 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12012
8bad7136
JL
12013(define_insn "*rotrsi3_1_one_bit"
12014 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12015 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
630eef90 12016 (match_operand:QI 2 "const1_operand" "")))
8bc527af 12017 (clobber (reg:CC FLAGS_REG))]
8bad7136 12018 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
495333a6 12019 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 12020 "ror{l}\t%0"
890d52e8 12021 [(set_attr "type" "rotate")
8bad7136
JL
12022 (set (attr "length")
12023 (if_then_else (match_operand:SI 0 "register_operand" "")
12024 (const_string "2")
12025 (const_string "*")))])
12026
371bc54b
JH
12027(define_insn "*rotrsi3_1_one_bit_zext"
12028 [(set (match_operand:DI 0 "register_operand" "=r")
12029 (zero_extend:DI
12030 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
630eef90 12031 (match_operand:QI 2 "const1_operand" ""))))
8bc527af 12032 (clobber (reg:CC FLAGS_REG))]
371bc54b 12033 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
495333a6 12034 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 12035 "ror{l}\t%k0"
890d52e8 12036 [(set_attr "type" "rotate")
371bc54b
JH
12037 (set (attr "length")
12038 (if_then_else (match_operand:SI 0 "register_operand" "")
12039 (const_string "2")
12040 (const_string "*")))])
12041
d525dfdf 12042(define_insn "*rotrsi3_1"
e075ae69
RH
12043 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12044 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12045 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 12046 (clobber (reg:CC FLAGS_REG))]
d525dfdf 12047 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
e075ae69 12048 "@
0f40f9f7
ZW
12049 ror{l}\t{%2, %0|%0, %2}
12050 ror{l}\t{%b2, %0|%0, %b2}"
890d52e8 12051 [(set_attr "type" "rotate")
6ef67412 12052 (set_attr "mode" "SI")])
47af5d50 12053
371bc54b
JH
12054(define_insn "*rotrsi3_1_zext"
12055 [(set (match_operand:DI 0 "register_operand" "=r,r")
12056 (zero_extend:DI
12057 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12058 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
8bc527af 12059 (clobber (reg:CC FLAGS_REG))]
371bc54b
JH
12060 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12061 "@
0f40f9f7
ZW
12062 ror{l}\t{%2, %k0|%k0, %2}
12063 ror{l}\t{%b2, %k0|%k0, %b2}"
890d52e8 12064 [(set_attr "type" "rotate")
371bc54b
JH
12065 (set_attr "mode" "SI")])
12066
d525dfdf
JH
12067(define_expand "rotrhi3"
12068 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12069 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12070 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 12071 (clobber (reg:CC FLAGS_REG))]
d9f32422 12072 "TARGET_HIMODE_MATH"
d525dfdf
JH
12073 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12074
8bad7136
JL
12075(define_insn "*rotrhi3_one_bit"
12076 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12077 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
630eef90 12078 (match_operand:QI 2 "const1_operand" "")))
8bc527af 12079 (clobber (reg:CC FLAGS_REG))]
8bad7136 12080 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
495333a6 12081 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 12082 "ror{w}\t%0"
890d52e8 12083 [(set_attr "type" "rotate")
8bad7136 12084 (set (attr "length")
3d117b30 12085 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
12086 (const_string "2")
12087 (const_string "*")))])
12088
d525dfdf 12089(define_insn "*rotrhi3"
e075ae69
RH
12090 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12091 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12092 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 12093 (clobber (reg:CC FLAGS_REG))]
d525dfdf 12094 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
e075ae69 12095 "@
0f40f9f7
ZW
12096 ror{w}\t{%2, %0|%0, %2}
12097 ror{w}\t{%b2, %0|%0, %b2}"
890d52e8 12098 [(set_attr "type" "rotate")
6ef67412 12099 (set_attr "mode" "HI")])
a199fdd6 12100
d525dfdf
JH
12101(define_expand "rotrqi3"
12102 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12103 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12104 (match_operand:QI 2 "nonmemory_operand" "")))
8bc527af 12105 (clobber (reg:CC FLAGS_REG))]
d9f32422 12106 "TARGET_QIMODE_MATH"
d525dfdf
JH
12107 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12108
8bad7136
JL
12109(define_insn "*rotrqi3_1_one_bit"
12110 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12111 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
630eef90 12112 (match_operand:QI 2 "const1_operand" "")))
8bc527af 12113 (clobber (reg:CC FLAGS_REG))]
8bad7136 12114 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
495333a6 12115 && (TARGET_SHIFT1 || optimize_size)"
0f40f9f7 12116 "ror{b}\t%0"
890d52e8 12117 [(set_attr "type" "rotate")
8bad7136 12118 (set (attr "length")
3d117b30 12119 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
12120 (const_string "2")
12121 (const_string "*")))])
12122
2f41793e
JH
12123(define_insn "*rotrqi3_1_one_bit_slp"
12124 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1b245ade 12125 (rotatert:QI (match_dup 0)
630eef90 12126 (match_operand:QI 1 "const1_operand" "")))
8bc527af 12127 (clobber (reg:CC FLAGS_REG))]
2f41793e 12128 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
495333a6 12129 && (TARGET_SHIFT1 || optimize_size)"
2f41793e 12130 "ror{b}\t%0"
1b245ade 12131 [(set_attr "type" "rotate1")
2f41793e
JH
12132 (set (attr "length")
12133 (if_then_else (match_operand 0 "register_operand" "")
12134 (const_string "2")
12135 (const_string "*")))])
12136
d525dfdf 12137(define_insn "*rotrqi3_1"
e075ae69
RH
12138 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12139 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12140 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8bc527af 12141 (clobber (reg:CC FLAGS_REG))]
d525dfdf 12142 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
e075ae69 12143 "@
0f40f9f7
ZW
12144 ror{b}\t{%2, %0|%0, %2}
12145 ror{b}\t{%b2, %0|%0, %b2}"
890d52e8 12146 [(set_attr "type" "rotate")
6ef67412 12147 (set_attr "mode" "QI")])
2f41793e
JH
12148
12149(define_insn "*rotrqi3_1_slp"
12150 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
1b245ade
JH
12151 (rotatert:QI (match_dup 0)
12152 (match_operand:QI 1 "nonmemory_operand" "I,c")))
8bc527af 12153 (clobber (reg:CC FLAGS_REG))]
2f41793e 12154 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1b245ade 12155 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f41793e 12156 "@
1b245ade
JH
12157 ror{b}\t{%1, %0|%0, %1}
12158 ror{b}\t{%b1, %0|%0, %b1}"
12159 [(set_attr "type" "rotate1")
2f41793e 12160 (set_attr "mode" "QI")])
e075ae69
RH
12161\f
12162;; Bit set / bit test instructions
a199fdd6 12163
e075ae69
RH
12164(define_expand "extv"
12165 [(set (match_operand:SI 0 "register_operand" "")
12166 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12167 (match_operand:SI 2 "immediate_operand" "")
12168 (match_operand:SI 3 "immediate_operand" "")))]
12169 ""
e075ae69
RH
12170{
12171 /* Handle extractions from %ah et al. */
12172 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12173 FAIL;
a199fdd6 12174
e075ae69
RH
12175 /* From mips.md: extract_bit_field doesn't verify that our source
12176 matches the predicate, so check it again here. */
6e62a38d 12177 if (! ext_register_operand (operands[1], VOIDmode))
e075ae69 12178 FAIL;
0f40f9f7 12179})
a199fdd6 12180
e075ae69
RH
12181(define_expand "extzv"
12182 [(set (match_operand:SI 0 "register_operand" "")
12183 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12184 (match_operand:SI 2 "immediate_operand" "")
12185 (match_operand:SI 3 "immediate_operand" "")))]
12186 ""
e075ae69
RH
12187{
12188 /* Handle extractions from %ah et al. */
12189 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12190 FAIL;
a199fdd6 12191
e075ae69
RH
12192 /* From mips.md: extract_bit_field doesn't verify that our source
12193 matches the predicate, so check it again here. */
6e62a38d 12194 if (! ext_register_operand (operands[1], VOIDmode))
e075ae69 12195 FAIL;
0f40f9f7 12196})
a199fdd6 12197
e075ae69 12198(define_expand "insv"
044b3892
L
12199 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12200 (match_operand 1 "immediate_operand" "")
12201 (match_operand 2 "immediate_operand" ""))
12202 (match_operand 3 "register_operand" ""))]
e075ae69 12203 ""
e075ae69
RH
12204{
12205 /* Handle extractions from %ah et al. */
12206 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12207 FAIL;
a199fdd6 12208
e075ae69
RH
12209 /* From mips.md: insert_bit_field doesn't verify that our source
12210 matches the predicate, so check it again here. */
6e62a38d 12211 if (! ext_register_operand (operands[0], VOIDmode))
e075ae69 12212 FAIL;
044b3892
L
12213
12214 if (TARGET_64BIT)
12215 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12216 else
12217 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12218
12219 DONE;
0f40f9f7 12220})
e075ae69
RH
12221
12222;; %%% bts, btr, btc, bt.
7cacf53e
RH
12223;; In general these instructions are *slow* when applied to memory,
12224;; since they enforce atomic operation. When applied to registers,
12225;; it depends on the cpu implementation. They're never faster than
12226;; the corresponding and/ior/xor operations, so with 32-bit there's
12227;; no point. But in 64-bit, we can't hold the relevant immediates
12228;; within the instruction itself, so operating on bits in the high
12229;; 32-bits of a register becomes easier.
12230;;
12231;; These are slow on Nocona, but fast on Athlon64. We do require the use
12232;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12233;; negdf respectively, so they can never be disabled entirely.
12234
12235(define_insn "*btsq"
ad4f9e7e 12236 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
7cacf53e 12237 (const_int 1)
ad4f9e7e 12238 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
12239 (const_int 1))
12240 (clobber (reg:CC FLAGS_REG))]
12241 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12242 "bts{q} %1,%0"
12243 [(set_attr "type" "alu1")])
12244
12245(define_insn "*btrq"
ad4f9e7e 12246 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
7cacf53e 12247 (const_int 1)
ad4f9e7e 12248 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
12249 (const_int 0))
12250 (clobber (reg:CC FLAGS_REG))]
12251 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12252 "btr{q} %1,%0"
12253 [(set_attr "type" "alu1")])
12254
12255(define_insn "*btcq"
ad4f9e7e 12256 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
7cacf53e 12257 (const_int 1)
ad4f9e7e 12258 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
12259 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12260 (clobber (reg:CC FLAGS_REG))]
12261 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12262 "btc{q} %1,%0"
12263 [(set_attr "type" "alu1")])
12264
12265;; Allow Nocona to avoid these instructions if a register is available.
12266
12267(define_peephole2
12268 [(match_scratch:DI 2 "r")
12269 (parallel [(set (zero_extract:DI
ad4f9e7e 12270 (match_operand:DI 0 "register_operand" "")
7cacf53e 12271 (const_int 1)
ad4f9e7e 12272 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
12273 (const_int 1))
12274 (clobber (reg:CC FLAGS_REG))])]
12275 "TARGET_64BIT && !TARGET_USE_BT"
12276 [(const_int 0)]
12277{
12278 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12279 rtx op1;
12280
12281 if (HOST_BITS_PER_WIDE_INT >= 64)
12282 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12283 else if (i < HOST_BITS_PER_WIDE_INT)
12284 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12285 else
12286 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12287
12288 op1 = immed_double_const (lo, hi, DImode);
12289 if (i >= 31)
12290 {
12291 emit_move_insn (operands[2], op1);
12292 op1 = operands[2];
12293 }
12294
12295 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12296 DONE;
12297})
12298
12299(define_peephole2
12300 [(match_scratch:DI 2 "r")
12301 (parallel [(set (zero_extract:DI
ad4f9e7e 12302 (match_operand:DI 0 "register_operand" "")
7cacf53e 12303 (const_int 1)
ad4f9e7e 12304 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
12305 (const_int 0))
12306 (clobber (reg:CC FLAGS_REG))])]
12307 "TARGET_64BIT && !TARGET_USE_BT"
12308 [(const_int 0)]
12309{
12310 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12311 rtx op1;
12312
12313 if (HOST_BITS_PER_WIDE_INT >= 64)
12314 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12315 else if (i < HOST_BITS_PER_WIDE_INT)
12316 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12317 else
12318 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12319
12320 op1 = immed_double_const (~lo, ~hi, DImode);
12321 if (i >= 32)
12322 {
12323 emit_move_insn (operands[2], op1);
12324 op1 = operands[2];
12325 }
12326
12327 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12328 DONE;
12329})
12330
12331(define_peephole2
12332 [(match_scratch:DI 2 "r")
12333 (parallel [(set (zero_extract:DI
ad4f9e7e 12334 (match_operand:DI 0 "register_operand" "")
7cacf53e 12335 (const_int 1)
ad4f9e7e 12336 (match_operand:DI 1 "const_0_to_63_operand" ""))
7cacf53e
RH
12337 (not:DI (zero_extract:DI
12338 (match_dup 0) (const_int 1) (match_dup 1))))
12339 (clobber (reg:CC FLAGS_REG))])]
12340 "TARGET_64BIT && !TARGET_USE_BT"
12341 [(const_int 0)]
12342{
12343 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12344 rtx op1;
12345
12346 if (HOST_BITS_PER_WIDE_INT >= 64)
12347 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12348 else if (i < HOST_BITS_PER_WIDE_INT)
12349 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12350 else
12351 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12352
12353 op1 = immed_double_const (lo, hi, DImode);
12354 if (i >= 31)
12355 {
12356 emit_move_insn (operands[2], op1);
12357 op1 = operands[2];
12358 }
12359
12360 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12361 DONE;
12362})
886c62d1
JVA
12363\f
12364;; Store-flag instructions.
12365
c572e5ba
JVA
12366;; For all sCOND expanders, also expand the compare or test insn that
12367;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12368
e075ae69
RH
12369;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12370;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12371;; way, which can later delete the movzx if only QImode is needed.
12372
c572e5ba 12373(define_expand "seq"
b932f770 12374 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12375 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12376 ""
3a3677ff 12377 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
c572e5ba 12378
c572e5ba 12379(define_expand "sne"
b932f770 12380 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12381 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12382 ""
3a3677ff 12383 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
c572e5ba 12384
c572e5ba 12385(define_expand "sgt"
b932f770 12386 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12387 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12388 ""
3a3677ff 12389 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
c572e5ba 12390
c572e5ba 12391(define_expand "sgtu"
b932f770 12392 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12393 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12394 ""
3a3677ff 12395 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
c572e5ba 12396
c572e5ba 12397(define_expand "slt"
b932f770 12398 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12399 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12400 ""
3a3677ff 12401 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
c572e5ba 12402
c572e5ba 12403(define_expand "sltu"
b932f770 12404 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12405 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12406 ""
3a3677ff 12407 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
c572e5ba 12408
c572e5ba 12409(define_expand "sge"
b932f770 12410 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12411 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12412 ""
3a3677ff 12413 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
c572e5ba 12414
c572e5ba 12415(define_expand "sgeu"
b932f770 12416 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12417 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12418 ""
3a3677ff 12419 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
c572e5ba 12420
c572e5ba 12421(define_expand "sle"
b932f770 12422 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12423 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
c572e5ba 12424 ""
3a3677ff 12425 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
c572e5ba 12426
c785c660 12427(define_expand "sleu"
b932f770 12428 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12429 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
c785c660 12430 ""
3a3677ff
RH
12431 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12432
12433(define_expand "sunordered"
b932f770 12434 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12435 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12436 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12437 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12438
12439(define_expand "sordered"
b932f770 12440 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12441 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
3a3677ff
RH
12442 "TARGET_80387"
12443 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12444
12445(define_expand "suneq"
b932f770 12446 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12447 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12448 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12449 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12450
12451(define_expand "sunge"
b932f770 12452 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12453 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12454 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12455 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12456
12457(define_expand "sungt"
b932f770 12458 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12459 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12460 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12461 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12462
12463(define_expand "sunle"
b932f770 12464 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12465 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12466 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12467 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12468
12469(define_expand "sunlt"
b932f770 12470 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12471 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12472 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12473 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12474
12475(define_expand "sltgt"
b932f770 12476 [(set (match_operand:QI 0 "register_operand" "")
8bc527af 12477 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
0644b628 12478 "TARGET_80387 || TARGET_SSE"
3a3677ff 12479 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
c785c660 12480
e075ae69 12481(define_insn "*setcc_1"
a269a03c 12482 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9076b9c1 12483 (match_operator:QI 1 "ix86_comparison_operator"
42fabf21 12484 [(reg FLAGS_REG) (const_int 0)]))]
e075ae69 12485 ""
0f40f9f7 12486 "set%C1\t%0"
6ef67412
JH
12487 [(set_attr "type" "setcc")
12488 (set_attr "mode" "QI")])
a269a03c 12489
93330ea1 12490(define_insn "*setcc_2"
e075ae69 12491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9076b9c1 12492 (match_operator:QI 1 "ix86_comparison_operator"
42fabf21 12493 [(reg FLAGS_REG) (const_int 0)]))]
e075ae69 12494 ""
0f40f9f7 12495 "set%C1\t%0"
6ef67412
JH
12496 [(set_attr "type" "setcc")
12497 (set_attr "mode" "QI")])
e075ae69 12498
10978207
RH
12499;; In general it is not safe to assume too much about CCmode registers,
12500;; so simplify-rtx stops when it sees a second one. Under certain
12501;; conditions this is safe on x86, so help combine not create
12502;;
12503;; seta %al
12504;; testb %al, %al
12505;; sete %al
12506
12507(define_split
12508 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12509 (ne:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 12510 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
12511 (const_int 0)))]
12512 ""
12513 [(set (match_dup 0) (match_dup 1))]
12514{
12515 PUT_MODE (operands[1], QImode);
12516})
12517
12518(define_split
12519 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12520 (ne:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 12521 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
12522 (const_int 0)))]
12523 ""
12524 [(set (match_dup 0) (match_dup 1))]
12525{
12526 PUT_MODE (operands[1], QImode);
12527})
12528
12529(define_split
12530 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12531 (eq:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 12532 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
12533 (const_int 0)))]
12534 ""
12535 [(set (match_dup 0) (match_dup 1))]
12536{
12537 rtx new_op1 = copy_rtx (operands[1]);
12538 operands[1] = new_op1;
12539 PUT_MODE (new_op1, QImode);
3c5cb3e4
KH
12540 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12541 GET_MODE (XEXP (new_op1, 0))));
10978207
RH
12542
12543 /* Make sure that (a) the CCmode we have for the flags is strong
12544 enough for the reversed compare or (b) we have a valid FP compare. */
12545 if (! ix86_comparison_operator (new_op1, VOIDmode))
12546 FAIL;
12547})
12548
12549(define_split
12550 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12551 (eq:QI (match_operator 1 "ix86_comparison_operator"
42fabf21 12552 [(reg FLAGS_REG) (const_int 0)])
10978207
RH
12553 (const_int 0)))]
12554 ""
12555 [(set (match_dup 0) (match_dup 1))]
12556{
12557 rtx new_op1 = copy_rtx (operands[1]);
12558 operands[1] = new_op1;
12559 PUT_MODE (new_op1, QImode);
3c5cb3e4
KH
12560 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12561 GET_MODE (XEXP (new_op1, 0))));
10978207
RH
12562
12563 /* Make sure that (a) the CCmode we have for the flags is strong
12564 enough for the reversed compare or (b) we have a valid FP compare. */
12565 if (! ix86_comparison_operator (new_op1, VOIDmode))
12566 FAIL;
12567})
12568
a46d1d38
JH
12569;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12570;; subsequent logical operations are used to imitate conditional moves.
12571;; 0xffffffff is NaN, but not in normalized form, so we can't represent
d1f87653 12572;; it directly. Further holding this value in pseudo register might bring
a46d1d38
JH
12573;; problem in implicit normalization in spill code.
12574;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12575;; instructions after reload by splitting the conditional move patterns.
12576
12577(define_insn "*sse_setccsf"
12578 [(set (match_operand:SF 0 "register_operand" "=x")
12579 (match_operator:SF 1 "sse_comparison_operator"
12580 [(match_operand:SF 2 "register_operand" "0")
12581 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12582 "TARGET_SSE && reload_completed"
0f40f9f7 12583 "cmp%D1ss\t{%3, %0|%0, %3}"
3d34cd91 12584 [(set_attr "type" "ssecmp")
a46d1d38
JH
12585 (set_attr "mode" "SF")])
12586
12587(define_insn "*sse_setccdf"
12588 [(set (match_operand:DF 0 "register_operand" "=Y")
12589 (match_operator:DF 1 "sse_comparison_operator"
12590 [(match_operand:DF 2 "register_operand" "0")
12591 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12592 "TARGET_SSE2 && reload_completed"
0f40f9f7 12593 "cmp%D1sd\t{%3, %0|%0, %3}"
3d34cd91 12594 [(set_attr "type" "ssecmp")
a46d1d38 12595 (set_attr "mode" "DF")])
886c62d1
JVA
12596\f
12597;; Basic conditional jump instructions.
12598;; We ignore the overflow flag for signed branch instructions.
12599
c572e5ba 12600;; For all bCOND expanders, also expand the compare or test insn that
42fabf21 12601;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
c572e5ba
JVA
12602
12603(define_expand "beq"
e075ae69
RH
12604 [(set (pc)
12605 (if_then_else (match_dup 1)
c572e5ba
JVA
12606 (label_ref (match_operand 0 "" ""))
12607 (pc)))]
12608 ""
3a3677ff 12609 "ix86_expand_branch (EQ, operands[0]); DONE;")
c572e5ba 12610
c572e5ba 12611(define_expand "bne"
e075ae69
RH
12612 [(set (pc)
12613 (if_then_else (match_dup 1)
c572e5ba
JVA
12614 (label_ref (match_operand 0 "" ""))
12615 (pc)))]
12616 ""
3a3677ff 12617 "ix86_expand_branch (NE, operands[0]); DONE;")
886c62d1 12618
c572e5ba 12619(define_expand "bgt"
e075ae69
RH
12620 [(set (pc)
12621 (if_then_else (match_dup 1)
c572e5ba
JVA
12622 (label_ref (match_operand 0 "" ""))
12623 (pc)))]
12624 ""
3a3677ff 12625 "ix86_expand_branch (GT, operands[0]); DONE;")
c572e5ba 12626
c572e5ba 12627(define_expand "bgtu"
e075ae69
RH
12628 [(set (pc)
12629 (if_then_else (match_dup 1)
c572e5ba
JVA
12630 (label_ref (match_operand 0 "" ""))
12631 (pc)))]
12632 ""
3a3677ff 12633 "ix86_expand_branch (GTU, operands[0]); DONE;")
886c62d1 12634
886c62d1 12635(define_expand "blt"
e075ae69
RH
12636 [(set (pc)
12637 (if_then_else (match_dup 1)
886c62d1
JVA
12638 (label_ref (match_operand 0 "" ""))
12639 (pc)))]
12640 ""
3a3677ff 12641 "ix86_expand_branch (LT, operands[0]); DONE;")
886c62d1 12642
c572e5ba 12643(define_expand "bltu"
e075ae69
RH
12644 [(set (pc)
12645 (if_then_else (match_dup 1)
c572e5ba
JVA
12646 (label_ref (match_operand 0 "" ""))
12647 (pc)))]
12648 ""
3a3677ff 12649 "ix86_expand_branch (LTU, operands[0]); DONE;")
c572e5ba 12650
c572e5ba 12651(define_expand "bge"
e075ae69
RH
12652 [(set (pc)
12653 (if_then_else (match_dup 1)
c572e5ba
JVA
12654 (label_ref (match_operand 0 "" ""))
12655 (pc)))]
12656 ""
3a3677ff 12657 "ix86_expand_branch (GE, operands[0]); DONE;")
c572e5ba 12658
c572e5ba 12659(define_expand "bgeu"
e075ae69
RH
12660 [(set (pc)
12661 (if_then_else (match_dup 1)
c572e5ba
JVA
12662 (label_ref (match_operand 0 "" ""))
12663 (pc)))]
12664 ""
3a3677ff 12665 "ix86_expand_branch (GEU, operands[0]); DONE;")
886c62d1 12666
886c62d1 12667(define_expand "ble"
e075ae69
RH
12668 [(set (pc)
12669 (if_then_else (match_dup 1)
886c62d1
JVA
12670 (label_ref (match_operand 0 "" ""))
12671 (pc)))]
12672 ""
3a3677ff 12673 "ix86_expand_branch (LE, operands[0]); DONE;")
886c62d1 12674
c572e5ba 12675(define_expand "bleu"
e075ae69
RH
12676 [(set (pc)
12677 (if_then_else (match_dup 1)
c572e5ba
JVA
12678 (label_ref (match_operand 0 "" ""))
12679 (pc)))]
12680 ""
3a3677ff
RH
12681 "ix86_expand_branch (LEU, operands[0]); DONE;")
12682
12683(define_expand "bunordered"
12684 [(set (pc)
12685 (if_then_else (match_dup 1)
12686 (label_ref (match_operand 0 "" ""))
12687 (pc)))]
eaa49b49 12688 "TARGET_80387 || TARGET_SSE_MATH"
3a3677ff
RH
12689 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12690
12691(define_expand "bordered"
12692 [(set (pc)
12693 (if_then_else (match_dup 1)
12694 (label_ref (match_operand 0 "" ""))
12695 (pc)))]
eaa49b49 12696 "TARGET_80387 || TARGET_SSE_MATH"
3a3677ff
RH
12697 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12698
12699(define_expand "buneq"
12700 [(set (pc)
12701 (if_then_else (match_dup 1)
12702 (label_ref (match_operand 0 "" ""))
12703 (pc)))]
eaa49b49 12704 "TARGET_80387 || TARGET_SSE_MATH"
3a3677ff
RH
12705 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12706
12707(define_expand "bunge"
12708 [(set (pc)
12709 (if_then_else (match_dup 1)
12710 (label_ref (match_operand 0 "" ""))
12711 (pc)))]
eaa49b49 12712 "TARGET_80387 || TARGET_SSE_MATH"
3a3677ff
RH
12713 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12714
12715(define_expand "bungt"
12716 [(set (pc)
12717 (if_then_else (match_dup 1)
12718 (label_ref (match_operand 0 "" ""))
12719 (pc)))]
eaa49b49 12720 "TARGET_80387 || TARGET_SSE_MATH"
3a3677ff
RH
12721 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12722
12723(define_expand "bunle"
12724 [(set (pc)
12725 (if_then_else (match_dup 1)
12726 (label_ref (match_operand 0 "" ""))
12727 (pc)))]
eaa49b49 12728 "TARGET_80387 || TARGET_SSE_MATH"
3a3677ff
RH
12729 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12730
12731(define_expand "bunlt"
12732 [(set (pc)
12733 (if_then_else (match_dup 1)
12734 (label_ref (match_operand 0 "" ""))
12735 (pc)))]
eaa49b49 12736 "TARGET_80387 || TARGET_SSE_MATH"
3a3677ff
RH
12737 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12738
12739(define_expand "bltgt"
12740 [(set (pc)
12741 (if_then_else (match_dup 1)
12742 (label_ref (match_operand 0 "" ""))
12743 (pc)))]
eaa49b49 12744 "TARGET_80387 || TARGET_SSE_MATH"
3a3677ff 12745 "ix86_expand_branch (LTGT, operands[0]); DONE;")
886c62d1 12746
e075ae69
RH
12747(define_insn "*jcc_1"
12748 [(set (pc)
9076b9c1 12749 (if_then_else (match_operator 1 "ix86_comparison_operator"
42fabf21 12750 [(reg FLAGS_REG) (const_int 0)])
6ef67412 12751 (label_ref (match_operand 0 "" ""))
e075ae69
RH
12752 (pc)))]
12753 ""
0f40f9f7 12754 "%+j%C1\t%l0"
e075ae69 12755 [(set_attr "type" "ibr")
c7375e61 12756 (set_attr "modrm" "0")
efcc7037 12757 (set (attr "length")
6ef67412 12758 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 12759 (const_int -126))
6ef67412 12760 (lt (minus (match_dup 0) (pc))
db1077d3 12761 (const_int 128)))
efcc7037
JH
12762 (const_int 2)
12763 (const_int 6)))])
e075ae69
RH
12764
12765(define_insn "*jcc_2"
12766 [(set (pc)
9076b9c1 12767 (if_then_else (match_operator 1 "ix86_comparison_operator"
42fabf21 12768 [(reg FLAGS_REG) (const_int 0)])
e075ae69 12769 (pc)
6ef67412 12770 (label_ref (match_operand 0 "" ""))))]
e075ae69 12771 ""
0f40f9f7 12772 "%+j%c1\t%l0"
e075ae69 12773 [(set_attr "type" "ibr")
c7375e61 12774 (set_attr "modrm" "0")
efcc7037 12775 (set (attr "length")
6ef67412 12776 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 12777 (const_int -126))
6ef67412 12778 (lt (minus (match_dup 0) (pc))
db1077d3 12779 (const_int 128)))
efcc7037
JH
12780 (const_int 2)
12781 (const_int 6)))])
e075ae69 12782
592188a5
RH
12783;; In general it is not safe to assume too much about CCmode registers,
12784;; so simplify-rtx stops when it sees a second one. Under certain
12785;; conditions this is safe on x86, so help combine not create
12786;;
12787;; seta %al
12788;; testb %al, %al
12789;; je Lfoo
12790
12791(define_split
12792 [(set (pc)
12793 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
42fabf21 12794 [(reg FLAGS_REG) (const_int 0)])
592188a5
RH
12795 (const_int 0))
12796 (label_ref (match_operand 1 "" ""))
12797 (pc)))]
12798 ""
12799 [(set (pc)
12800 (if_then_else (match_dup 0)
12801 (label_ref (match_dup 1))
12802 (pc)))]
12803{
12804 PUT_MODE (operands[0], VOIDmode);
12805})
12806
12807(define_split
12808 [(set (pc)
12809 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
42fabf21 12810 [(reg FLAGS_REG) (const_int 0)])
592188a5
RH
12811 (const_int 0))
12812 (label_ref (match_operand 1 "" ""))
12813 (pc)))]
12814 ""
12815 [(set (pc)
12816 (if_then_else (match_dup 0)
12817 (label_ref (match_dup 1))
12818 (pc)))]
12819{
12820 rtx new_op0 = copy_rtx (operands[0]);
12821 operands[0] = new_op0;
12822 PUT_MODE (new_op0, VOIDmode);
3c5cb3e4
KH
12823 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12824 GET_MODE (XEXP (new_op0, 0))));
592188a5
RH
12825
12826 /* Make sure that (a) the CCmode we have for the flags is strong
12827 enough for the reversed compare or (b) we have a valid FP compare. */
12828 if (! ix86_comparison_operator (new_op0, VOIDmode))
12829 FAIL;
12830})
12831
3a3677ff
RH
12832;; Define combination compare-and-branch fp compare instructions to use
12833;; during early optimization. Splitting the operation apart early makes
12834;; for bad code when we want to reverse the operation.
12835
eaa49b49 12836(define_insn "*fp_jcc_1_mixed"
3a3677ff
RH
12837 [(set (pc)
12838 (if_then_else (match_operator 0 "comparison_operator"
eaa49b49
RH
12839 [(match_operand 1 "register_operand" "f#x,x#f")
12840 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
3a3677ff
RH
12841 (label_ref (match_operand 3 "" ""))
12842 (pc)))
8bc527af
SB
12843 (clobber (reg:CCFP FPSR_REG))
12844 (clobber (reg:CCFP FLAGS_REG))]
eaa49b49
RH
12845 "TARGET_MIX_SSE_I387
12846 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12847 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12848 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12849 "#")
12850
0644b628
JH
12851(define_insn "*fp_jcc_1_sse"
12852 [(set (pc)
12853 (if_then_else (match_operator 0 "comparison_operator"
eaa49b49
RH
12854 [(match_operand 1 "register_operand" "x")
12855 (match_operand 2 "nonimmediate_operand" "xm")])
0644b628
JH
12856 (label_ref (match_operand 3 "" ""))
12857 (pc)))
8bc527af
SB
12858 (clobber (reg:CCFP FPSR_REG))
12859 (clobber (reg:CCFP FLAGS_REG))]
eaa49b49 12860 "TARGET_SSE_MATH
0644b628 12861 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12862 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12863 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12864 "#")
12865
eaa49b49 12866(define_insn "*fp_jcc_1_387"
0644b628
JH
12867 [(set (pc)
12868 (if_then_else (match_operator 0 "comparison_operator"
eaa49b49
RH
12869 [(match_operand 1 "register_operand" "f")
12870 (match_operand 2 "register_operand" "f")])
0644b628
JH
12871 (label_ref (match_operand 3 "" ""))
12872 (pc)))
8bc527af
SB
12873 (clobber (reg:CCFP FPSR_REG))
12874 (clobber (reg:CCFP FLAGS_REG))]
eaa49b49
RH
12875 "TARGET_CMOVE && TARGET_80387
12876 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12877 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12878 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12879 "#")
12880
eaa49b49 12881(define_insn "*fp_jcc_2_mixed"
3a3677ff
RH
12882 [(set (pc)
12883 (if_then_else (match_operator 0 "comparison_operator"
eaa49b49
RH
12884 [(match_operand 1 "register_operand" "f#x,x#f")
12885 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
3a3677ff
RH
12886 (pc)
12887 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
12888 (clobber (reg:CCFP FPSR_REG))
12889 (clobber (reg:CCFP FLAGS_REG))]
eaa49b49
RH
12890 "TARGET_MIX_SSE_I387
12891 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12892 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12893 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12894 "#")
12895
0644b628
JH
12896(define_insn "*fp_jcc_2_sse"
12897 [(set (pc)
12898 (if_then_else (match_operator 0 "comparison_operator"
eaa49b49
RH
12899 [(match_operand 1 "register_operand" "x")
12900 (match_operand 2 "nonimmediate_operand" "xm")])
0644b628
JH
12901 (pc)
12902 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
12903 (clobber (reg:CCFP FPSR_REG))
12904 (clobber (reg:CCFP FLAGS_REG))]
eaa49b49 12905 "TARGET_SSE_MATH
0644b628 12906 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12907 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12908 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12909 "#")
12910
eaa49b49 12911(define_insn "*fp_jcc_2_387"
0644b628
JH
12912 [(set (pc)
12913 (if_then_else (match_operator 0 "comparison_operator"
eaa49b49
RH
12914 [(match_operand 1 "register_operand" "f")
12915 (match_operand 2 "register_operand" "f")])
0644b628
JH
12916 (pc)
12917 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
12918 (clobber (reg:CCFP FPSR_REG))
12919 (clobber (reg:CCFP FLAGS_REG))]
eaa49b49
RH
12920 "TARGET_CMOVE && TARGET_80387
12921 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12922 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12923 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12924 "#")
12925
eaa49b49 12926(define_insn "*fp_jcc_3_387"
3a3677ff 12927 [(set (pc)
b1cdafbb 12928 (if_then_else (match_operator 0 "comparison_operator"
3a3677ff
RH
12929 [(match_operand 1 "register_operand" "f")
12930 (match_operand 2 "nonimmediate_operand" "fm")])
12931 (label_ref (match_operand 3 "" ""))
12932 (pc)))
8bc527af
SB
12933 (clobber (reg:CCFP FPSR_REG))
12934 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
12935 (clobber (match_scratch:HI 4 "=a"))]
12936 "TARGET_80387
12937 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 12938 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb
JH
12939 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12940 && SELECT_CC_MODE (GET_CODE (operands[0]),
03598dea
JH
12941 operands[1], operands[2]) == CCFPmode
12942 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12943 "#")
12944
eaa49b49 12945(define_insn "*fp_jcc_4_387"
3a3677ff 12946 [(set (pc)
b1cdafbb 12947 (if_then_else (match_operator 0 "comparison_operator"
3a3677ff
RH
12948 [(match_operand 1 "register_operand" "f")
12949 (match_operand 2 "nonimmediate_operand" "fm")])
12950 (pc)
12951 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
12952 (clobber (reg:CCFP FPSR_REG))
12953 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
12954 (clobber (match_scratch:HI 4 "=a"))]
12955 "TARGET_80387
12956 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 12957 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb
JH
12958 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12959 && SELECT_CC_MODE (GET_CODE (operands[0]),
03598dea
JH
12960 operands[1], operands[2]) == CCFPmode
12961 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12962 "#")
12963
eaa49b49 12964(define_insn "*fp_jcc_5_387"
3a3677ff
RH
12965 [(set (pc)
12966 (if_then_else (match_operator 0 "comparison_operator"
12967 [(match_operand 1 "register_operand" "f")
12968 (match_operand 2 "register_operand" "f")])
12969 (label_ref (match_operand 3 "" ""))
12970 (pc)))
8bc527af
SB
12971 (clobber (reg:CCFP FPSR_REG))
12972 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
12973 (clobber (match_scratch:HI 4 "=a"))]
12974 "TARGET_80387
12975 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12976 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12977 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12978 "#")
12979
eaa49b49 12980(define_insn "*fp_jcc_6_387"
3a3677ff
RH
12981 [(set (pc)
12982 (if_then_else (match_operator 0 "comparison_operator"
12983 [(match_operand 1 "register_operand" "f")
12984 (match_operand 2 "register_operand" "f")])
12985 (pc)
12986 (label_ref (match_operand 3 "" ""))))
8bc527af
SB
12987 (clobber (reg:CCFP FPSR_REG))
12988 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
12989 (clobber (match_scratch:HI 4 "=a"))]
12990 "TARGET_80387
12991 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12992 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12993 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12994 "#")
12995
eaa49b49 12996(define_insn "*fp_jcc_7_387"
45c8c47f
UB
12997 [(set (pc)
12998 (if_then_else (match_operator 0 "comparison_operator"
12999 [(match_operand 1 "register_operand" "f")
13000 (match_operand 2 "const_double_operand" "C")])
13001 (label_ref (match_operand 3 "" ""))
13002 (pc)))
13003 (clobber (reg:CCFP FPSR_REG))
13004 (clobber (reg:CCFP FLAGS_REG))
13005 (clobber (match_scratch:HI 4 "=a"))]
13006 "TARGET_80387
13007 && FLOAT_MODE_P (GET_MODE (operands[1]))
13008 && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13009 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13010 && SELECT_CC_MODE (GET_CODE (operands[0]),
13011 operands[1], operands[2]) == CCFPmode
13012 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13013 "#")
13014
7c82106f
UB
13015;; The order of operands in *fp_jcc_8 is forced by combine in
13016;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13017;; with a precedence over other operators and is always put in the first
13018;; place. Swap condition and operands to match ficom instruction.
13019
eaa49b49 13020(define_insn "*fp_jcc_8_387"
7c82106f
UB
13021 [(set (pc)
13022 (if_then_else (match_operator 0 "comparison_operator"
13023 [(match_operator 1 "float_operator"
13024 [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13025 (match_operand 3 "register_operand" "f,f")])
13026 (label_ref (match_operand 4 "" ""))
13027 (pc)))
13028 (clobber (reg:CCFP FPSR_REG))
13029 (clobber (reg:CCFP FLAGS_REG))
13030 (clobber (match_scratch:HI 5 "=a,a"))]
13031 "TARGET_80387 && TARGET_USE_FIOP
13032 && FLOAT_MODE_P (GET_MODE (operands[3]))
13033 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13034 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13035 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13036 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13037 "#")
13038
3a3677ff
RH
13039(define_split
13040 [(set (pc)
13041 (if_then_else (match_operator 0 "comparison_operator"
13042 [(match_operand 1 "register_operand" "")
13043 (match_operand 2 "nonimmediate_operand" "")])
13044 (match_operand 3 "" "")
13045 (match_operand 4 "" "")))
8bc527af
SB
13046 (clobber (reg:CCFP FPSR_REG))
13047 (clobber (reg:CCFP FLAGS_REG))]
3a3677ff 13048 "reload_completed"
9e7adcb3 13049 [(const_int 0)]
3a3677ff 13050{
03598dea 13051 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
7c82106f 13052 operands[3], operands[4], NULL_RTX, NULL_RTX);
9e7adcb3 13053 DONE;
0f40f9f7 13054})
3a3677ff
RH
13055
13056(define_split
13057 [(set (pc)
13058 (if_then_else (match_operator 0 "comparison_operator"
13059 [(match_operand 1 "register_operand" "")
45c8c47f 13060 (match_operand 2 "general_operand" "")])
3a3677ff
RH
13061 (match_operand 3 "" "")
13062 (match_operand 4 "" "")))
8bc527af
SB
13063 (clobber (reg:CCFP FPSR_REG))
13064 (clobber (reg:CCFP FLAGS_REG))
3a3677ff
RH
13065 (clobber (match_scratch:HI 5 "=a"))]
13066 "reload_completed"
45c8c47f 13067 [(const_int 0)]
3a3677ff 13068{
03598dea 13069 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
7c82106f
UB
13070 operands[3], operands[4], operands[5], NULL_RTX);
13071 DONE;
13072})
13073
13074(define_split
13075 [(set (pc)
13076 (if_then_else (match_operator 0 "comparison_operator"
13077 [(match_operator 1 "float_operator"
13078 [(match_operand:SI 2 "memory_operand" "")])
13079 (match_operand 3 "register_operand" "")])
13080 (match_operand 4 "" "")
13081 (match_operand 5 "" "")))
13082 (clobber (reg:CCFP FPSR_REG))
13083 (clobber (reg:CCFP FLAGS_REG))
13084 (clobber (match_scratch:HI 6 "=a"))]
13085 "reload_completed"
13086 [(const_int 0)]
13087{
13088 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13089 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13090 operands[3], operands[7],
13091 operands[4], operands[5], operands[6], NULL_RTX);
13092 DONE;
13093})
13094
13095;; %%% Kill this when reload knows how to do it.
13096(define_split
13097 [(set (pc)
13098 (if_then_else (match_operator 0 "comparison_operator"
13099 [(match_operator 1 "float_operator"
13100 [(match_operand:SI 2 "register_operand" "")])
13101 (match_operand 3 "register_operand" "")])
13102 (match_operand 4 "" "")
13103 (match_operand 5 "" "")))
13104 (clobber (reg:CCFP FPSR_REG))
13105 (clobber (reg:CCFP FLAGS_REG))
13106 (clobber (match_scratch:HI 6 "=a"))]
13107 "reload_completed"
13108 [(const_int 0)]
13109{
13110 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13111 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13112 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13113 operands[3], operands[7],
13114 operands[4], operands[5], operands[6], operands[2]);
9e7adcb3 13115 DONE;
0f40f9f7 13116})
886c62d1
JVA
13117\f
13118;; Unconditional and other jump instructions
13119
13120(define_insn "jump"
13121 [(set (pc)
13122 (label_ref (match_operand 0 "" "")))]
13123 ""
0f40f9f7 13124 "jmp\t%l0"
c7375e61 13125 [(set_attr "type" "ibr")
efcc7037
JH
13126 (set (attr "length")
13127 (if_then_else (and (ge (minus (match_dup 0) (pc))
db1077d3 13128 (const_int -126))
efcc7037 13129 (lt (minus (match_dup 0) (pc))
db1077d3 13130 (const_int 128)))
efcc7037
JH
13131 (const_int 2)
13132 (const_int 5)))
c7375e61 13133 (set_attr "modrm" "0")])
886c62d1 13134
14f73b5a
JH
13135(define_expand "indirect_jump"
13136 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
886c62d1 13137 ""
14f73b5a
JH
13138 "")
13139
13140(define_insn "*indirect_jump"
13141 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13142 "!TARGET_64BIT"
13143 "jmp\t%A0"
13144 [(set_attr "type" "ibr")
13145 (set_attr "length_immediate" "0")])
13146
13147(define_insn "*indirect_jump_rtx64"
13148 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13149 "TARGET_64BIT"
0f40f9f7 13150 "jmp\t%A0"
6ef67412
JH
13151 [(set_attr "type" "ibr")
13152 (set_attr "length_immediate" "0")])
4801403e 13153
90675921 13154(define_expand "tablejump"
6eb791fc 13155 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
90675921
RH
13156 (use (label_ref (match_operand 1 "" "")))])]
13157 ""
13158{
66edd3b4
RH
13159 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13160 relative. Convert the relative address to an absolute address. */
90675921
RH
13161 if (flag_pic)
13162 {
66edd3b4
RH
13163 rtx op0, op1;
13164 enum rtx_code code;
13165
6eb791fc 13166 if (TARGET_64BIT)
66edd3b4
RH
13167 {
13168 code = PLUS;
13169 op0 = operands[0];
13170 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13171 }
b069de3b 13172 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
f88c65f7 13173 {
66edd3b4
RH
13174 code = PLUS;
13175 op0 = operands[0];
13176 op1 = pic_offset_table_rtx;
f88c65f7 13177 }
6eb791fc
JH
13178 else
13179 {
66edd3b4
RH
13180 code = MINUS;
13181 op0 = pic_offset_table_rtx;
13182 op1 = operands[0];
6eb791fc 13183 }
66edd3b4 13184
c16576e6 13185 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
66edd3b4 13186 OPTAB_DIRECT);
90675921 13187 }
0f40f9f7 13188})
2bb7a0f5 13189
90675921 13190(define_insn "*tablejump_1"
2ae0f82c 13191 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
886c62d1 13192 (use (label_ref (match_operand 1 "" "")))]
14f73b5a
JH
13193 "!TARGET_64BIT"
13194 "jmp\t%A0"
13195 [(set_attr "type" "ibr")
13196 (set_attr "length_immediate" "0")])
13197
13198(define_insn "*tablejump_1_rtx64"
13199 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13200 (use (label_ref (match_operand 1 "" "")))]
13201 "TARGET_64BIT"
0f40f9f7 13202 "jmp\t%A0"
6ef67412
JH
13203 [(set_attr "type" "ibr")
13204 (set_attr "length_immediate" "0")])
e075ae69
RH
13205\f
13206;; Loop instruction
13207;;
13208;; This is all complicated by the fact that since this is a jump insn
13209;; we must handle our own reloads.
13210
5527bf14
RH
13211(define_expand "doloop_end"
13212 [(use (match_operand 0 "" "")) ; loop pseudo
13213 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13214 (use (match_operand 2 "" "")) ; max iterations
13215 (use (match_operand 3 "" "")) ; loop level
13216 (use (match_operand 4 "" ""))] ; label
1b0c37d7 13217 "!TARGET_64BIT && TARGET_USE_LOOP"
5527bf14
RH
13218 "
13219{
13220 /* Only use cloop on innermost loops. */
13221 if (INTVAL (operands[3]) > 1)
13222 FAIL;
13223 if (GET_MODE (operands[0]) != SImode)
13224 FAIL;
13225 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13226 operands[0]));
13227 DONE;
13228}")
e075ae69 13229
5527bf14 13230(define_insn "doloop_end_internal"
e075ae69 13231 [(set (pc)
5527bf14 13232 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
e075ae69
RH
13233 (const_int 1))
13234 (label_ref (match_operand 0 "" ""))
13235 (pc)))
e0c34369 13236 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
e075ae69
RH
13237 (plus:SI (match_dup 1)
13238 (const_int -1)))
13239 (clobber (match_scratch:SI 3 "=X,X,r"))
8bc527af 13240 (clobber (reg:CC FLAGS_REG))]
e0c34369
JW
13241 "!TARGET_64BIT && TARGET_USE_LOOP
13242 && (reload_in_progress || reload_completed
13243 || register_operand (operands[2], VOIDmode))"
e075ae69
RH
13244{
13245 if (which_alternative != 0)
0f40f9f7 13246 return "#";
e075ae69 13247 if (get_attr_length (insn) == 2)
0f40f9f7 13248 return "%+loop\t%l0";
e075ae69 13249 else
0f40f9f7
ZW
13250 return "dec{l}\t%1\;%+jne\t%l0";
13251}
56bab446 13252 [(set (attr "length")
c7375e61
EB
13253 (if_then_else (and (eq_attr "alternative" "0")
13254 (and (ge (minus (match_dup 0) (pc))
db1077d3 13255 (const_int -126))
c7375e61 13256 (lt (minus (match_dup 0) (pc))
db1077d3 13257 (const_int 128))))
c7375e61
EB
13258 (const_int 2)
13259 (const_int 16)))
efcc7037
JH
13260 ;; We don't know the type before shorten branches. Optimistically expect
13261 ;; the loop instruction to match.
13262 (set (attr "type") (const_string "ibr"))])
e075ae69 13263
e075ae69
RH
13264(define_split
13265 [(set (pc)
13266 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13267 (const_int 1))
13268 (match_operand 0 "" "")
13269 (pc)))
5527bf14 13270 (set (match_dup 1)
e075ae69
RH
13271 (plus:SI (match_dup 1)
13272 (const_int -1)))
5527bf14 13273 (clobber (match_scratch:SI 2 ""))
8bc527af 13274 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 13275 "!TARGET_64BIT && TARGET_USE_LOOP
5527bf14
RH
13276 && reload_completed
13277 && REGNO (operands[1]) != 2"
8bc527af 13278 [(parallel [(set (reg:CCZ FLAGS_REG)
5527bf14 13279 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
e075ae69 13280 (const_int 0)))
5527bf14 13281 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
8bc527af 13282 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
e075ae69
RH
13283 (match_dup 0)
13284 (pc)))]
13285 "")
13286
13287(define_split
13288 [(set (pc)
13289 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13290 (const_int 1))
13291 (match_operand 0 "" "")
13292 (pc)))
5527bf14 13293 (set (match_operand:SI 2 "nonimmediate_operand" "")
e075ae69
RH
13294 (plus:SI (match_dup 1)
13295 (const_int -1)))
13296 (clobber (match_scratch:SI 3 ""))
8bc527af 13297 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 13298 "!TARGET_64BIT && TARGET_USE_LOOP
5527bf14
RH
13299 && reload_completed
13300 && (! REG_P (operands[2])
13301 || ! rtx_equal_p (operands[1], operands[2]))"
e075ae69 13302 [(set (match_dup 3) (match_dup 1))
8bc527af 13303 (parallel [(set (reg:CCZ FLAGS_REG)
16189740
RH
13304 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13305 (const_int 0)))
e075ae69
RH
13306 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13307 (set (match_dup 2) (match_dup 3))
8bc527af 13308 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
e075ae69
RH
13309 (match_dup 0)
13310 (pc)))]
13311 "")
c50e5bc0
RH
13312
13313;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13314
13315(define_peephole2
42fabf21 13316 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
c50e5bc0
RH
13317 (set (match_operand:QI 1 "register_operand" "")
13318 (match_operator:QI 2 "ix86_comparison_operator"
42fabf21 13319 [(reg FLAGS_REG) (const_int 0)]))
c50e5bc0
RH
13320 (set (match_operand 3 "q_regs_operand" "")
13321 (zero_extend (match_dup 1)))]
646ded90
RH
13322 "(peep2_reg_dead_p (3, operands[1])
13323 || operands_match_p (operands[1], operands[3]))
c50e5bc0 13324 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
646ded90
RH
13325 [(set (match_dup 4) (match_dup 0))
13326 (set (strict_low_part (match_dup 5))
13327 (match_dup 2))]
13328{
13329 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1e2115dc 13330 operands[5] = gen_lowpart (QImode, operands[3]);
a8bac9ab 13331 ix86_expand_clear (operands[3]);
646ded90
RH
13332})
13333
13334;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13335
13336(define_peephole2
42fabf21 13337 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
646ded90
RH
13338 (set (match_operand:QI 1 "register_operand" "")
13339 (match_operator:QI 2 "ix86_comparison_operator"
42fabf21 13340 [(reg FLAGS_REG) (const_int 0)]))
646ded90
RH
13341 (parallel [(set (match_operand 3 "q_regs_operand" "")
13342 (zero_extend (match_dup 1)))
8bc527af 13343 (clobber (reg:CC FLAGS_REG))])]
646ded90
RH
13344 "(peep2_reg_dead_p (3, operands[1])
13345 || operands_match_p (operands[1], operands[3]))
13346 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13347 [(set (match_dup 4) (match_dup 0))
c50e5bc0
RH
13348 (set (strict_low_part (match_dup 5))
13349 (match_dup 2))]
646ded90
RH
13350{
13351 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1e2115dc 13352 operands[5] = gen_lowpart (QImode, operands[3]);
a8bac9ab 13353 ix86_expand_clear (operands[3]);
646ded90 13354})
e075ae69
RH
13355\f
13356;; Call instructions.
2bb7a0f5 13357
cbbf65e0
RH
13358;; The predicates normally associated with named expanders are not properly
13359;; checked for calls. This is a bug in the generic code, but it isn't that
13360;; easy to fix. Ignore it for now and be prepared to fix things up.
2bb7a0f5 13361
886c62d1
JVA
13362;; Call subroutine returning no value.
13363
2bb7a0f5 13364(define_expand "call_pop"
cbbf65e0
RH
13365 [(parallel [(call (match_operand:QI 0 "" "")
13366 (match_operand:SI 1 "" ""))
8bc527af
SB
13367 (set (reg:SI SP_REG)
13368 (plus:SI (reg:SI SP_REG)
cbbf65e0 13369 (match_operand:SI 3 "" "")))])]
1e07edd3 13370 "!TARGET_64BIT"
2bb7a0f5 13371{
4977bab6 13372 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
0e07aff3 13373 DONE;
0f40f9f7 13374})
2bb7a0f5 13375
94bb5d0c 13376(define_insn "*call_pop_0"
e1ff012c 13377 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
94bb5d0c 13378 (match_operand:SI 1 "" ""))
8bc527af 13379 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 13380 (match_operand:SI 2 "immediate_operand" "")))]
1e07edd3 13381 "!TARGET_64BIT"
94bb5d0c
RH
13382{
13383 if (SIBLING_CALL_P (insn))
0f40f9f7 13384 return "jmp\t%P0";
94bb5d0c 13385 else
0f40f9f7
ZW
13386 return "call\t%P0";
13387}
94bb5d0c
RH
13388 [(set_attr "type" "call")])
13389
cbbf65e0 13390(define_insn "*call_pop_1"
e1ff012c 13391 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
94bb5d0c 13392 (match_operand:SI 1 "" ""))
8bc527af 13393 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 13394 (match_operand:SI 2 "immediate_operand" "i")))]
1e07edd3 13395 "!TARGET_64BIT"
886c62d1 13396{
e1ff012c 13397 if (constant_call_address_operand (operands[0], Pmode))
94bb5d0c
RH
13398 {
13399 if (SIBLING_CALL_P (insn))
0f40f9f7 13400 return "jmp\t%P0";
94bb5d0c 13401 else
0f40f9f7 13402 return "call\t%P0";
94bb5d0c 13403 }
94bb5d0c 13404 if (SIBLING_CALL_P (insn))
0f40f9f7 13405 return "jmp\t%A0";
94bb5d0c 13406 else
0f40f9f7
ZW
13407 return "call\t%A0";
13408}
e075ae69 13409 [(set_attr "type" "call")])
886c62d1 13410
2bb7a0f5 13411(define_expand "call"
cbbf65e0 13412 [(call (match_operand:QI 0 "" "")
39d04363
JH
13413 (match_operand 1 "" ""))
13414 (use (match_operand 2 "" ""))]
2bb7a0f5 13415 ""
2bb7a0f5 13416{
4977bab6
ZW
13417 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13418 DONE;
13419})
13420
13421(define_expand "sibcall"
13422 [(call (match_operand:QI 0 "" "")
13423 (match_operand 1 "" ""))
13424 (use (match_operand 2 "" ""))]
13425 ""
13426{
13427 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
0e07aff3 13428 DONE;
0f40f9f7 13429})
2bb7a0f5 13430
94bb5d0c 13431(define_insn "*call_0"
32ee7d1d
JH
13432 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13433 (match_operand 1 "" ""))]
94bb5d0c 13434 ""
94bb5d0c
RH
13435{
13436 if (SIBLING_CALL_P (insn))
0f40f9f7 13437 return "jmp\t%P0";
94bb5d0c 13438 else
0f40f9f7
ZW
13439 return "call\t%P0";
13440}
94bb5d0c
RH
13441 [(set_attr "type" "call")])
13442
cbbf65e0 13443(define_insn "*call_1"
e1ff012c 13444 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
32ee7d1d 13445 (match_operand 1 "" ""))]
4977bab6 13446 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
32ee7d1d 13447{
e427abbf 13448 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
13449 return "call\t%P0";
13450 return "call\t%A0";
13451}
13452 [(set_attr "type" "call")])
13453
13454(define_insn "*sibcall_1"
13455 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13456 (match_operand 1 "" ""))]
13457 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13458{
e427abbf 13459 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
13460 return "jmp\t%P0";
13461 return "jmp\t%A0";
0f40f9f7 13462}
32ee7d1d
JH
13463 [(set_attr "type" "call")])
13464
13465(define_insn "*call_1_rex64"
13466 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13467 (match_operand 1 "" ""))]
4977bab6 13468 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
886c62d1 13469{
e427abbf 13470 if (constant_call_address_operand (operands[0], Pmode))
4977bab6
ZW
13471 return "call\t%P0";
13472 return "call\t%A0";
0f40f9f7 13473}
e075ae69 13474 [(set_attr "type" "call")])
886c62d1 13475
4977bab6
ZW
13476(define_insn "*sibcall_1_rex64"
13477 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13478 (match_operand 1 "" ""))]
13479 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13480 "jmp\t%P0"
13481 [(set_attr "type" "call")])
13482
13483(define_insn "*sibcall_1_rex64_v"
13484 [(call (mem:QI (reg:DI 40))
13485 (match_operand 0 "" ""))]
13486 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13487 "jmp\t*%%r11"
13488 [(set_attr "type" "call")])
13489
13490
886c62d1 13491;; Call subroutine, returning value in operand 0
886c62d1 13492
2bb7a0f5
RS
13493(define_expand "call_value_pop"
13494 [(parallel [(set (match_operand 0 "" "")
cbbf65e0
RH
13495 (call (match_operand:QI 1 "" "")
13496 (match_operand:SI 2 "" "")))
8bc527af
SB
13497 (set (reg:SI SP_REG)
13498 (plus:SI (reg:SI SP_REG)
cbbf65e0 13499 (match_operand:SI 4 "" "")))])]
1e07edd3 13500 "!TARGET_64BIT"
2bb7a0f5 13501{
0e07aff3 13502 ix86_expand_call (operands[0], operands[1], operands[2],
4977bab6 13503 operands[3], operands[4], 0);
0e07aff3 13504 DONE;
0f40f9f7 13505})
2bb7a0f5 13506
2bb7a0f5
RS
13507(define_expand "call_value"
13508 [(set (match_operand 0 "" "")
cbbf65e0 13509 (call (match_operand:QI 1 "" "")
39d04363
JH
13510 (match_operand:SI 2 "" "")))
13511 (use (match_operand:SI 3 "" ""))]
2bb7a0f5
RS
13512 ;; Operand 2 not used on the i386.
13513 ""
2bb7a0f5 13514{
4977bab6
ZW
13515 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13516 DONE;
13517})
13518
13519(define_expand "sibcall_value"
13520 [(set (match_operand 0 "" "")
13521 (call (match_operand:QI 1 "" "")
13522 (match_operand:SI 2 "" "")))
13523 (use (match_operand:SI 3 "" ""))]
13524 ;; Operand 2 not used on the i386.
13525 ""
13526{
13527 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
39d04363 13528 DONE;
0f40f9f7 13529})
2bb7a0f5 13530
b840bfb0
MM
13531;; Call subroutine returning any type.
13532
576182a3 13533(define_expand "untyped_call"
b840bfb0 13534 [(parallel [(call (match_operand 0 "" "")
576182a3 13535 (const_int 0))
b840bfb0 13536 (match_operand 1 "" "")
576182a3
TW
13537 (match_operand 2 "" "")])]
13538 ""
576182a3 13539{
b840bfb0 13540 int i;
576182a3 13541
d8b679b9
RK
13542 /* In order to give reg-stack an easier job in validating two
13543 coprocessor registers as containing a possible return value,
13544 simply pretend the untyped call returns a complex long double
13545 value. */
74775c7a 13546
0e07aff3
RH
13547 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13548 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13549 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
4977bab6 13550 NULL, 0);
576182a3 13551
b840bfb0 13552 for (i = 0; i < XVECLEN (operands[2], 0); i++)
576182a3 13553 {
b840bfb0
MM
13554 rtx set = XVECEXP (operands[2], 0, i);
13555 emit_move_insn (SET_DEST (set), SET_SRC (set));
576182a3 13556 }
576182a3 13557
b840bfb0
MM
13558 /* The optimizer does not know that the call sets the function value
13559 registers we stored in the result block. We avoid problems by
13560 claiming that all hard registers are used and clobbered at this
13561 point. */
66edd3b4 13562 emit_insn (gen_blockage (const0_rtx));
576182a3
TW
13563
13564 DONE;
0f40f9f7 13565})
e075ae69
RH
13566\f
13567;; Prologue and epilogue instructions
576182a3 13568
b840bfb0
MM
13569;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13570;; all of memory. This blocks insns from being moved across this point.
13571
13572(define_insn "blockage"
66edd3b4 13573 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
576182a3 13574 ""
90aec2cf 13575 ""
e075ae69 13576 [(set_attr "length" "0")])
576182a3 13577
886c62d1
JVA
13578;; Insn emitted into the body of a function to return from a function.
13579;; This is only done if the function's epilogue is known to be simple.
182a4620 13580;; See comments for ix86_can_use_return_insn_p in i386.c.
886c62d1 13581
5f3d14e3 13582(define_expand "return"
886c62d1 13583 [(return)]
5f3d14e3 13584 "ix86_can_use_return_insn_p ()"
9a7372d6
RH
13585{
13586 if (current_function_pops_args)
13587 {
13588 rtx popc = GEN_INT (current_function_pops_args);
13589 emit_jump_insn (gen_return_pop_internal (popc));
13590 DONE;
13591 }
0f40f9f7 13592})
5f3d14e3
SC
13593
13594(define_insn "return_internal"
13595 [(return)]
13596 "reload_completed"
90aec2cf 13597 "ret"
6ef67412
JH
13598 [(set_attr "length" "1")
13599 (set_attr "length_immediate" "0")
13600 (set_attr "modrm" "0")])
5f3d14e3 13601
253c7a00
JH
13602;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13603;; instruction Athlon and K8 have.
13604
13605(define_insn "return_internal_long"
13606 [(return)
13607 (unspec [(const_int 0)] UNSPEC_REP)]
13608 "reload_completed"
13609 "rep {;} ret"
13610 [(set_attr "length" "1")
13611 (set_attr "length_immediate" "0")
13612 (set_attr "prefix_rep" "1")
13613 (set_attr "modrm" "0")])
13614
6cd96118
SC
13615(define_insn "return_pop_internal"
13616 [(return)
13617 (use (match_operand:SI 0 "const_int_operand" ""))]
13618 "reload_completed"
0f40f9f7 13619 "ret\t%0"
6ef67412
JH
13620 [(set_attr "length" "3")
13621 (set_attr "length_immediate" "2")
13622 (set_attr "modrm" "0")])
6cd96118 13623
11837777
RH
13624(define_insn "return_indirect_internal"
13625 [(return)
13626 (use (match_operand:SI 0 "register_operand" "r"))]
13627 "reload_completed"
0f40f9f7 13628 "jmp\t%A0"
11837777
RH
13629 [(set_attr "type" "ibr")
13630 (set_attr "length_immediate" "0")])
13631
5f3d14e3
SC
13632(define_insn "nop"
13633 [(const_int 0)]
13634 ""
90aec2cf 13635 "nop"
e075ae69 13636 [(set_attr "length" "1")
6ef67412 13637 (set_attr "length_immediate" "0")
56bab446 13638 (set_attr "modrm" "0")])
5f3d14e3 13639
9ccf9681
RH
13640;; Align to 16-byte boundary, max skip in op0. Used to avoid
13641;; branch prediction penalty for the third jump in a 16-byte
13642;; block on K8.
d2c49530
JH
13643
13644(define_insn "align"
13645 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13646 ""
13647{
9ccf9681 13648#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
6262f66a 13649 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
9ccf9681 13650#else
6262f66a
JH
13651 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13652 The align insn is used to avoid 3 jump instructions in the row to improve
13653 branch prediction and the benefits hardly outweight the cost of extra 8
13654 nops on the average inserted by full alignment pseudo operation. */
d2c49530 13655#endif
9ccf9681 13656 return "";
d2c49530
JH
13657}
13658 [(set_attr "length" "16")])
13659
5f3d14e3
SC
13660(define_expand "prologue"
13661 [(const_int 1)]
13662 ""
e075ae69 13663 "ix86_expand_prologue (); DONE;")
5f3d14e3 13664
bd09bdeb 13665(define_insn "set_got"
69404d6f 13666 [(set (match_operand:SI 0 "register_operand" "=r")
c8c03509 13667 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
8bc527af 13668 (clobber (reg:CC FLAGS_REG))]
1e07edd3 13669 "!TARGET_64BIT"
c8c03509
RH
13670 { return output_set_got (operands[0]); }
13671 [(set_attr "type" "multi")
13672 (set_attr "length" "12")])
5f3d14e3 13673
e075ae69
RH
13674(define_expand "epilogue"
13675 [(const_int 1)]
13676 ""
cbbf65e0
RH
13677 "ix86_expand_epilogue (1); DONE;")
13678
13679(define_expand "sibcall_epilogue"
13680 [(const_int 1)]
13681 ""
13682 "ix86_expand_epilogue (0); DONE;")
e075ae69 13683
1020a5ab 13684(define_expand "eh_return"
34dc173c 13685 [(use (match_operand 0 "register_operand" ""))]
1020a5ab 13686 ""
1020a5ab 13687{
34dc173c 13688 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
1020a5ab
RH
13689
13690 /* Tricky bit: we write the address of the handler to which we will
13691 be returning into someone else's stack frame, one word below the
13692 stack address we wish to restore. */
13693 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13694 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13695 tmp = gen_rtx_MEM (Pmode, tmp);
13696 emit_move_insn (tmp, ra);
13697
d5d6a58b 13698 if (Pmode == SImode)
2e2052b1 13699 emit_jump_insn (gen_eh_return_si (sa));
d5d6a58b 13700 else
2e2052b1 13701 emit_jump_insn (gen_eh_return_di (sa));
1020a5ab
RH
13702 emit_barrier ();
13703 DONE;
0f40f9f7 13704})
1020a5ab 13705
d5d6a58b 13706(define_insn_and_split "eh_return_si"
2e2052b1
JH
13707 [(set (pc)
13708 (unspec [(match_operand:SI 0 "register_operand" "c")]
13709 UNSPEC_EH_RETURN))]
1b0c37d7 13710 "!TARGET_64BIT"
d5d6a58b
RH
13711 "#"
13712 "reload_completed"
13713 [(const_int 1)]
13714 "ix86_expand_epilogue (2); DONE;")
13715
13716(define_insn_and_split "eh_return_di"
2e2052b1
JH
13717 [(set (pc)
13718 (unspec [(match_operand:DI 0 "register_operand" "c")]
13719 UNSPEC_EH_RETURN))]
1b0c37d7 13720 "TARGET_64BIT"
1020a5ab
RH
13721 "#"
13722 "reload_completed"
13723 [(const_int 1)]
13724 "ix86_expand_epilogue (2); DONE;")
13725
e075ae69 13726(define_insn "leave"
8bc527af
SB
13727 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13728 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
f2042df3 13729 (clobber (mem:BLK (scratch)))]
1e07edd3 13730 "!TARGET_64BIT"
e075ae69 13731 "leave"
4977bab6 13732 [(set_attr "type" "leave")])
8362f420
JH
13733
13734(define_insn "leave_rex64"
8bc527af
SB
13735 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13736 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
f2042df3 13737 (clobber (mem:BLK (scratch)))]
8362f420
JH
13738 "TARGET_64BIT"
13739 "leave"
4977bab6 13740 [(set_attr "type" "leave")])
e075ae69
RH
13741\f
13742(define_expand "ffssi2"
8acfdd43
RH
13743 [(parallel
13744 [(set (match_operand:SI 0 "register_operand" "")
13745 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13746 (clobber (match_scratch:SI 2 ""))
8bc527af 13747 (clobber (reg:CC FLAGS_REG))])]
e075ae69 13748 ""
8acfdd43 13749 "")
e075ae69 13750
8acfdd43
RH
13751(define_insn_and_split "*ffs_cmove"
13752 [(set (match_operand:SI 0 "register_operand" "=r")
13753 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13754 (clobber (match_scratch:SI 2 "=&r"))
8bc527af 13755 (clobber (reg:CC FLAGS_REG))]
8acfdd43
RH
13756 "TARGET_CMOVE"
13757 "#"
13758 "&& reload_completed"
13759 [(set (match_dup 2) (const_int -1))
8bc527af 13760 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
8acfdd43
RH
13761 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13762 (set (match_dup 0) (if_then_else:SI
8bc527af 13763 (eq (reg:CCZ FLAGS_REG) (const_int 0))
8acfdd43
RH
13764 (match_dup 2)
13765 (match_dup 0)))
13766 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8bc527af 13767 (clobber (reg:CC FLAGS_REG))])]
8acfdd43 13768 "")
e0dc26ff 13769
8acfdd43
RH
13770(define_insn_and_split "*ffs_no_cmove"
13771 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13772 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
fa543fdd 13773 (clobber (match_scratch:SI 2 "=&q"))
8bc527af 13774 (clobber (reg:CC FLAGS_REG))]
8acfdd43
RH
13775 ""
13776 "#"
13777 "reload_completed"
8bc527af 13778 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
8acfdd43
RH
13779 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13780 (set (strict_low_part (match_dup 3))
8bc527af 13781 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
8acfdd43 13782 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
8bc527af 13783 (clobber (reg:CC FLAGS_REG))])
8acfdd43 13784 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
8bc527af 13785 (clobber (reg:CC FLAGS_REG))])
8acfdd43 13786 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8bc527af 13787 (clobber (reg:CC FLAGS_REG))])]
8acfdd43
RH
13788{
13789 operands[3] = gen_lowpart (QImode, operands[2]);
707e58b1 13790 ix86_expand_clear (operands[2]);
0f40f9f7 13791})
886c62d1 13792
8acfdd43 13793(define_insn "*ffssi_1"
8bc527af 13794 [(set (reg:CCZ FLAGS_REG)
8acfdd43 13795 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
16189740 13796 (const_int 0)))
e075ae69 13797 (set (match_operand:SI 0 "register_operand" "=r")
8acfdd43
RH
13798 (ctz:SI (match_dup 1)))]
13799 ""
13800 "bsf{l}\t{%1, %0|%0, %1}"
56bab446 13801 [(set_attr "prefix_0f" "1")])
8acfdd43 13802
d413e3cc
JJ
13803(define_expand "ffsdi2"
13804 [(parallel
13805 [(set (match_operand:DI 0 "register_operand" "")
13806 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13807 (clobber (match_scratch:DI 2 ""))
42fabf21 13808 (clobber (reg:CC FLAGS_REG))])]
d413e3cc
JJ
13809 "TARGET_64BIT && TARGET_CMOVE"
13810 "")
13811
13812(define_insn_and_split "*ffs_rex64"
13813 [(set (match_operand:DI 0 "register_operand" "=r")
13814 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13815 (clobber (match_scratch:DI 2 "=&r"))
42fabf21 13816 (clobber (reg:CC FLAGS_REG))]
d413e3cc
JJ
13817 "TARGET_64BIT && TARGET_CMOVE"
13818 "#"
13819 "&& reload_completed"
13820 [(set (match_dup 2) (const_int -1))
42fabf21
RH
13821 (parallel [(set (reg:CCZ FLAGS_REG)
13822 (compare:CCZ (match_dup 1) (const_int 0)))
d413e3cc
JJ
13823 (set (match_dup 0) (ctz:DI (match_dup 1)))])
13824 (set (match_dup 0) (if_then_else:DI
42fabf21 13825 (eq (reg:CCZ FLAGS_REG) (const_int 0))
d413e3cc
JJ
13826 (match_dup 2)
13827 (match_dup 0)))
13828 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
42fabf21 13829 (clobber (reg:CC FLAGS_REG))])]
d413e3cc
JJ
13830 "")
13831
13832(define_insn "*ffsdi_1"
42fabf21 13833 [(set (reg:CCZ FLAGS_REG)
d413e3cc
JJ
13834 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13835 (const_int 0)))
13836 (set (match_operand:DI 0 "register_operand" "=r")
13837 (ctz:DI (match_dup 1)))]
13838 "TARGET_64BIT"
13839 "bsf{q}\t{%1, %0|%0, %1}"
13840 [(set_attr "prefix_0f" "1")])
13841
8acfdd43
RH
13842(define_insn "ctzsi2"
13843 [(set (match_operand:SI 0 "register_operand" "=r")
13844 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
8bc527af 13845 (clobber (reg:CC FLAGS_REG))]
e075ae69 13846 ""
0f40f9f7 13847 "bsf{l}\t{%1, %0|%0, %1}"
56bab446 13848 [(set_attr "prefix_0f" "1")])
e075ae69 13849
d413e3cc
JJ
13850(define_insn "ctzdi2"
13851 [(set (match_operand:DI 0 "register_operand" "=r")
13852 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
42fabf21 13853 (clobber (reg:CC FLAGS_REG))]
d413e3cc
JJ
13854 "TARGET_64BIT"
13855 "bsf{q}\t{%1, %0|%0, %1}"
13856 [(set_attr "prefix_0f" "1")])
13857
8acfdd43
RH
13858(define_expand "clzsi2"
13859 [(parallel
13860 [(set (match_operand:SI 0 "register_operand" "")
13861 (minus:SI (const_int 31)
13862 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
8bc527af 13863 (clobber (reg:CC FLAGS_REG))])
8acfdd43
RH
13864 (parallel
13865 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
8bc527af 13866 (clobber (reg:CC FLAGS_REG))])]
8acfdd43
RH
13867 ""
13868 "")
13869
13870(define_insn "*bsr"
13871 [(set (match_operand:SI 0 "register_operand" "=r")
13872 (minus:SI (const_int 31)
13873 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
8bc527af 13874 (clobber (reg:CC FLAGS_REG))]
8acfdd43
RH
13875 ""
13876 "bsr{l}\t{%1, %0|%0, %1}"
56bab446 13877 [(set_attr "prefix_0f" "1")])
d413e3cc
JJ
13878
13879(define_expand "clzdi2"
13880 [(parallel
13881 [(set (match_operand:DI 0 "register_operand" "")
13882 (minus:DI (const_int 63)
13883 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
42fabf21 13884 (clobber (reg:CC FLAGS_REG))])
d413e3cc
JJ
13885 (parallel
13886 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
42fabf21 13887 (clobber (reg:CC FLAGS_REG))])]
d413e3cc
JJ
13888 "TARGET_64BIT"
13889 "")
13890
13891(define_insn "*bsr_rex64"
13892 [(set (match_operand:DI 0 "register_operand" "=r")
13893 (minus:DI (const_int 63)
13894 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
42fabf21 13895 (clobber (reg:CC FLAGS_REG))]
d413e3cc
JJ
13896 "TARGET_64BIT"
13897 "bsr{q}\t{%1, %0|%0, %1}"
13898 [(set_attr "prefix_0f" "1")])
e075ae69 13899\f
f996902d
RH
13900;; Thread-local storage patterns for ELF.
13901;;
13902;; Note that these code sequences must appear exactly as shown
13903;; in order to allow linker relaxation.
13904
75d38379 13905(define_insn "*tls_global_dynamic_32_gnu"
f996902d
RH
13906 [(set (match_operand:SI 0 "register_operand" "=a")
13907 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13908 (match_operand:SI 2 "tls_symbolic_operand" "")
13909 (match_operand:SI 3 "call_insn_operand" "")]
13910 UNSPEC_TLS_GD))
13911 (clobber (match_scratch:SI 4 "=d"))
13912 (clobber (match_scratch:SI 5 "=c"))
8bc527af 13913 (clobber (reg:CC FLAGS_REG))]
75d38379 13914 "!TARGET_64BIT && TARGET_GNU_TLS"
f996902d
RH
13915 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13916 [(set_attr "type" "multi")
13917 (set_attr "length" "12")])
13918
75d38379 13919(define_insn "*tls_global_dynamic_32_sun"
f996902d
RH
13920 [(set (match_operand:SI 0 "register_operand" "=a")
13921 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13922 (match_operand:SI 2 "tls_symbolic_operand" "")
13923 (match_operand:SI 3 "call_insn_operand" "")]
13924 UNSPEC_TLS_GD))
13925 (clobber (match_scratch:SI 4 "=d"))
13926 (clobber (match_scratch:SI 5 "=c"))
8bc527af 13927 (clobber (reg:CC FLAGS_REG))]
75d38379 13928 "!TARGET_64BIT && TARGET_SUN_TLS"
f996902d
RH
13929 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13930 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13931 [(set_attr "type" "multi")
13932 (set_attr "length" "14")])
13933
75d38379 13934(define_expand "tls_global_dynamic_32"
f996902d
RH
13935 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13936 (unspec:SI
13937 [(match_dup 2)
13938 (match_operand:SI 1 "tls_symbolic_operand" "")
13939 (match_dup 3)]
13940 UNSPEC_TLS_GD))
13941 (clobber (match_scratch:SI 4 ""))
13942 (clobber (match_scratch:SI 5 ""))
8bc527af 13943 (clobber (reg:CC FLAGS_REG))])]
f996902d
RH
13944 ""
13945{
dce81a1a
JJ
13946 if (flag_pic)
13947 operands[2] = pic_offset_table_rtx;
13948 else
13949 {
13950 operands[2] = gen_reg_rtx (Pmode);
13951 emit_insn (gen_set_got (operands[2]));
13952 }
f996902d
RH
13953 operands[3] = ix86_tls_get_addr ();
13954})
13955
75d38379
JJ
13956(define_insn "*tls_global_dynamic_64"
13957 [(set (match_operand:DI 0 "register_operand" "=a")
13958 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13959 (match_operand:DI 3 "" "")))
13960 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13961 UNSPEC_TLS_GD)]
13962 "TARGET_64BIT"
13963 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13964 [(set_attr "type" "multi")
13965 (set_attr "length" "16")])
13966
13967(define_expand "tls_global_dynamic_64"
13968 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13969 (call (mem:QI (match_dup 2)) (const_int 0)))
13970 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13971 UNSPEC_TLS_GD)])]
13972 ""
13973{
13974 operands[2] = ix86_tls_get_addr ();
13975})
13976
13977(define_insn "*tls_local_dynamic_base_32_gnu"
f996902d
RH
13978 [(set (match_operand:SI 0 "register_operand" "=a")
13979 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13980 (match_operand:SI 2 "call_insn_operand" "")]
13981 UNSPEC_TLS_LD_BASE))
13982 (clobber (match_scratch:SI 3 "=d"))
13983 (clobber (match_scratch:SI 4 "=c"))
8bc527af 13984 (clobber (reg:CC FLAGS_REG))]
75d38379 13985 "!TARGET_64BIT && TARGET_GNU_TLS"
f996902d
RH
13986 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13987 [(set_attr "type" "multi")
13988 (set_attr "length" "11")])
13989
75d38379 13990(define_insn "*tls_local_dynamic_base_32_sun"
f996902d
RH
13991 [(set (match_operand:SI 0 "register_operand" "=a")
13992 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13993 (match_operand:SI 2 "call_insn_operand" "")]
13994 UNSPEC_TLS_LD_BASE))
13995 (clobber (match_scratch:SI 3 "=d"))
13996 (clobber (match_scratch:SI 4 "=c"))
8bc527af 13997 (clobber (reg:CC FLAGS_REG))]
75d38379 13998 "!TARGET_64BIT && TARGET_SUN_TLS"
f996902d
RH
13999 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14000 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14001 [(set_attr "type" "multi")
14002 (set_attr "length" "13")])
14003
75d38379 14004(define_expand "tls_local_dynamic_base_32"
f996902d
RH
14005 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14006 (unspec:SI [(match_dup 1) (match_dup 2)]
14007 UNSPEC_TLS_LD_BASE))
14008 (clobber (match_scratch:SI 3 ""))
14009 (clobber (match_scratch:SI 4 ""))
8bc527af 14010 (clobber (reg:CC FLAGS_REG))])]
f996902d
RH
14011 ""
14012{
dce81a1a 14013 if (flag_pic)
9785f1d9 14014 operands[1] = pic_offset_table_rtx;
dce81a1a
JJ
14015 else
14016 {
9785f1d9
JJ
14017 operands[1] = gen_reg_rtx (Pmode);
14018 emit_insn (gen_set_got (operands[1]));
dce81a1a 14019 }
f996902d
RH
14020 operands[2] = ix86_tls_get_addr ();
14021})
14022
75d38379
JJ
14023(define_insn "*tls_local_dynamic_base_64"
14024 [(set (match_operand:DI 0 "register_operand" "=a")
14025 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14026 (match_operand:DI 2 "" "")))
14027 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14028 "TARGET_64BIT"
14029 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14030 [(set_attr "type" "multi")
14031 (set_attr "length" "12")])
14032
14033(define_expand "tls_local_dynamic_base_64"
14034 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14035 (call (mem:QI (match_dup 1)) (const_int 0)))
14036 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14037 ""
14038{
14039 operands[1] = ix86_tls_get_addr ();
14040})
14041
f996902d
RH
14042;; Local dynamic of a single variable is a lose. Show combine how
14043;; to convert that back to global dynamic.
14044
75d38379 14045(define_insn_and_split "*tls_local_dynamic_32_once"
f996902d
RH
14046 [(set (match_operand:SI 0 "register_operand" "=a")
14047 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14048 (match_operand:SI 2 "call_insn_operand" "")]
14049 UNSPEC_TLS_LD_BASE)
14050 (const:SI (unspec:SI
14051 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14052 UNSPEC_DTPOFF))))
14053 (clobber (match_scratch:SI 4 "=d"))
14054 (clobber (match_scratch:SI 5 "=c"))
8bc527af 14055 (clobber (reg:CC FLAGS_REG))]
f996902d
RH
14056 ""
14057 "#"
14058 ""
14059 [(parallel [(set (match_dup 0)
14060 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14061 UNSPEC_TLS_GD))
14062 (clobber (match_dup 4))
14063 (clobber (match_dup 5))
8bc527af 14064 (clobber (reg:CC FLAGS_REG))])]
f996902d 14065 "")
74dc3e94
RH
14066
14067;; Load and add the thread base pointer from %gs:0.
14068
14069(define_insn "*load_tp_si"
14070 [(set (match_operand:SI 0 "register_operand" "=r")
14071 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14072 "!TARGET_64BIT"
14073 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14074 [(set_attr "type" "imov")
14075 (set_attr "modrm" "0")
14076 (set_attr "length" "7")
14077 (set_attr "memory" "load")
14078 (set_attr "imm_disp" "false")])
14079
14080(define_insn "*add_tp_si"
14081 [(set (match_operand:SI 0 "register_operand" "=r")
14082 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14083 (match_operand:SI 1 "register_operand" "0")))
8bc527af 14084 (clobber (reg:CC FLAGS_REG))]
74dc3e94
RH
14085 "!TARGET_64BIT"
14086 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14087 [(set_attr "type" "alu")
14088 (set_attr "modrm" "0")
14089 (set_attr "length" "7")
14090 (set_attr "memory" "load")
14091 (set_attr "imm_disp" "false")])
14092
14093(define_insn "*load_tp_di"
14094 [(set (match_operand:DI 0 "register_operand" "=r")
14095 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14096 "TARGET_64BIT"
965514bd 14097 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
74dc3e94
RH
14098 [(set_attr "type" "imov")
14099 (set_attr "modrm" "0")
14100 (set_attr "length" "7")
14101 (set_attr "memory" "load")
14102 (set_attr "imm_disp" "false")])
14103
14104(define_insn "*add_tp_di"
14105 [(set (match_operand:DI 0 "register_operand" "=r")
14106 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14107 (match_operand:DI 1 "register_operand" "0")))
8bc527af 14108 (clobber (reg:CC FLAGS_REG))]
74dc3e94
RH
14109 "TARGET_64BIT"
14110 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14111 [(set_attr "type" "alu")
14112 (set_attr "modrm" "0")
14113 (set_attr "length" "7")
14114 (set_attr "memory" "load")
14115 (set_attr "imm_disp" "false")])
f996902d 14116\f
e075ae69
RH
14117;; These patterns match the binary 387 instructions for addM3, subM3,
14118;; mulM3 and divM3. There are three patterns for each of DFmode and
14119;; SFmode. The first is the normal insn, the second the same insn but
14120;; with one operand a conversion, and the third the same insn but with
14121;; the other operand a conversion. The conversion may be SFmode or
14122;; SImode if the target mode DFmode, but only SImode if the target mode
14123;; is SFmode.
14124
caa6ec8d
JH
14125;; Gcc is slightly more smart about handling normal two address instructions
14126;; so use special patterns for add and mull.
965f5423 14127
cfa185b8 14128(define_insn "*fop_sf_comm_mixed"
1deaa899 14129 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
caa6ec8d 14130 (match_operator:SF 3 "binary_fp_operator"
aebfea10 14131 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
1deaa899 14132 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
cfa185b8 14133 "TARGET_MIX_SSE_I387
ec8e098d 14134 && COMMUTATIVE_ARITH_P (operands[3])
aebfea10 14135 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
caa6ec8d
JH
14136 "* return output_387_binary_op (insn, operands);"
14137 [(set (attr "type")
1deaa899 14138 (if_then_else (eq_attr "alternative" "1")
3d34cd91
JH
14139 (if_then_else (match_operand:SF 3 "mult_operator" "")
14140 (const_string "ssemul")
14141 (const_string "sseadd"))
1deaa899
JH
14142 (if_then_else (match_operand:SF 3 "mult_operator" "")
14143 (const_string "fmul")
14144 (const_string "fop"))))
14145 (set_attr "mode" "SF")])
14146
14147(define_insn "*fop_sf_comm_sse"
14148 [(set (match_operand:SF 0 "register_operand" "=x")
14149 (match_operator:SF 3 "binary_fp_operator"
aebfea10 14150 [(match_operand:SF 1 "nonimmediate_operand" "%0")
1deaa899 14151 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
cfa185b8
UB
14152 "TARGET_SSE_MATH
14153 && COMMUTATIVE_ARITH_P (operands[3])
aebfea10 14154 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1deaa899 14155 "* return output_387_binary_op (insn, operands);"
3d34cd91
JH
14156 [(set (attr "type")
14157 (if_then_else (match_operand:SF 3 "mult_operator" "")
14158 (const_string "ssemul")
14159 (const_string "sseadd")))
6ef67412 14160 (set_attr "mode" "SF")])
caa6ec8d 14161
cfa185b8
UB
14162(define_insn "*fop_sf_comm_i387"
14163 [(set (match_operand:SF 0 "register_operand" "=f")
14164 (match_operator:SF 3 "binary_fp_operator"
14165 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14166 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14167 "TARGET_80387
ec8e098d 14168 && COMMUTATIVE_ARITH_P (operands[3])
aebfea10 14169 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
965f5423
JH
14170 "* return output_387_binary_op (insn, operands);"
14171 [(set (attr "type")
14172 (if_then_else (match_operand:SF 3 "mult_operator" "")
14173 (const_string "fmul")
14174 (const_string "fop")))
965f5423
JH
14175 (set_attr "mode" "SF")])
14176
cfa185b8 14177(define_insn "*fop_sf_1_mixed"
1deaa899 14178 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
e075ae69 14179 (match_operator:SF 3 "binary_fp_operator"
1deaa899
JH
14180 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14181 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
cfa185b8 14182 "TARGET_MIX_SSE_I387
ec8e098d 14183 && !COMMUTATIVE_ARITH_P (operands[3])
f97d9ec3 14184 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
14185 "* return output_387_binary_op (insn, operands);"
14186 [(set (attr "type")
3d34cd91
JH
14187 (cond [(and (eq_attr "alternative" "2")
14188 (match_operand:SF 3 "mult_operator" ""))
14189 (const_string "ssemul")
14190 (and (eq_attr "alternative" "2")
14191 (match_operand:SF 3 "div_operator" ""))
14192 (const_string "ssediv")
14193 (eq_attr "alternative" "2")
14194 (const_string "sseadd")
1deaa899 14195 (match_operand:SF 3 "mult_operator" "")
e075ae69
RH
14196 (const_string "fmul")
14197 (match_operand:SF 3 "div_operator" "")
14198 (const_string "fdiv")
14199 ]
6ef67412
JH
14200 (const_string "fop")))
14201 (set_attr "mode" "SF")])
e075ae69 14202
1deaa899
JH
14203(define_insn "*fop_sf_1_sse"
14204 [(set (match_operand:SF 0 "register_operand" "=x")
14205 (match_operator:SF 3 "binary_fp_operator"
14206 [(match_operand:SF 1 "register_operand" "0")
14207 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
965f5423 14208 "TARGET_SSE_MATH
ec8e098d 14209 && !COMMUTATIVE_ARITH_P (operands[3])"
1deaa899 14210 "* return output_387_binary_op (insn, operands);"
3d34cd91
JH
14211 [(set (attr "type")
14212 (cond [(match_operand:SF 3 "mult_operator" "")
14213 (const_string "ssemul")
14214 (match_operand:SF 3 "div_operator" "")
14215 (const_string "ssediv")
14216 ]
14217 (const_string "sseadd")))
1deaa899
JH
14218 (set_attr "mode" "SF")])
14219
9e4ae64b 14220;; This pattern is not fully shadowed by the pattern above.
cfa185b8
UB
14221(define_insn "*fop_sf_1_i387"
14222 [(set (match_operand:SF 0 "register_operand" "=f,f")
14223 (match_operator:SF 3 "binary_fp_operator"
14224 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14225 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
9e4ae64b 14226 "TARGET_80387 && !TARGET_SSE_MATH
cfa185b8
UB
14227 && !COMMUTATIVE_ARITH_P (operands[3])
14228 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14229 "* return output_387_binary_op (insn, operands);"
14230 [(set (attr "type")
14231 (cond [(match_operand:SF 3 "mult_operator" "")
14232 (const_string "fmul")
14233 (match_operand:SF 3 "div_operator" "")
14234 (const_string "fdiv")
14235 ]
14236 (const_string "fop")))
14237 (set_attr "mode" "SF")])
14238
14239
1deaa899 14240;; ??? Add SSE splitters for these!
cfa185b8 14241(define_insn "*fop_sf_2_i387"
e075ae69
RH
14242 [(set (match_operand:SF 0 "register_operand" "=f,f")
14243 (match_operator:SF 3 "binary_fp_operator"
14244 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14245 (match_operand:SF 2 "register_operand" "0,0")]))]
965f5423 14246 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
e075ae69
RH
14247 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14248 [(set (attr "type")
14249 (cond [(match_operand:SF 3 "mult_operator" "")
14250 (const_string "fmul")
14251 (match_operand:SF 3 "div_operator" "")
14252 (const_string "fdiv")
14253 ]
14254 (const_string "fop")))
14255 (set_attr "fp_int_src" "true")
6ef67412 14256 (set_attr "mode" "SI")])
e075ae69 14257
cfa185b8 14258(define_insn "*fop_sf_3_i387"
e075ae69
RH
14259 [(set (match_operand:SF 0 "register_operand" "=f,f")
14260 (match_operator:SF 3 "binary_fp_operator"
14261 [(match_operand:SF 1 "register_operand" "0,0")
14262 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
965f5423 14263 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
e075ae69
RH
14264 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14265 [(set (attr "type")
14266 (cond [(match_operand:SF 3 "mult_operator" "")
14267 (const_string "fmul")
14268 (match_operand:SF 3 "div_operator" "")
14269 (const_string "fdiv")
14270 ]
14271 (const_string "fop")))
14272 (set_attr "fp_int_src" "true")
6ef67412 14273 (set_attr "mode" "SI")])
e075ae69 14274
cfa185b8
UB
14275(define_insn "*fop_df_comm_mixed"
14276 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
965f5423 14277 (match_operator:DF 3 "binary_fp_operator"
cfa185b8
UB
14278 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14279 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14280 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14281 && COMMUTATIVE_ARITH_P (operands[3])
965f5423
JH
14282 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14283 "* return output_387_binary_op (insn, operands);"
14284 [(set (attr "type")
cfa185b8
UB
14285 (if_then_else (eq_attr "alternative" "1")
14286 (if_then_else (match_operand:SF 3 "mult_operator" "")
14287 (const_string "ssemul")
14288 (const_string "sseadd"))
14289 (if_then_else (match_operand:SF 3 "mult_operator" "")
14290 (const_string "fmul")
14291 (const_string "fop"))))
14292 (set_attr "mode" "DF")])
14293
14294(define_insn "*fop_df_comm_sse"
14295 [(set (match_operand:DF 0 "register_operand" "=Y")
14296 (match_operator:DF 3 "binary_fp_operator"
14297 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14298 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14299 "TARGET_SSE2 && TARGET_SSE_MATH
14300 && COMMUTATIVE_ARITH_P (operands[3])
14301 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14302 "* return output_387_binary_op (insn, operands);"
14303 [(set (attr "type")
14304 (if_then_else (match_operand:SF 3 "mult_operator" "")
14305 (const_string "ssemul")
14306 (const_string "sseadd")))
965f5423
JH
14307 (set_attr "mode" "DF")])
14308
cfa185b8
UB
14309(define_insn "*fop_df_comm_i387"
14310 [(set (match_operand:DF 0 "register_operand" "=f")
14311 (match_operator:DF 3 "binary_fp_operator"
14312 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14313 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14314 "TARGET_80387
14315 && COMMUTATIVE_ARITH_P (operands[3])
14316 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14317 "* return output_387_binary_op (insn, operands);"
14318 [(set (attr "type")
14319 (if_then_else (match_operand:SF 3 "mult_operator" "")
14320 (const_string "fmul")
14321 (const_string "fop")))
14322 (set_attr "mode" "DF")])
965f5423 14323
cfa185b8 14324(define_insn "*fop_df_1_mixed"
1deaa899 14325 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
e075ae69 14326 (match_operator:DF 3 "binary_fp_operator"
1deaa899
JH
14327 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14328 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
cfa185b8 14329 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
ec8e098d 14330 && !COMMUTATIVE_ARITH_P (operands[3])
f97d9ec3 14331 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
14332 "* return output_387_binary_op (insn, operands);"
14333 [(set (attr "type")
3d34cd91
JH
14334 (cond [(and (eq_attr "alternative" "2")
14335 (match_operand:SF 3 "mult_operator" ""))
14336 (const_string "ssemul")
14337 (and (eq_attr "alternative" "2")
14338 (match_operand:SF 3 "div_operator" ""))
14339 (const_string "ssediv")
14340 (eq_attr "alternative" "2")
14341 (const_string "sseadd")
1deaa899 14342 (match_operand:DF 3 "mult_operator" "")
e075ae69
RH
14343 (const_string "fmul")
14344 (match_operand:DF 3 "div_operator" "")
14345 (const_string "fdiv")
14346 ]
6ef67412
JH
14347 (const_string "fop")))
14348 (set_attr "mode" "DF")])
e075ae69 14349
1deaa899
JH
14350(define_insn "*fop_df_1_sse"
14351 [(set (match_operand:DF 0 "register_operand" "=Y")
14352 (match_operator:DF 3 "binary_fp_operator"
14353 [(match_operand:DF 1 "register_operand" "0")
14354 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
965f5423 14355 "TARGET_SSE2 && TARGET_SSE_MATH
ec8e098d 14356 && !COMMUTATIVE_ARITH_P (operands[3])"
1deaa899 14357 "* return output_387_binary_op (insn, operands);"
3d34cd91
JH
14358 [(set_attr "mode" "DF")
14359 (set (attr "type")
14360 (cond [(match_operand:SF 3 "mult_operator" "")
14361 (const_string "ssemul")
14362 (match_operand:SF 3 "div_operator" "")
14363 (const_string "ssediv")
14364 ]
14365 (const_string "sseadd")))])
1deaa899 14366
9e4ae64b 14367;; This pattern is not fully shadowed by the pattern above.
cfa185b8
UB
14368(define_insn "*fop_df_1_i387"
14369 [(set (match_operand:DF 0 "register_operand" "=f,f")
14370 (match_operator:DF 3 "binary_fp_operator"
14371 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14372 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
9e4ae64b 14373 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
cfa185b8
UB
14374 && !COMMUTATIVE_ARITH_P (operands[3])
14375 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14376 "* return output_387_binary_op (insn, operands);"
14377 [(set (attr "type")
14378 (cond [(match_operand:DF 3 "mult_operator" "")
14379 (const_string "fmul")
14380 (match_operand:DF 3 "div_operator" "")
14381 (const_string "fdiv")
14382 ]
14383 (const_string "fop")))
14384 (set_attr "mode" "DF")])
14385
1deaa899 14386;; ??? Add SSE splitters for these!
cfa185b8 14387(define_insn "*fop_df_2_i387"
e075ae69
RH
14388 [(set (match_operand:DF 0 "register_operand" "=f,f")
14389 (match_operator:DF 3 "binary_fp_operator"
14390 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14391 (match_operand:DF 2 "register_operand" "0,0")]))]
965f5423 14392 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
e075ae69
RH
14393 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14394 [(set (attr "type")
14395 (cond [(match_operand:DF 3 "mult_operator" "")
14396 (const_string "fmul")
14397 (match_operand:DF 3 "div_operator" "")
14398 (const_string "fdiv")
14399 ]
14400 (const_string "fop")))
14401 (set_attr "fp_int_src" "true")
6ef67412 14402 (set_attr "mode" "SI")])
e075ae69 14403
cfa185b8 14404(define_insn "*fop_df_3_i387"
e075ae69
RH
14405 [(set (match_operand:DF 0 "register_operand" "=f,f")
14406 (match_operator:DF 3 "binary_fp_operator"
14407 [(match_operand:DF 1 "register_operand" "0,0")
14408 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
965f5423 14409 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
e075ae69
RH
14410 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14411 [(set (attr "type")
14412 (cond [(match_operand:DF 3 "mult_operator" "")
14413 (const_string "fmul")
14414 (match_operand:DF 3 "div_operator" "")
14415 (const_string "fdiv")
14416 ]
14417 (const_string "fop")))
14418 (set_attr "fp_int_src" "true")
6ef67412 14419 (set_attr "mode" "SI")])
e075ae69 14420
cfa185b8 14421(define_insn "*fop_df_4_i387"
e075ae69
RH
14422 [(set (match_operand:DF 0 "register_operand" "=f,f")
14423 (match_operator:DF 3 "binary_fp_operator"
14424 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14425 (match_operand:DF 2 "register_operand" "0,f")]))]
cfa185b8 14426 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
f97d9ec3 14427 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
14428 "* return output_387_binary_op (insn, operands);"
14429 [(set (attr "type")
14430 (cond [(match_operand:DF 3 "mult_operator" "")
14431 (const_string "fmul")
14432 (match_operand:DF 3 "div_operator" "")
14433 (const_string "fdiv")
14434 ]
6ef67412
JH
14435 (const_string "fop")))
14436 (set_attr "mode" "SF")])
e075ae69 14437
cfa185b8 14438(define_insn "*fop_df_5_i387"
e075ae69
RH
14439 [(set (match_operand:DF 0 "register_operand" "=f,f")
14440 (match_operator:DF 3 "binary_fp_operator"
14441 [(match_operand:DF 1 "register_operand" "0,f")
14442 (float_extend:DF
14443 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
965f5423 14444 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
e075ae69
RH
14445 "* return output_387_binary_op (insn, operands);"
14446 [(set (attr "type")
14447 (cond [(match_operand:DF 3 "mult_operator" "")
14448 (const_string "fmul")
14449 (match_operand:DF 3 "div_operator" "")
14450 (const_string "fdiv")
14451 ]
6ef67412
JH
14452 (const_string "fop")))
14453 (set_attr "mode" "SF")])
e075ae69 14454
cfa185b8 14455(define_insn "*fop_df_6_i387"
4977bab6
ZW
14456 [(set (match_operand:DF 0 "register_operand" "=f,f")
14457 (match_operator:DF 3 "binary_fp_operator"
14458 [(float_extend:DF
14459 (match_operand:SF 1 "register_operand" "0,f"))
14460 (float_extend:DF
14461 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14462 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14463 "* return output_387_binary_op (insn, operands);"
14464 [(set (attr "type")
14465 (cond [(match_operand:DF 3 "mult_operator" "")
14466 (const_string "fmul")
14467 (match_operand:DF 3 "div_operator" "")
14468 (const_string "fdiv")
14469 ]
14470 (const_string "fop")))
14471 (set_attr "mode" "SF")])
14472
cfa185b8
UB
14473(define_insn "*fop_xf_comm_i387"
14474 [(set (match_operand:XF 0 "register_operand" "=f")
14475 (match_operator:XF 3 "binary_fp_operator"
14476 [(match_operand:XF 1 "register_operand" "%0")
14477 (match_operand:XF 2 "register_operand" "f")]))]
14478 "TARGET_80387
14479 && COMMUTATIVE_ARITH_P (operands[3])"
14480 "* return output_387_binary_op (insn, operands);"
14481 [(set (attr "type")
14482 (if_then_else (match_operand:XF 3 "mult_operator" "")
14483 (const_string "fmul")
14484 (const_string "fop")))
14485 (set_attr "mode" "XF")])
14486
14487(define_insn "*fop_xf_1_i387"
e075ae69
RH
14488 [(set (match_operand:XF 0 "register_operand" "=f,f")
14489 (match_operator:XF 3 "binary_fp_operator"
14490 [(match_operand:XF 1 "register_operand" "0,f")
14491 (match_operand:XF 2 "register_operand" "f,0")]))]
f8a1ebc6 14492 "TARGET_80387
ec8e098d 14493 && !COMMUTATIVE_ARITH_P (operands[3])"
e075ae69
RH
14494 "* return output_387_binary_op (insn, operands);"
14495 [(set (attr "type")
ca285e07 14496 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14497 (const_string "fmul")
ca285e07 14498 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14499 (const_string "fdiv")
14500 ]
6ef67412
JH
14501 (const_string "fop")))
14502 (set_attr "mode" "XF")])
e075ae69 14503
cfa185b8 14504(define_insn "*fop_xf_2_i387"
e075ae69
RH
14505 [(set (match_operand:XF 0 "register_operand" "=f,f")
14506 (match_operator:XF 3 "binary_fp_operator"
14507 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14508 (match_operand:XF 2 "register_operand" "0,0")]))]
2b589241
JH
14509 "TARGET_80387 && TARGET_USE_FIOP"
14510 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14511 [(set (attr "type")
f8a1ebc6 14512 (cond [(match_operand:XF 3 "mult_operator" "")
2b589241 14513 (const_string "fmul")
f8a1ebc6 14514 (match_operand:XF 3 "div_operator" "")
2b589241
JH
14515 (const_string "fdiv")
14516 ]
14517 (const_string "fop")))
14518 (set_attr "fp_int_src" "true")
56bab446 14519 (set_attr "mode" "SI")])
2b589241 14520
cfa185b8 14521(define_insn "*fop_xf_3_i387"
e075ae69
RH
14522 [(set (match_operand:XF 0 "register_operand" "=f,f")
14523 (match_operator:XF 3 "binary_fp_operator"
14524 [(match_operand:XF 1 "register_operand" "0,0")
14525 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
f8a1ebc6 14526 "TARGET_80387 && TARGET_USE_FIOP"
e075ae69
RH
14527 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14528 [(set (attr "type")
ca285e07 14529 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14530 (const_string "fmul")
ca285e07 14531 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14532 (const_string "fdiv")
14533 ]
14534 (const_string "fop")))
14535 (set_attr "fp_int_src" "true")
56bab446 14536 (set_attr "mode" "SI")])
e075ae69 14537
cfa185b8 14538(define_insn "*fop_xf_4_i387"
e075ae69
RH
14539 [(set (match_operand:XF 0 "register_operand" "=f,f")
14540 (match_operator:XF 3 "binary_fp_operator"
4977bab6 14541 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
e075ae69 14542 (match_operand:XF 2 "register_operand" "0,f")]))]
f8a1ebc6 14543 "TARGET_80387"
e075ae69
RH
14544 "* return output_387_binary_op (insn, operands);"
14545 [(set (attr "type")
ca285e07 14546 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14547 (const_string "fmul")
ca285e07 14548 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14549 (const_string "fdiv")
14550 ]
6ef67412
JH
14551 (const_string "fop")))
14552 (set_attr "mode" "SF")])
e075ae69 14553
cfa185b8 14554(define_insn "*fop_xf_5_i387"
e075ae69
RH
14555 [(set (match_operand:XF 0 "register_operand" "=f,f")
14556 (match_operator:XF 3 "binary_fp_operator"
14557 [(match_operand:XF 1 "register_operand" "0,f")
14558 (float_extend:XF
4977bab6 14559 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
f8a1ebc6 14560 "TARGET_80387"
e075ae69
RH
14561 "* return output_387_binary_op (insn, operands);"
14562 [(set (attr "type")
ca285e07 14563 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14564 (const_string "fmul")
ca285e07 14565 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14566 (const_string "fdiv")
14567 ]
6ef67412
JH
14568 (const_string "fop")))
14569 (set_attr "mode" "SF")])
e075ae69 14570
cfa185b8 14571(define_insn "*fop_xf_6_i387"
e075ae69
RH
14572 [(set (match_operand:XF 0 "register_operand" "=f,f")
14573 (match_operator:XF 3 "binary_fp_operator"
4977bab6
ZW
14574 [(float_extend:XF
14575 (match_operand 1 "register_operand" "0,f"))
e075ae69 14576 (float_extend:XF
4977bab6 14577 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
f8a1ebc6 14578 "TARGET_80387"
e075ae69
RH
14579 "* return output_387_binary_op (insn, operands);"
14580 [(set (attr "type")
ca285e07 14581 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14582 (const_string "fmul")
ca285e07 14583 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14584 (const_string "fdiv")
14585 ]
6ef67412 14586 (const_string "fop")))
4977bab6 14587 (set_attr "mode" "SF")])
e075ae69
RH
14588
14589(define_split
14590 [(set (match_operand 0 "register_operand" "")
14591 (match_operator 3 "binary_fp_operator"
14592 [(float (match_operand:SI 1 "register_operand" ""))
14593 (match_operand 2 "register_operand" "")]))]
14594 "TARGET_80387 && reload_completed
14595 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211a8fb 14596 [(const_int 0)]
4211a8fb
JH
14597{
14598 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14599 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14600 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14601 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14602 GET_MODE (operands[3]),
14603 operands[4],
14604 operands[2])));
14605 ix86_free_from_memory (GET_MODE (operands[1]));
14606 DONE;
0f40f9f7 14607})
e075ae69
RH
14608
14609(define_split
14610 [(set (match_operand 0 "register_operand" "")
14611 (match_operator 3 "binary_fp_operator"
14612 [(match_operand 1 "register_operand" "")
14613 (float (match_operand:SI 2 "register_operand" ""))]))]
14614 "TARGET_80387 && reload_completed
14615 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211a8fb 14616 [(const_int 0)]
4211a8fb
JH
14617{
14618 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14619 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14620 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2b66da3c 14621 gen_rtx_fmt_ee (GET_CODE (operands[3]),
4211a8fb
JH
14622 GET_MODE (operands[3]),
14623 operands[1],
14624 operands[4])));
14625 ix86_free_from_memory (GET_MODE (operands[2]));
14626 DONE;
0f40f9f7 14627})
e075ae69
RH
14628\f
14629;; FPU special functions.
14630
a8083431
JH
14631(define_expand "sqrtsf2"
14632 [(set (match_operand:SF 0 "register_operand" "")
14633 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
ba2baa55 14634 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
a8083431 14635{
abf80f8f 14636 if (!TARGET_SSE_MATH)
a8083431 14637 operands[1] = force_reg (SFmode, operands[1]);
0f40f9f7 14638})
a8083431 14639
22b768d4 14640(define_insn "*sqrtsf2_mixed"
ca9a9b12
JH
14641 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14642 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
22b768d4 14643 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
a8083431
JH
14644 "@
14645 fsqrt
0f40f9f7 14646 sqrtss\t{%1, %0|%0, %1}"
a8083431
JH
14647 [(set_attr "type" "fpspc,sse")
14648 (set_attr "mode" "SF,SF")
14649 (set_attr "athlon_decode" "direct,*")])
14650
22b768d4 14651(define_insn "*sqrtsf2_sse"
ca9a9b12
JH
14652 [(set (match_operand:SF 0 "register_operand" "=x")
14653 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
22b768d4 14654 "TARGET_SSE_MATH"
0f40f9f7 14655 "sqrtss\t{%1, %0|%0, %1}"
a8083431
JH
14656 [(set_attr "type" "sse")
14657 (set_attr "mode" "SF")
14658 (set_attr "athlon_decode" "*")])
14659
22b768d4 14660(define_insn "*sqrtsf2_i387"
e075ae69
RH
14661 [(set (match_operand:SF 0 "register_operand" "=f")
14662 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
22b768d4 14663 "TARGET_USE_FANCY_MATH_387"
e075ae69 14664 "fsqrt"
0b5107cf 14665 [(set_attr "type" "fpspc")
6ef67412 14666 (set_attr "mode" "SF")
0b5107cf 14667 (set_attr "athlon_decode" "direct")])
e075ae69 14668
a8083431
JH
14669(define_expand "sqrtdf2"
14670 [(set (match_operand:DF 0 "register_operand" "")
14671 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
22b768d4 14672 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
a8083431 14673{
22b768d4 14674 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
2406cfed 14675 operands[1] = force_reg (DFmode, operands[1]);
0f40f9f7 14676})
a8083431 14677
22b768d4 14678(define_insn "*sqrtdf2_mixed"
a8083431
JH
14679 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14680 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
22b768d4 14681 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
a8083431
JH
14682 "@
14683 fsqrt
0f40f9f7 14684 sqrtsd\t{%1, %0|%0, %1}"
a8083431
JH
14685 [(set_attr "type" "fpspc,sse")
14686 (set_attr "mode" "DF,DF")
14687 (set_attr "athlon_decode" "direct,*")])
14688
22b768d4 14689(define_insn "*sqrtdf2_sse"
a8083431
JH
14690 [(set (match_operand:DF 0 "register_operand" "=Y")
14691 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
22b768d4 14692 "TARGET_SSE2 && TARGET_SSE_MATH"
0f40f9f7 14693 "sqrtsd\t{%1, %0|%0, %1}"
a8083431
JH
14694 [(set_attr "type" "sse")
14695 (set_attr "mode" "DF")
14696 (set_attr "athlon_decode" "*")])
14697
22b768d4 14698(define_insn "*sqrtdf2_i387"
e075ae69
RH
14699 [(set (match_operand:DF 0 "register_operand" "=f")
14700 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
22b768d4 14701 "TARGET_USE_FANCY_MATH_387"
e075ae69 14702 "fsqrt"
0b5107cf 14703 [(set_attr "type" "fpspc")
6ef67412 14704 (set_attr "mode" "DF")
0b5107cf 14705 (set_attr "athlon_decode" "direct")])
e075ae69 14706
22b768d4 14707(define_insn "*sqrtextendsfdf2_i387"
e075ae69
RH
14708 [(set (match_operand:DF 0 "register_operand" "=f")
14709 (sqrt:DF (float_extend:DF
14710 (match_operand:SF 1 "register_operand" "0"))))]
ba2baa55 14711 "TARGET_USE_FANCY_MATH_387
22b768d4 14712 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
e075ae69 14713 "fsqrt"
0b5107cf 14714 [(set_attr "type" "fpspc")
6ef67412 14715 (set_attr "mode" "DF")
0b5107cf 14716 (set_attr "athlon_decode" "direct")])
e075ae69
RH
14717
14718(define_insn "sqrtxf2"
14719 [(set (match_operand:XF 0 "register_operand" "=f")
14720 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
ba2baa55 14721 "TARGET_USE_FANCY_MATH_387
de6c5979 14722 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
2b589241
JH
14723 "fsqrt"
14724 [(set_attr "type" "fpspc")
14725 (set_attr "mode" "XF")
14726 (set_attr "athlon_decode" "direct")])
14727
22b768d4 14728(define_insn "*sqrtextendsfxf2_i387"
e075ae69
RH
14729 [(set (match_operand:XF 0 "register_operand" "=f")
14730 (sqrt:XF (float_extend:XF
22b768d4 14731 (match_operand:SF 1 "register_operand" "0"))))]
ba2baa55 14732 "TARGET_USE_FANCY_MATH_387"
2b589241
JH
14733 "fsqrt"
14734 [(set_attr "type" "fpspc")
14735 (set_attr "mode" "XF")
14736 (set_attr "athlon_decode" "direct")])
14737
22b768d4 14738(define_insn "*sqrtextenddfxf2_i387"
e075ae69
RH
14739 [(set (match_operand:XF 0 "register_operand" "=f")
14740 (sqrt:XF (float_extend:XF
22b768d4 14741 (match_operand:DF 1 "register_operand" "0"))))]
ba2baa55 14742 "TARGET_USE_FANCY_MATH_387"
2b589241
JH
14743 "fsqrt"
14744 [(set_attr "type" "fpspc")
14745 (set_attr "mode" "XF")
14746 (set_attr "athlon_decode" "direct")])
14747
5ae27cfa
UB
14748(define_insn "fpremxf4"
14749 [(set (match_operand:XF 0 "register_operand" "=f")
14750 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14751 (match_operand:XF 3 "register_operand" "1")]
14752 UNSPEC_FPREM_F))
14753 (set (match_operand:XF 1 "register_operand" "=u")
14754 (unspec:XF [(match_dup 2) (match_dup 3)]
14755 UNSPEC_FPREM_U))
8bc527af 14756 (set (reg:CCFP FPSR_REG)
5ae27cfa 14757 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
ba2baa55 14758 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14759 && flag_unsafe_math_optimizations"
14760 "fprem"
14761 [(set_attr "type" "fpspc")
14762 (set_attr "mode" "XF")])
14763
14764(define_expand "fmodsf3"
14765 [(use (match_operand:SF 0 "register_operand" ""))
14766 (use (match_operand:SF 1 "register_operand" ""))
14767 (use (match_operand:SF 2 "register_operand" ""))]
ba2baa55 14768 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14769 && flag_unsafe_math_optimizations"
14770{
14771 rtx label = gen_label_rtx ();
14772
14773 rtx op1 = gen_reg_rtx (XFmode);
14774 rtx op2 = gen_reg_rtx (XFmode);
14775
14776 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14777 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14778
14779 emit_label (label);
14780
14781 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14782 ix86_emit_fp_unordered_jump (label);
14783
5b1f1e63 14784 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
5ae27cfa
UB
14785 DONE;
14786})
14787
14788(define_expand "fmoddf3"
14789 [(use (match_operand:DF 0 "register_operand" ""))
14790 (use (match_operand:DF 1 "register_operand" ""))
14791 (use (match_operand:DF 2 "register_operand" ""))]
ba2baa55 14792 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14793 && flag_unsafe_math_optimizations"
14794{
14795 rtx label = gen_label_rtx ();
14796
14797 rtx op1 = gen_reg_rtx (XFmode);
14798 rtx op2 = gen_reg_rtx (XFmode);
14799
14800 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14801 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14802
14803 emit_label (label);
14804
14805 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14806 ix86_emit_fp_unordered_jump (label);
14807
5b1f1e63 14808 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
5ae27cfa
UB
14809 DONE;
14810})
14811
14812(define_expand "fmodxf3"
14813 [(use (match_operand:XF 0 "register_operand" ""))
14814 (use (match_operand:XF 1 "register_operand" ""))
14815 (use (match_operand:XF 2 "register_operand" ""))]
ba2baa55 14816 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14817 && flag_unsafe_math_optimizations"
14818{
14819 rtx label = gen_label_rtx ();
14820
14821 emit_label (label);
14822
14823 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14824 operands[1], operands[2]));
14825 ix86_emit_fp_unordered_jump (label);
14826
14827 emit_move_insn (operands[0], operands[1]);
14828 DONE;
14829})
14830
14831(define_insn "fprem1xf4"
14832 [(set (match_operand:XF 0 "register_operand" "=f")
14833 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14834 (match_operand:XF 3 "register_operand" "1")]
14835 UNSPEC_FPREM1_F))
14836 (set (match_operand:XF 1 "register_operand" "=u")
14837 (unspec:XF [(match_dup 2) (match_dup 3)]
14838 UNSPEC_FPREM1_U))
8bc527af 14839 (set (reg:CCFP FPSR_REG)
5ae27cfa 14840 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
ba2baa55 14841 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14842 && flag_unsafe_math_optimizations"
14843 "fprem1"
14844 [(set_attr "type" "fpspc")
14845 (set_attr "mode" "XF")])
14846
14847(define_expand "dremsf3"
14848 [(use (match_operand:SF 0 "register_operand" ""))
14849 (use (match_operand:SF 1 "register_operand" ""))
14850 (use (match_operand:SF 2 "register_operand" ""))]
ba2baa55 14851 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14852 && flag_unsafe_math_optimizations"
14853{
14854 rtx label = gen_label_rtx ();
14855
14856 rtx op1 = gen_reg_rtx (XFmode);
14857 rtx op2 = gen_reg_rtx (XFmode);
14858
14859 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14860 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14861
14862 emit_label (label);
14863
14864 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14865 ix86_emit_fp_unordered_jump (label);
14866
5b1f1e63 14867 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
5ae27cfa
UB
14868 DONE;
14869})
14870
14871(define_expand "dremdf3"
14872 [(use (match_operand:DF 0 "register_operand" ""))
14873 (use (match_operand:DF 1 "register_operand" ""))
14874 (use (match_operand:DF 2 "register_operand" ""))]
ba2baa55 14875 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14876 && flag_unsafe_math_optimizations"
14877{
14878 rtx label = gen_label_rtx ();
14879
14880 rtx op1 = gen_reg_rtx (XFmode);
14881 rtx op2 = gen_reg_rtx (XFmode);
14882
14883 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14884 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14885
14886 emit_label (label);
14887
14888 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14889 ix86_emit_fp_unordered_jump (label);
14890
5b1f1e63 14891 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
5ae27cfa
UB
14892 DONE;
14893})
14894
14895(define_expand "dremxf3"
14896 [(use (match_operand:XF 0 "register_operand" ""))
14897 (use (match_operand:XF 1 "register_operand" ""))
14898 (use (match_operand:XF 2 "register_operand" ""))]
ba2baa55 14899 "TARGET_USE_FANCY_MATH_387
5ae27cfa
UB
14900 && flag_unsafe_math_optimizations"
14901{
14902 rtx label = gen_label_rtx ();
14903
14904 emit_label (label);
14905
14906 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14907 operands[1], operands[2]));
14908 ix86_emit_fp_unordered_jump (label);
14909
14910 emit_move_insn (operands[0], operands[1]);
14911 DONE;
14912})
14913
6c7cf1f0 14914(define_insn "*sindf2"
e075ae69 14915 [(set (match_operand:DF 0 "register_operand" "=f")
8ee41eaf 14916 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
ba2baa55 14917 "TARGET_USE_FANCY_MATH_387
de6c5979 14918 && flag_unsafe_math_optimizations"
e075ae69 14919 "fsin"
6ef67412
JH
14920 [(set_attr "type" "fpspc")
14921 (set_attr "mode" "DF")])
e075ae69 14922
6c7cf1f0 14923(define_insn "*sinsf2"
e075ae69 14924 [(set (match_operand:SF 0 "register_operand" "=f")
8ee41eaf 14925 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
ba2baa55 14926 "TARGET_USE_FANCY_MATH_387
de6c5979 14927 && flag_unsafe_math_optimizations"
e075ae69 14928 "fsin"
6ef67412
JH
14929 [(set_attr "type" "fpspc")
14930 (set_attr "mode" "SF")])
5f3d14e3 14931
6343a50e 14932(define_insn "*sinextendsfdf2"
e075ae69
RH
14933 [(set (match_operand:DF 0 "register_operand" "=f")
14934 (unspec:DF [(float_extend:DF
8ee41eaf
RH
14935 (match_operand:SF 1 "register_operand" "0"))]
14936 UNSPEC_SIN))]
ba2baa55 14937 "TARGET_USE_FANCY_MATH_387
de6c5979 14938 && flag_unsafe_math_optimizations"
e075ae69 14939 "fsin"
6ef67412
JH
14940 [(set_attr "type" "fpspc")
14941 (set_attr "mode" "DF")])
4f9ca067 14942
6c7cf1f0 14943(define_insn "*sinxf2"
e075ae69 14944 [(set (match_operand:XF 0 "register_operand" "=f")
8ee41eaf 14945 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
ba2baa55 14946 "TARGET_USE_FANCY_MATH_387
de6c5979 14947 && flag_unsafe_math_optimizations"
2b589241
JH
14948 "fsin"
14949 [(set_attr "type" "fpspc")
14950 (set_attr "mode" "XF")])
14951
6c7cf1f0 14952(define_insn "*cosdf2"
e075ae69 14953 [(set (match_operand:DF 0 "register_operand" "=f")
8ee41eaf 14954 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
ba2baa55 14955 "TARGET_USE_FANCY_MATH_387
de6c5979 14956 && flag_unsafe_math_optimizations"
e075ae69 14957 "fcos"
6ef67412
JH
14958 [(set_attr "type" "fpspc")
14959 (set_attr "mode" "DF")])
bca7cce2 14960
6c7cf1f0 14961(define_insn "*cossf2"
e075ae69 14962 [(set (match_operand:SF 0 "register_operand" "=f")
8ee41eaf 14963 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
ba2baa55 14964 "TARGET_USE_FANCY_MATH_387
de6c5979 14965 && flag_unsafe_math_optimizations"
e075ae69 14966 "fcos"
6ef67412
JH
14967 [(set_attr "type" "fpspc")
14968 (set_attr "mode" "SF")])
bca7cce2 14969
6343a50e 14970(define_insn "*cosextendsfdf2"
e075ae69
RH
14971 [(set (match_operand:DF 0 "register_operand" "=f")
14972 (unspec:DF [(float_extend:DF
8ee41eaf
RH
14973 (match_operand:SF 1 "register_operand" "0"))]
14974 UNSPEC_COS))]
ba2baa55 14975 "TARGET_USE_FANCY_MATH_387
de6c5979 14976 && flag_unsafe_math_optimizations"
e075ae69 14977 "fcos"
6ef67412
JH
14978 [(set_attr "type" "fpspc")
14979 (set_attr "mode" "DF")])
5f3d14e3 14980
6c7cf1f0 14981(define_insn "*cosxf2"
e075ae69 14982 [(set (match_operand:XF 0 "register_operand" "=f")
8ee41eaf 14983 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
ba2baa55 14984 "TARGET_USE_FANCY_MATH_387
de6c5979 14985 && flag_unsafe_math_optimizations"
2b589241
JH
14986 "fcos"
14987 [(set_attr "type" "fpspc")
14988 (set_attr "mode" "XF")])
1fb54135 14989
6c7cf1f0
UB
14990;; With sincos pattern defined, sin and cos builtin function will be
14991;; expanded to sincos pattern with one of its outputs left unused.
14992;; Cse pass will detected, if two sincos patterns can be combined,
1ae58c30 14993;; otherwise sincos pattern will be split back to sin or cos pattern,
6c7cf1f0
UB
14994;; depending on the unused output.
14995
14996(define_insn "sincosdf3"
14997 [(set (match_operand:DF 0 "register_operand" "=f")
14998 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14999 UNSPEC_SINCOS_COS))
15000 (set (match_operand:DF 1 "register_operand" "=u")
15001 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
ba2baa55 15002 "TARGET_USE_FANCY_MATH_387
6c7cf1f0
UB
15003 && flag_unsafe_math_optimizations"
15004 "fsincos"
15005 [(set_attr "type" "fpspc")
15006 (set_attr "mode" "DF")])
15007
15008(define_split
15009 [(set (match_operand:DF 0 "register_operand" "")
15010 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15011 UNSPEC_SINCOS_COS))
15012 (set (match_operand:DF 1 "register_operand" "")
15013 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15014 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15015 && !reload_completed && !reload_in_progress"
15016 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15017 "")
15018
15019(define_split
15020 [(set (match_operand:DF 0 "register_operand" "")
15021 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15022 UNSPEC_SINCOS_COS))
15023 (set (match_operand:DF 1 "register_operand" "")
15024 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15025 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15026 && !reload_completed && !reload_in_progress"
15027 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15028 "")
15029
15030(define_insn "sincossf3"
15031 [(set (match_operand:SF 0 "register_operand" "=f")
15032 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15033 UNSPEC_SINCOS_COS))
15034 (set (match_operand:SF 1 "register_operand" "=u")
15035 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
ba2baa55 15036 "TARGET_USE_FANCY_MATH_387
6c7cf1f0
UB
15037 && flag_unsafe_math_optimizations"
15038 "fsincos"
15039 [(set_attr "type" "fpspc")
15040 (set_attr "mode" "SF")])
15041
15042(define_split
15043 [(set (match_operand:SF 0 "register_operand" "")
15044 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15045 UNSPEC_SINCOS_COS))
15046 (set (match_operand:SF 1 "register_operand" "")
15047 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15048 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15049 && !reload_completed && !reload_in_progress"
15050 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15051 "")
15052
15053(define_split
15054 [(set (match_operand:SF 0 "register_operand" "")
15055 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15056 UNSPEC_SINCOS_COS))
15057 (set (match_operand:SF 1 "register_operand" "")
15058 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15059 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15060 && !reload_completed && !reload_in_progress"
15061 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15062 "")
15063
15064(define_insn "*sincosextendsfdf3"
15065 [(set (match_operand:DF 0 "register_operand" "=f")
15066 (unspec:DF [(float_extend:DF
15067 (match_operand:SF 2 "register_operand" "0"))]
15068 UNSPEC_SINCOS_COS))
15069 (set (match_operand:DF 1 "register_operand" "=u")
15070 (unspec:DF [(float_extend:DF
15071 (match_dup 2))] UNSPEC_SINCOS_SIN))]
ba2baa55 15072 "TARGET_USE_FANCY_MATH_387
6c7cf1f0
UB
15073 && flag_unsafe_math_optimizations"
15074 "fsincos"
15075 [(set_attr "type" "fpspc")
15076 (set_attr "mode" "DF")])
15077
15078(define_split
15079 [(set (match_operand:DF 0 "register_operand" "")
15080 (unspec:DF [(float_extend:DF
15081 (match_operand:SF 2 "register_operand" ""))]
15082 UNSPEC_SINCOS_COS))
15083 (set (match_operand:DF 1 "register_operand" "")
15084 (unspec:DF [(float_extend:DF
15085 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15086 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15087 && !reload_completed && !reload_in_progress"
15088 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15089 (match_dup 2))] UNSPEC_SIN))]
15090 "")
15091
15092(define_split
15093 [(set (match_operand:DF 0 "register_operand" "")
15094 (unspec:DF [(float_extend:DF
15095 (match_operand:SF 2 "register_operand" ""))]
15096 UNSPEC_SINCOS_COS))
15097 (set (match_operand:DF 1 "register_operand" "")
15098 (unspec:DF [(float_extend:DF
15099 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15100 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15101 && !reload_completed && !reload_in_progress"
15102 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15103 (match_dup 2))] UNSPEC_COS))]
15104 "")
15105
15106(define_insn "sincosxf3"
15107 [(set (match_operand:XF 0 "register_operand" "=f")
15108 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15109 UNSPEC_SINCOS_COS))
15110 (set (match_operand:XF 1 "register_operand" "=u")
15111 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
ba2baa55 15112 "TARGET_USE_FANCY_MATH_387
6c7cf1f0
UB
15113 && flag_unsafe_math_optimizations"
15114 "fsincos"
15115 [(set_attr "type" "fpspc")
15116 (set_attr "mode" "XF")])
15117
15118(define_split
15119 [(set (match_operand:XF 0 "register_operand" "")
15120 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15121 UNSPEC_SINCOS_COS))
15122 (set (match_operand:XF 1 "register_operand" "")
15123 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15124 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15125 && !reload_completed && !reload_in_progress"
15126 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15127 "")
15128
15129(define_split
15130 [(set (match_operand:XF 0 "register_operand" "")
15131 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15132 UNSPEC_SINCOS_COS))
15133 (set (match_operand:XF 1 "register_operand" "")
15134 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15135 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15136 && !reload_completed && !reload_in_progress"
15137 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15138 "")
15139
a072d43b
UB
15140(define_insn "*tandf3_1"
15141 [(set (match_operand:DF 0 "register_operand" "=f")
15142 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15143 UNSPEC_TAN_ONE))
15144 (set (match_operand:DF 1 "register_operand" "=u")
15145 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
ba2baa55 15146 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15147 && flag_unsafe_math_optimizations"
15148 "fptan"
15149 [(set_attr "type" "fpspc")
15150 (set_attr "mode" "DF")])
15151
15152;; optimize sequence: fptan
15153;; fstp %st(0)
15154;; fld1
15155;; into fptan insn.
15156
15157(define_peephole2
15158 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15159 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15160 UNSPEC_TAN_ONE))
15161 (set (match_operand:DF 1 "register_operand" "")
15162 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15163 (set (match_dup 0)
15164 (match_operand:DF 3 "immediate_operand" ""))]
15165 "standard_80387_constant_p (operands[3]) == 2"
15166 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15167 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15168 "")
15169
15170(define_expand "tandf2"
15171 [(parallel [(set (match_dup 2)
15172 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15173 UNSPEC_TAN_ONE))
15174 (set (match_operand:DF 0 "register_operand" "")
15175 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
ba2baa55 15176 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15177 && flag_unsafe_math_optimizations"
15178{
15179 operands[2] = gen_reg_rtx (DFmode);
15180})
15181
15182(define_insn "*tansf3_1"
15183 [(set (match_operand:SF 0 "register_operand" "=f")
15184 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15185 UNSPEC_TAN_ONE))
15186 (set (match_operand:SF 1 "register_operand" "=u")
15187 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
ba2baa55 15188 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15189 && flag_unsafe_math_optimizations"
15190 "fptan"
15191 [(set_attr "type" "fpspc")
15192 (set_attr "mode" "SF")])
15193
15194;; optimize sequence: fptan
15195;; fstp %st(0)
15196;; fld1
15197;; into fptan insn.
15198
15199(define_peephole2
15200 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15201 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15202 UNSPEC_TAN_ONE))
15203 (set (match_operand:SF 1 "register_operand" "")
15204 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15205 (set (match_dup 0)
15206 (match_operand:SF 3 "immediate_operand" ""))]
15207 "standard_80387_constant_p (operands[3]) == 2"
15208 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15209 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15210 "")
15211
15212(define_expand "tansf2"
15213 [(parallel [(set (match_dup 2)
15214 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15215 UNSPEC_TAN_ONE))
15216 (set (match_operand:SF 0 "register_operand" "")
15217 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
ba2baa55 15218 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15219 && flag_unsafe_math_optimizations"
15220{
15221 operands[2] = gen_reg_rtx (SFmode);
15222})
15223
15224(define_insn "*tanxf3_1"
15225 [(set (match_operand:XF 0 "register_operand" "=f")
15226 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15227 UNSPEC_TAN_ONE))
15228 (set (match_operand:XF 1 "register_operand" "=u")
15229 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
ba2baa55 15230 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15231 && flag_unsafe_math_optimizations"
15232 "fptan"
15233 [(set_attr "type" "fpspc")
15234 (set_attr "mode" "XF")])
15235
15236;; optimize sequence: fptan
15237;; fstp %st(0)
15238;; fld1
15239;; into fptan insn.
15240
15241(define_peephole2
15242 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15243 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15244 UNSPEC_TAN_ONE))
15245 (set (match_operand:XF 1 "register_operand" "")
15246 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15247 (set (match_dup 0)
15248 (match_operand:XF 3 "immediate_operand" ""))]
15249 "standard_80387_constant_p (operands[3]) == 2"
15250 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15251 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15252 "")
15253
15254(define_expand "tanxf2"
15255 [(parallel [(set (match_dup 2)
15256 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15257 UNSPEC_TAN_ONE))
15258 (set (match_operand:XF 0 "register_operand" "")
15259 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
ba2baa55 15260 "TARGET_USE_FANCY_MATH_387
a072d43b
UB
15261 && flag_unsafe_math_optimizations"
15262{
15263 operands[2] = gen_reg_rtx (XFmode);
15264})
15265
afeeac3f 15266(define_insn "atan2df3_1"
cb0bc263
JH
15267 [(set (match_operand:DF 0 "register_operand" "=f")
15268 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15269 (match_operand:DF 1 "register_operand" "u")]
15270 UNSPEC_FPATAN))
15271 (clobber (match_scratch:DF 3 "=1"))]
ba2baa55 15272 "TARGET_USE_FANCY_MATH_387
1fb54135
RS
15273 && flag_unsafe_math_optimizations"
15274 "fpatan"
15275 [(set_attr "type" "fpspc")
15276 (set_attr "mode" "DF")])
15277
afeeac3f
RS
15278(define_expand "atan2df3"
15279 [(use (match_operand:DF 0 "register_operand" "=f"))
15280 (use (match_operand:DF 2 "register_operand" "0"))
15281 (use (match_operand:DF 1 "register_operand" "u"))]
ba2baa55 15282 "TARGET_USE_FANCY_MATH_387
afeeac3f
RS
15283 && flag_unsafe_math_optimizations"
15284{
15285 rtx copy = gen_reg_rtx (DFmode);
15286 emit_move_insn (copy, operands[1]);
15287 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15288 DONE;
923c4cf2 15289})
afeeac3f 15290
a6bf61c7
UB
15291(define_expand "atandf2"
15292 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15293 (unspec:DF [(match_dup 2)
15294 (match_operand:DF 1 "register_operand" "")]
15295 UNSPEC_FPATAN))
15296 (clobber (match_scratch:DF 3 ""))])]
ba2baa55 15297 "TARGET_USE_FANCY_MATH_387
a6bf61c7
UB
15298 && flag_unsafe_math_optimizations"
15299{
15300 operands[2] = gen_reg_rtx (DFmode);
15301 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15302})
15303
afeeac3f 15304(define_insn "atan2sf3_1"
cb0bc263
JH
15305 [(set (match_operand:SF 0 "register_operand" "=f")
15306 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15307 (match_operand:SF 1 "register_operand" "u")]
15308 UNSPEC_FPATAN))
15309 (clobber (match_scratch:SF 3 "=1"))]
ba2baa55 15310 "TARGET_USE_FANCY_MATH_387
1fb54135
RS
15311 && flag_unsafe_math_optimizations"
15312 "fpatan"
15313 [(set_attr "type" "fpspc")
15314 (set_attr "mode" "SF")])
15315
afeeac3f
RS
15316(define_expand "atan2sf3"
15317 [(use (match_operand:SF 0 "register_operand" "=f"))
15318 (use (match_operand:SF 2 "register_operand" "0"))
15319 (use (match_operand:SF 1 "register_operand" "u"))]
ba2baa55 15320 "TARGET_USE_FANCY_MATH_387
afeeac3f
RS
15321 && flag_unsafe_math_optimizations"
15322{
15323 rtx copy = gen_reg_rtx (SFmode);
15324 emit_move_insn (copy, operands[1]);
15325 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15326 DONE;
923c4cf2 15327})
afeeac3f 15328
a6bf61c7
UB
15329(define_expand "atansf2"
15330 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15331 (unspec:SF [(match_dup 2)
15332 (match_operand:SF 1 "register_operand" "")]
15333 UNSPEC_FPATAN))
15334 (clobber (match_scratch:SF 3 ""))])]
ba2baa55 15335 "TARGET_USE_FANCY_MATH_387
a6bf61c7
UB
15336 && flag_unsafe_math_optimizations"
15337{
15338 operands[2] = gen_reg_rtx (SFmode);
15339 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15340})
15341
afeeac3f 15342(define_insn "atan2xf3_1"
cb0bc263
JH
15343 [(set (match_operand:XF 0 "register_operand" "=f")
15344 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15345 (match_operand:XF 1 "register_operand" "u")]
15346 UNSPEC_FPATAN))
15347 (clobber (match_scratch:XF 3 "=1"))]
ba2baa55 15348 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15349 && flag_unsafe_math_optimizations"
1fb54135
RS
15350 "fpatan"
15351 [(set_attr "type" "fpspc")
15352 (set_attr "mode" "XF")])
15353
afeeac3f
RS
15354(define_expand "atan2xf3"
15355 [(use (match_operand:XF 0 "register_operand" "=f"))
15356 (use (match_operand:XF 2 "register_operand" "0"))
15357 (use (match_operand:XF 1 "register_operand" "u"))]
ba2baa55 15358 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15359 && flag_unsafe_math_optimizations"
afeeac3f
RS
15360{
15361 rtx copy = gen_reg_rtx (XFmode);
15362 emit_move_insn (copy, operands[1]);
15363 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15364 DONE;
923c4cf2 15365})
afeeac3f 15366
a6bf61c7
UB
15367(define_expand "atanxf2"
15368 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15369 (unspec:XF [(match_dup 2)
15370 (match_operand:XF 1 "register_operand" "")]
15371 UNSPEC_FPATAN))
15372 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 15373 "TARGET_USE_FANCY_MATH_387
a6bf61c7
UB
15374 && flag_unsafe_math_optimizations"
15375{
15376 operands[2] = gen_reg_rtx (XFmode);
15377 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15378})
15379
c56122d8
UB
15380(define_expand "asindf2"
15381 [(set (match_dup 2)
15382 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15383 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15384 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15385 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15386 (parallel [(set (match_dup 7)
15387 (unspec:XF [(match_dup 6) (match_dup 2)]
15388 UNSPEC_FPATAN))
15389 (clobber (match_scratch:XF 8 ""))])
15390 (set (match_operand:DF 0 "register_operand" "")
15391 (float_truncate:DF (match_dup 7)))]
ba2baa55 15392 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15393 && flag_unsafe_math_optimizations"
15394{
15395 int i;
15396
15397 for (i=2; i<8; i++)
15398 operands[i] = gen_reg_rtx (XFmode);
15399
15400 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15401})
15402
15403(define_expand "asinsf2"
15404 [(set (match_dup 2)
15405 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15406 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15407 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15408 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15409 (parallel [(set (match_dup 7)
15410 (unspec:XF [(match_dup 6) (match_dup 2)]
15411 UNSPEC_FPATAN))
15412 (clobber (match_scratch:XF 8 ""))])
15413 (set (match_operand:SF 0 "register_operand" "")
15414 (float_truncate:SF (match_dup 7)))]
ba2baa55 15415 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15416 && flag_unsafe_math_optimizations"
15417{
15418 int i;
15419
15420 for (i=2; i<8; i++)
15421 operands[i] = gen_reg_rtx (XFmode);
15422
15423 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15424})
15425
15426(define_expand "asinxf2"
15427 [(set (match_dup 2)
15428 (mult:XF (match_operand:XF 1 "register_operand" "")
15429 (match_dup 1)))
15430 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15431 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15432 (parallel [(set (match_operand:XF 0 "register_operand" "")
15433 (unspec:XF [(match_dup 5) (match_dup 1)]
15434 UNSPEC_FPATAN))
15435 (clobber (match_scratch:XF 6 ""))])]
ba2baa55 15436 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15437 && flag_unsafe_math_optimizations"
15438{
15439 int i;
15440
15441 for (i=2; i<6; i++)
15442 operands[i] = gen_reg_rtx (XFmode);
15443
15444 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15445})
15446
15447(define_expand "acosdf2"
15448 [(set (match_dup 2)
15449 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15450 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15451 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15452 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15453 (parallel [(set (match_dup 7)
15454 (unspec:XF [(match_dup 2) (match_dup 6)]
15455 UNSPEC_FPATAN))
15456 (clobber (match_scratch:XF 8 ""))])
15457 (set (match_operand:DF 0 "register_operand" "")
15458 (float_truncate:DF (match_dup 7)))]
ba2baa55 15459 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15460 && flag_unsafe_math_optimizations"
15461{
15462 int i;
15463
15464 for (i=2; i<8; i++)
15465 operands[i] = gen_reg_rtx (XFmode);
15466
15467 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15468})
15469
15470(define_expand "acossf2"
15471 [(set (match_dup 2)
15472 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15473 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15474 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15475 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15476 (parallel [(set (match_dup 7)
15477 (unspec:XF [(match_dup 2) (match_dup 6)]
15478 UNSPEC_FPATAN))
15479 (clobber (match_scratch:XF 8 ""))])
15480 (set (match_operand:SF 0 "register_operand" "")
15481 (float_truncate:SF (match_dup 7)))]
ba2baa55 15482 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15483 && flag_unsafe_math_optimizations"
15484{
15485 int i;
15486
15487 for (i=2; i<8; i++)
15488 operands[i] = gen_reg_rtx (XFmode);
15489
15490 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15491})
15492
15493(define_expand "acosxf2"
15494 [(set (match_dup 2)
15495 (mult:XF (match_operand:XF 1 "register_operand" "")
15496 (match_dup 1)))
15497 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15498 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15499 (parallel [(set (match_operand:XF 0 "register_operand" "")
15500 (unspec:XF [(match_dup 1) (match_dup 5)]
15501 UNSPEC_FPATAN))
15502 (clobber (match_scratch:XF 6 ""))])]
ba2baa55 15503 "TARGET_USE_FANCY_MATH_387
c56122d8
UB
15504 && flag_unsafe_math_optimizations"
15505{
15506 int i;
15507
15508 for (i=2; i<6; i++)
15509 operands[i] = gen_reg_rtx (XFmode);
15510
15511 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15512})
15513
c2fcfa4f 15514(define_insn "fyl2x_xf3"
cb0bc263
JH
15515 [(set (match_operand:XF 0 "register_operand" "=f")
15516 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15517 (match_operand:XF 1 "register_operand" "u")]
15518 UNSPEC_FYL2X))
15519 (clobber (match_scratch:XF 3 "=1"))]
ba2baa55 15520 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15521 && flag_unsafe_math_optimizations"
358997e2
RS
15522 "fyl2x"
15523 [(set_attr "type" "fpspc")
15524 (set_attr "mode" "XF")])
15525
15526(define_expand "logsf2"
6adcf89d
UB
15527 [(set (match_dup 2)
15528 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15529 (parallel [(set (match_dup 4)
15530 (unspec:XF [(match_dup 2)
15531 (match_dup 3)] UNSPEC_FYL2X))
15532 (clobber (match_scratch:XF 5 ""))])
15533 (set (match_operand:SF 0 "register_operand" "")
15534 (float_truncate:SF (match_dup 4)))]
ba2baa55 15535 "TARGET_USE_FANCY_MATH_387
358997e2
RS
15536 && flag_unsafe_math_optimizations"
15537{
15538 rtx temp;
15539
f8a1ebc6 15540 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15541 operands[3] = gen_reg_rtx (XFmode);
15542 operands[4] = gen_reg_rtx (XFmode);
15543
358997e2 15544 temp = standard_80387_constant_rtx (4); /* fldln2 */
6adcf89d 15545 emit_move_insn (operands[3], temp);
358997e2
RS
15546})
15547
15548(define_expand "logdf2"
6adcf89d
UB
15549 [(set (match_dup 2)
15550 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15551 (parallel [(set (match_dup 4)
15552 (unspec:XF [(match_dup 2)
15553 (match_dup 3)] UNSPEC_FYL2X))
15554 (clobber (match_scratch:XF 5 ""))])
15555 (set (match_operand:DF 0 "register_operand" "")
15556 (float_truncate:DF (match_dup 4)))]
ba2baa55 15557 "TARGET_USE_FANCY_MATH_387
358997e2
RS
15558 && flag_unsafe_math_optimizations"
15559{
15560 rtx temp;
15561
f8a1ebc6 15562 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15563 operands[3] = gen_reg_rtx (XFmode);
15564 operands[4] = gen_reg_rtx (XFmode);
15565
358997e2 15566 temp = standard_80387_constant_rtx (4); /* fldln2 */
6adcf89d 15567 emit_move_insn (operands[3], temp);
358997e2
RS
15568})
15569
15570(define_expand "logxf2"
e43736ad
RS
15571 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15572 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15573 (match_dup 2)] UNSPEC_FYL2X))
cb0bc263 15574 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 15575 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15576 && flag_unsafe_math_optimizations"
358997e2
RS
15577{
15578 rtx temp;
15579
15580 operands[2] = gen_reg_rtx (XFmode);
15581 temp = standard_80387_constant_rtx (4); /* fldln2 */
15582 emit_move_insn (operands[2], temp);
15583})
15584
3b8e0c91 15585(define_expand "log10sf2"
6adcf89d
UB
15586 [(set (match_dup 2)
15587 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15588 (parallel [(set (match_dup 4)
15589 (unspec:XF [(match_dup 2)
15590 (match_dup 3)] UNSPEC_FYL2X))
15591 (clobber (match_scratch:XF 5 ""))])
15592 (set (match_operand:SF 0 "register_operand" "")
15593 (float_truncate:SF (match_dup 4)))]
ba2baa55 15594 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15595 && flag_unsafe_math_optimizations"
15596{
15597 rtx temp;
15598
15599 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15600 operands[3] = gen_reg_rtx (XFmode);
15601 operands[4] = gen_reg_rtx (XFmode);
15602
3b8e0c91 15603 temp = standard_80387_constant_rtx (3); /* fldlg2 */
6adcf89d 15604 emit_move_insn (operands[3], temp);
3b8e0c91
UB
15605})
15606
15607(define_expand "log10df2"
6adcf89d
UB
15608 [(set (match_dup 2)
15609 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15610 (parallel [(set (match_dup 4)
15611 (unspec:XF [(match_dup 2)
15612 (match_dup 3)] UNSPEC_FYL2X))
15613 (clobber (match_scratch:XF 5 ""))])
15614 (set (match_operand:DF 0 "register_operand" "")
15615 (float_truncate:DF (match_dup 4)))]
ba2baa55 15616 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15617 && flag_unsafe_math_optimizations"
15618{
15619 rtx temp;
15620
15621 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15622 operands[3] = gen_reg_rtx (XFmode);
15623 operands[4] = gen_reg_rtx (XFmode);
15624
3b8e0c91 15625 temp = standard_80387_constant_rtx (3); /* fldlg2 */
6adcf89d 15626 emit_move_insn (operands[3], temp);
3b8e0c91
UB
15627})
15628
15629(define_expand "log10xf2"
15630 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15631 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15632 (match_dup 2)] UNSPEC_FYL2X))
15633 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 15634 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15635 && flag_unsafe_math_optimizations"
15636{
15637 rtx temp;
15638
15639 operands[2] = gen_reg_rtx (XFmode);
15640 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15641 emit_move_insn (operands[2], temp);
15642})
15643
15644(define_expand "log2sf2"
6adcf89d
UB
15645 [(set (match_dup 2)
15646 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15647 (parallel [(set (match_dup 4)
15648 (unspec:XF [(match_dup 2)
15649 (match_dup 3)] UNSPEC_FYL2X))
15650 (clobber (match_scratch:XF 5 ""))])
15651 (set (match_operand:SF 0 "register_operand" "")
15652 (float_truncate:SF (match_dup 4)))]
ba2baa55 15653 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15654 && flag_unsafe_math_optimizations"
15655{
15656 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15657 operands[3] = gen_reg_rtx (XFmode);
15658 operands[4] = gen_reg_rtx (XFmode);
3b8e0c91 15659
6adcf89d 15660 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
3b8e0c91
UB
15661})
15662
15663(define_expand "log2df2"
6adcf89d
UB
15664 [(set (match_dup 2)
15665 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15666 (parallel [(set (match_dup 4)
15667 (unspec:XF [(match_dup 2)
15668 (match_dup 3)] UNSPEC_FYL2X))
15669 (clobber (match_scratch:XF 5 ""))])
15670 (set (match_operand:DF 0 "register_operand" "")
15671 (float_truncate:DF (match_dup 4)))]
ba2baa55 15672 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15673 && flag_unsafe_math_optimizations"
15674{
15675 operands[2] = gen_reg_rtx (XFmode);
6adcf89d
UB
15676 operands[3] = gen_reg_rtx (XFmode);
15677 operands[4] = gen_reg_rtx (XFmode);
15678
15679 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
3b8e0c91
UB
15680})
15681
15682(define_expand "log2xf2"
15683 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15684 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15685 (match_dup 2)] UNSPEC_FYL2X))
15686 (clobber (match_scratch:XF 3 ""))])]
ba2baa55 15687 "TARGET_USE_FANCY_MATH_387
3b8e0c91
UB
15688 && flag_unsafe_math_optimizations"
15689{
15690 operands[2] = gen_reg_rtx (XFmode);
15691 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15692})
15693
c2fcfa4f
UB
15694(define_insn "fyl2xp1_xf3"
15695 [(set (match_operand:XF 0 "register_operand" "=f")
15696 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15697 (match_operand:XF 1 "register_operand" "u")]
15698 UNSPEC_FYL2XP1))
15699 (clobber (match_scratch:XF 3 "=1"))]
ba2baa55 15700 "TARGET_USE_FANCY_MATH_387
c2fcfa4f
UB
15701 && flag_unsafe_math_optimizations"
15702 "fyl2xp1"
15703 [(set_attr "type" "fpspc")
15704 (set_attr "mode" "XF")])
15705
15706(define_expand "log1psf2"
088df4c2
UB
15707 [(use (match_operand:SF 0 "register_operand" ""))
15708 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 15709 "TARGET_USE_FANCY_MATH_387
c2fcfa4f
UB
15710 && flag_unsafe_math_optimizations"
15711{
15712 rtx op0 = gen_reg_rtx (XFmode);
15713 rtx op1 = gen_reg_rtx (XFmode);
15714
15715 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15716 ix86_emit_i387_log1p (op0, op1);
5b1f1e63 15717 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
c2fcfa4f
UB
15718 DONE;
15719})
15720
15721(define_expand "log1pdf2"
088df4c2
UB
15722 [(use (match_operand:DF 0 "register_operand" ""))
15723 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 15724 "TARGET_USE_FANCY_MATH_387
c2fcfa4f
UB
15725 && flag_unsafe_math_optimizations"
15726{
15727 rtx op0 = gen_reg_rtx (XFmode);
15728 rtx op1 = gen_reg_rtx (XFmode);
15729
15730 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15731 ix86_emit_i387_log1p (op0, op1);
5b1f1e63 15732 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
c2fcfa4f
UB
15733 DONE;
15734})
15735
15736(define_expand "log1pxf2"
15737 [(use (match_operand:XF 0 "register_operand" ""))
15738 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 15739 "TARGET_USE_FANCY_MATH_387
c2fcfa4f
UB
15740 && flag_unsafe_math_optimizations"
15741{
15742 ix86_emit_i387_log1p (operands[0], operands[1]);
15743 DONE;
15744})
15745
6adcf89d
UB
15746(define_insn "*fxtractxf3"
15747 [(set (match_operand:XF 0 "register_operand" "=f")
15748 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
88b28a31 15749 UNSPEC_XTRACT_FRACT))
6adcf89d
UB
15750 (set (match_operand:XF 1 "register_operand" "=u")
15751 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
ba2baa55 15752 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
15753 && flag_unsafe_math_optimizations"
15754 "fxtract"
15755 [(set_attr "type" "fpspc")
6adcf89d 15756 (set_attr "mode" "XF")])
88b28a31 15757
6adcf89d
UB
15758(define_expand "logbsf2"
15759 [(set (match_dup 2)
15760 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15761 (parallel [(set (match_dup 3)
15762 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15763 (set (match_dup 4)
15764 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15765 (set (match_operand:SF 0 "register_operand" "")
15766 (float_truncate:SF (match_dup 4)))]
ba2baa55 15767 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
15768 && flag_unsafe_math_optimizations"
15769{
6adcf89d
UB
15770 operands[2] = gen_reg_rtx (XFmode);
15771 operands[3] = gen_reg_rtx (XFmode);
15772 operands[4] = gen_reg_rtx (XFmode);
88b28a31
UB
15773})
15774
6adcf89d
UB
15775(define_expand "logbdf2"
15776 [(set (match_dup 2)
15777 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15778 (parallel [(set (match_dup 3)
15779 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15780 (set (match_dup 4)
15781 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15782 (set (match_operand:DF 0 "register_operand" "")
15783 (float_truncate:DF (match_dup 4)))]
ba2baa55 15784 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
15785 && flag_unsafe_math_optimizations"
15786{
6adcf89d
UB
15787 operands[2] = gen_reg_rtx (XFmode);
15788 operands[3] = gen_reg_rtx (XFmode);
15789 operands[4] = gen_reg_rtx (XFmode);
88b28a31
UB
15790})
15791
88b28a31
UB
15792(define_expand "logbxf2"
15793 [(parallel [(set (match_dup 2)
15794 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15795 UNSPEC_XTRACT_FRACT))
15796 (set (match_operand:XF 0 "register_operand" "")
15797 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
ba2baa55 15798 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
15799 && flag_unsafe_math_optimizations"
15800{
15801 operands[2] = gen_reg_rtx (XFmode);
15802})
15803
15804(define_expand "ilogbsi2"
15805 [(parallel [(set (match_dup 2)
15806 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15807 UNSPEC_XTRACT_FRACT))
15808 (set (match_operand:XF 3 "register_operand" "")
15809 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15810 (parallel [(set (match_operand:SI 0 "register_operand" "")
15811 (fix:SI (match_dup 3)))
8bc527af 15812 (clobber (reg:CC FLAGS_REG))])]
ba2baa55 15813 "TARGET_USE_FANCY_MATH_387
88b28a31
UB
15814 && flag_unsafe_math_optimizations"
15815{
15816 operands[2] = gen_reg_rtx (XFmode);
15817 operands[3] = gen_reg_rtx (XFmode);
15818})
15819
9d5b9dae
RS
15820(define_insn "*f2xm1xf2"
15821 [(set (match_operand:XF 0 "register_operand" "=f")
15822 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15823 UNSPEC_F2XM1))]
ba2baa55 15824 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15825 && flag_unsafe_math_optimizations"
9d5b9dae
RS
15826 "f2xm1"
15827 [(set_attr "type" "fpspc")
15828 (set_attr "mode" "XF")])
15829
f964bd29
UB
15830(define_insn "*fscalexf4"
15831 [(set (match_operand:XF 0 "register_operand" "=f")
15832 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15833 (match_operand:XF 3 "register_operand" "1")]
15834 UNSPEC_FSCALE_FRACT))
15835 (set (match_operand:XF 1 "register_operand" "=u")
15836 (unspec:XF [(match_dup 2) (match_dup 3)]
15837 UNSPEC_FSCALE_EXP))]
ba2baa55 15838 "TARGET_USE_FANCY_MATH_387
f964bd29
UB
15839 && flag_unsafe_math_optimizations"
15840 "fscale"
15841 [(set_attr "type" "fpspc")
152e3565 15842 (set_attr "mode" "XF")])
f964bd29 15843
9d5b9dae
RS
15844(define_expand "expsf2"
15845 [(set (match_dup 2)
15846 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15847 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15848 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15849 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15850 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15851 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
f964bd29
UB
15852 (parallel [(set (match_dup 10)
15853 (unspec:XF [(match_dup 9) (match_dup 5)]
15854 UNSPEC_FSCALE_FRACT))
15855 (set (match_dup 11)
15856 (unspec:XF [(match_dup 9) (match_dup 5)]
15857 UNSPEC_FSCALE_EXP))])
15858 (set (match_operand:SF 0 "register_operand" "")
15859 (float_truncate:SF (match_dup 10)))]
ba2baa55 15860 "TARGET_USE_FANCY_MATH_387
9d5b9dae
RS
15861 && flag_unsafe_math_optimizations"
15862{
15863 rtx temp;
15864 int i;
15865
f964bd29 15866 for (i=2; i<12; i++)
9d5b9dae
RS
15867 operands[i] = gen_reg_rtx (XFmode);
15868 temp = standard_80387_constant_rtx (5); /* fldl2e */
15869 emit_move_insn (operands[3], temp);
15870 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15871})
15872
15873(define_expand "expdf2"
15874 [(set (match_dup 2)
15875 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15876 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15877 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15878 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15879 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15880 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
f964bd29
UB
15881 (parallel [(set (match_dup 10)
15882 (unspec:XF [(match_dup 9) (match_dup 5)]
15883 UNSPEC_FSCALE_FRACT))
15884 (set (match_dup 11)
15885 (unspec:XF [(match_dup 9) (match_dup 5)]
15886 UNSPEC_FSCALE_EXP))])
15887 (set (match_operand:DF 0 "register_operand" "")
15888 (float_truncate:DF (match_dup 10)))]
ba2baa55 15889 "TARGET_USE_FANCY_MATH_387
9d5b9dae
RS
15890 && flag_unsafe_math_optimizations"
15891{
15892 rtx temp;
15893 int i;
15894
f964bd29 15895 for (i=2; i<12; i++)
9d5b9dae
RS
15896 operands[i] = gen_reg_rtx (XFmode);
15897 temp = standard_80387_constant_rtx (5); /* fldl2e */
15898 emit_move_insn (operands[3], temp);
15899 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15900})
15901
15902(define_expand "expxf2"
15903 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15904 (match_dup 2)))
15905 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15906 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15907 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15908 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15909 (parallel [(set (match_operand:XF 0 "register_operand" "")
f964bd29
UB
15910 (unspec:XF [(match_dup 8) (match_dup 4)]
15911 UNSPEC_FSCALE_FRACT))
15912 (set (match_dup 9)
15913 (unspec:XF [(match_dup 8) (match_dup 4)]
15914 UNSPEC_FSCALE_EXP))])]
ba2baa55 15915 "TARGET_USE_FANCY_MATH_387
f8a1ebc6 15916 && flag_unsafe_math_optimizations"
9d5b9dae
RS
15917{
15918 rtx temp;
15919 int i;
15920
f964bd29 15921 for (i=2; i<10; i++)
9d5b9dae
RS
15922 operands[i] = gen_reg_rtx (XFmode);
15923 temp = standard_80387_constant_rtx (5); /* fldl2e */
15924 emit_move_insn (operands[2], temp);
15925 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15926})
82d397c7 15927
a251102e
UB
15928(define_expand "exp10sf2"
15929 [(set (match_dup 2)
15930 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15931 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15932 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15933 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15934 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15935 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
f964bd29
UB
15936 (parallel [(set (match_dup 10)
15937 (unspec:XF [(match_dup 9) (match_dup 5)]
15938 UNSPEC_FSCALE_FRACT))
15939 (set (match_dup 11)
15940 (unspec:XF [(match_dup 9) (match_dup 5)]
15941 UNSPEC_FSCALE_EXP))])
15942 (set (match_operand:SF 0 "register_operand" "")
15943 (float_truncate:SF (match_dup 10)))]
ba2baa55 15944 "TARGET_USE_FANCY_MATH_387
a251102e
UB
15945 && flag_unsafe_math_optimizations"
15946{
15947 rtx temp;
15948 int i;
15949
f964bd29 15950 for (i=2; i<12; i++)
a251102e
UB
15951 operands[i] = gen_reg_rtx (XFmode);
15952 temp = standard_80387_constant_rtx (6); /* fldl2t */
15953 emit_move_insn (operands[3], temp);
15954 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15955})
15956
15957(define_expand "exp10df2"
15958 [(set (match_dup 2)
15959 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15960 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15961 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15962 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15963 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15964 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
f964bd29
UB
15965 (parallel [(set (match_dup 10)
15966 (unspec:XF [(match_dup 9) (match_dup 5)]
15967 UNSPEC_FSCALE_FRACT))
15968 (set (match_dup 11)
15969 (unspec:XF [(match_dup 9) (match_dup 5)]
15970 UNSPEC_FSCALE_EXP))])
15971 (set (match_operand:DF 0 "register_operand" "")
15972 (float_truncate:DF (match_dup 10)))]
ba2baa55 15973 "TARGET_USE_FANCY_MATH_387
a251102e
UB
15974 && flag_unsafe_math_optimizations"
15975{
15976 rtx temp;
15977 int i;
15978
f964bd29 15979 for (i=2; i<12; i++)
a251102e
UB
15980 operands[i] = gen_reg_rtx (XFmode);
15981 temp = standard_80387_constant_rtx (6); /* fldl2t */
15982 emit_move_insn (operands[3], temp);
15983 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15984})
15985
15986(define_expand "exp10xf2"
15987 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15988 (match_dup 2)))
15989 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15990 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15991 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15992 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15993 (parallel [(set (match_operand:XF 0 "register_operand" "")
f964bd29
UB
15994 (unspec:XF [(match_dup 8) (match_dup 4)]
15995 UNSPEC_FSCALE_FRACT))
15996 (set (match_dup 9)
15997 (unspec:XF [(match_dup 8) (match_dup 4)]
15998 UNSPEC_FSCALE_EXP))])]
ba2baa55 15999 "TARGET_USE_FANCY_MATH_387
a251102e
UB
16000 && flag_unsafe_math_optimizations"
16001{
16002 rtx temp;
16003 int i;
16004
f964bd29 16005 for (i=2; i<10; i++)
a251102e
UB
16006 operands[i] = gen_reg_rtx (XFmode);
16007 temp = standard_80387_constant_rtx (6); /* fldl2t */
16008 emit_move_insn (operands[2], temp);
16009 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16010})
16011
16012(define_expand "exp2sf2"
16013 [(set (match_dup 2)
16014 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16015 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16016 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16017 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16018 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
f964bd29
UB
16019 (parallel [(set (match_dup 8)
16020 (unspec:XF [(match_dup 7) (match_dup 3)]
16021 UNSPEC_FSCALE_FRACT))
16022 (set (match_dup 9)
16023 (unspec:XF [(match_dup 7) (match_dup 3)]
16024 UNSPEC_FSCALE_EXP))])
16025 (set (match_operand:SF 0 "register_operand" "")
16026 (float_truncate:SF (match_dup 8)))]
ba2baa55 16027 "TARGET_USE_FANCY_MATH_387
a251102e
UB
16028 && flag_unsafe_math_optimizations"
16029{
16030 int i;
16031
f964bd29 16032 for (i=2; i<10; i++)
a251102e
UB
16033 operands[i] = gen_reg_rtx (XFmode);
16034 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16035})
16036
16037(define_expand "exp2df2"
16038 [(set (match_dup 2)
16039 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16040 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16041 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16042 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16043 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
f964bd29
UB
16044 (parallel [(set (match_dup 8)
16045 (unspec:XF [(match_dup 7) (match_dup 3)]
16046 UNSPEC_FSCALE_FRACT))
16047 (set (match_dup 9)
16048 (unspec:XF [(match_dup 7) (match_dup 3)]
16049 UNSPEC_FSCALE_EXP))])
16050 (set (match_operand:DF 0 "register_operand" "")
16051 (float_truncate:DF (match_dup 8)))]
ba2baa55 16052 "TARGET_USE_FANCY_MATH_387
a251102e
UB
16053 && flag_unsafe_math_optimizations"
16054{
16055 int i;
16056
f964bd29 16057 for (i=2; i<10; i++)
a251102e
UB
16058 operands[i] = gen_reg_rtx (XFmode);
16059 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16060})
16061
16062(define_expand "exp2xf2"
16063 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16064 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16065 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16066 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16067 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16068 (parallel [(set (match_operand:XF 0 "register_operand" "")
f964bd29
UB
16069 (unspec:XF [(match_dup 7) (match_dup 3)]
16070 UNSPEC_FSCALE_FRACT))
16071 (set (match_dup 8)
16072 (unspec:XF [(match_dup 7) (match_dup 3)]
16073 UNSPEC_FSCALE_EXP))])]
ba2baa55 16074 "TARGET_USE_FANCY_MATH_387
a251102e
UB
16075 && flag_unsafe_math_optimizations"
16076{
16077 int i;
16078
f964bd29 16079 for (i=2; i<9; i++)
a251102e
UB
16080 operands[i] = gen_reg_rtx (XFmode);
16081 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16082})
7a8e07c7
UB
16083
16084(define_expand "expm1df2"
16085 [(set (match_dup 2)
16086 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16087 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16088 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16089 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16090 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16091 (parallel [(set (match_dup 8)
16092 (unspec:XF [(match_dup 7) (match_dup 5)]
16093 UNSPEC_FSCALE_FRACT))
16094 (set (match_dup 9)
16095 (unspec:XF [(match_dup 7) (match_dup 5)]
16096 UNSPEC_FSCALE_EXP))])
16097 (parallel [(set (match_dup 11)
16098 (unspec:XF [(match_dup 10) (match_dup 9)]
16099 UNSPEC_FSCALE_FRACT))
16100 (set (match_dup 12)
16101 (unspec:XF [(match_dup 10) (match_dup 9)]
16102 UNSPEC_FSCALE_EXP))])
16103 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16104 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16105 (set (match_operand:DF 0 "register_operand" "")
16106 (float_truncate:DF (match_dup 14)))]
ba2baa55 16107 "TARGET_USE_FANCY_MATH_387
7a8e07c7
UB
16108 && flag_unsafe_math_optimizations"
16109{
16110 rtx temp;
16111 int i;
16112
16113 for (i=2; i<15; i++)
16114 operands[i] = gen_reg_rtx (XFmode);
16115 temp = standard_80387_constant_rtx (5); /* fldl2e */
16116 emit_move_insn (operands[3], temp);
16117 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16118})
16119
16120(define_expand "expm1sf2"
16121 [(set (match_dup 2)
16122 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16123 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16124 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16125 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16126 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16127 (parallel [(set (match_dup 8)
16128 (unspec:XF [(match_dup 7) (match_dup 5)]
16129 UNSPEC_FSCALE_FRACT))
16130 (set (match_dup 9)
16131 (unspec:XF [(match_dup 7) (match_dup 5)]
16132 UNSPEC_FSCALE_EXP))])
16133 (parallel [(set (match_dup 11)
16134 (unspec:XF [(match_dup 10) (match_dup 9)]
16135 UNSPEC_FSCALE_FRACT))
16136 (set (match_dup 12)
16137 (unspec:XF [(match_dup 10) (match_dup 9)]
16138 UNSPEC_FSCALE_EXP))])
16139 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16140 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16141 (set (match_operand:SF 0 "register_operand" "")
16142 (float_truncate:SF (match_dup 14)))]
ba2baa55 16143 "TARGET_USE_FANCY_MATH_387
7a8e07c7
UB
16144 && flag_unsafe_math_optimizations"
16145{
16146 rtx temp;
16147 int i;
16148
16149 for (i=2; i<15; i++)
16150 operands[i] = gen_reg_rtx (XFmode);
16151 temp = standard_80387_constant_rtx (5); /* fldl2e */
16152 emit_move_insn (operands[3], temp);
16153 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16154})
16155
16156(define_expand "expm1xf2"
16157 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16158 (match_dup 2)))
16159 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16160 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16161 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16162 (parallel [(set (match_dup 7)
16163 (unspec:XF [(match_dup 6) (match_dup 4)]
16164 UNSPEC_FSCALE_FRACT))
16165 (set (match_dup 8)
16166 (unspec:XF [(match_dup 6) (match_dup 4)]
16167 UNSPEC_FSCALE_EXP))])
16168 (parallel [(set (match_dup 10)
16169 (unspec:XF [(match_dup 9) (match_dup 8)]
16170 UNSPEC_FSCALE_FRACT))
16171 (set (match_dup 11)
16172 (unspec:XF [(match_dup 9) (match_dup 8)]
16173 UNSPEC_FSCALE_EXP))])
16174 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16175 (set (match_operand:XF 0 "register_operand" "")
16176 (plus:XF (match_dup 12) (match_dup 7)))]
ba2baa55 16177 "TARGET_USE_FANCY_MATH_387
7a8e07c7
UB
16178 && flag_unsafe_math_optimizations"
16179{
16180 rtx temp;
16181 int i;
16182
16183 for (i=2; i<13; i++)
16184 operands[i] = gen_reg_rtx (XFmode);
16185 temp = standard_80387_constant_rtx (5); /* fldl2e */
16186 emit_move_insn (operands[2], temp);
16187 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16188})
edeacc14
UB
16189\f
16190
16191(define_insn "frndintxf2"
16192 [(set (match_operand:XF 0 "register_operand" "=f")
16193 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16194 UNSPEC_FRNDINT))]
ba2baa55 16195 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16196 && flag_unsafe_math_optimizations"
16197 "frndint"
16198 [(set_attr "type" "fpspc")
16199 (set_attr "mode" "XF")])
16200
16201(define_expand "rintdf2"
16202 [(use (match_operand:DF 0 "register_operand" ""))
16203 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 16204 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16205 && flag_unsafe_math_optimizations"
16206{
16207 rtx op0 = gen_reg_rtx (XFmode);
16208 rtx op1 = gen_reg_rtx (XFmode);
16209
16210 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16211 emit_insn (gen_frndintxf2 (op0, op1));
16212
5b1f1e63 16213 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
edeacc14
UB
16214 DONE;
16215})
16216
16217(define_expand "rintsf2"
16218 [(use (match_operand:SF 0 "register_operand" ""))
16219 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 16220 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16221 && flag_unsafe_math_optimizations"
16222{
16223 rtx op0 = gen_reg_rtx (XFmode);
16224 rtx op1 = gen_reg_rtx (XFmode);
16225
16226 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16227 emit_insn (gen_frndintxf2 (op0, op1));
16228
5b1f1e63 16229 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
edeacc14
UB
16230 DONE;
16231})
16232
16233(define_expand "rintxf2"
16234 [(use (match_operand:XF 0 "register_operand" ""))
16235 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 16236 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16237 && flag_unsafe_math_optimizations"
16238{
16239 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16240 DONE;
16241})
16242
16243(define_insn "frndintxf2_floor"
16244 [(set (match_operand:XF 0 "register_operand" "=f")
16245 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16246 UNSPEC_FRNDINT_FLOOR))
16247 (use (match_operand:HI 2 "memory_operand" "m"))
16248 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 16249 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16250 && flag_unsafe_math_optimizations"
16251 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16252 [(set_attr "type" "frndint")
16253 (set_attr "i387_cw" "floor")
16254 (set_attr "mode" "XF")])
16255
16256(define_expand "floordf2"
16257 [(use (match_operand:DF 0 "register_operand" ""))
16258 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 16259 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16260 && flag_unsafe_math_optimizations"
16261{
16262 rtx op0 = gen_reg_rtx (XFmode);
16263 rtx op1 = gen_reg_rtx (XFmode);
16264 rtx op2 = assign_386_stack_local (HImode, 1);
16265 rtx op3 = assign_386_stack_local (HImode, 2);
16266
16267 ix86_optimize_mode_switching = 1;
16268
16269 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16270 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16271
5b1f1e63 16272 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
edeacc14
UB
16273 DONE;
16274})
16275
16276(define_expand "floorsf2"
16277 [(use (match_operand:SF 0 "register_operand" ""))
16278 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 16279 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16280 && flag_unsafe_math_optimizations"
16281{
16282 rtx op0 = gen_reg_rtx (XFmode);
16283 rtx op1 = gen_reg_rtx (XFmode);
16284 rtx op2 = assign_386_stack_local (HImode, 1);
16285 rtx op3 = assign_386_stack_local (HImode, 2);
16286
16287 ix86_optimize_mode_switching = 1;
16288
16289 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16290 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16291
5b1f1e63 16292 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
edeacc14
UB
16293 DONE;
16294})
16295
16296(define_expand "floorxf2"
16297 [(use (match_operand:XF 0 "register_operand" ""))
16298 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 16299 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16300 && flag_unsafe_math_optimizations"
16301{
16302 rtx op2 = assign_386_stack_local (HImode, 1);
16303 rtx op3 = assign_386_stack_local (HImode, 2);
16304
16305 ix86_optimize_mode_switching = 1;
16306
16307 emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16308 DONE;
16309})
16310
16311(define_insn "frndintxf2_ceil"
16312 [(set (match_operand:XF 0 "register_operand" "=f")
16313 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16314 UNSPEC_FRNDINT_CEIL))
16315 (use (match_operand:HI 2 "memory_operand" "m"))
16316 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 16317 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16318 && flag_unsafe_math_optimizations"
16319 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16320 [(set_attr "type" "frndint")
16321 (set_attr "i387_cw" "ceil")
16322 (set_attr "mode" "XF")])
16323
16324(define_expand "ceildf2"
16325 [(use (match_operand:DF 0 "register_operand" ""))
16326 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 16327 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16328 && flag_unsafe_math_optimizations"
16329{
16330 rtx op0 = gen_reg_rtx (XFmode);
16331 rtx op1 = gen_reg_rtx (XFmode);
16332 rtx op2 = assign_386_stack_local (HImode, 1);
16333 rtx op3 = assign_386_stack_local (HImode, 2);
16334
16335 ix86_optimize_mode_switching = 1;
16336
16337 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16338 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16339
5b1f1e63 16340 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
edeacc14
UB
16341 DONE;
16342})
16343
16344(define_expand "ceilsf2"
16345 [(use (match_operand:SF 0 "register_operand" ""))
16346 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 16347 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16348 && flag_unsafe_math_optimizations"
16349{
16350 rtx op0 = gen_reg_rtx (XFmode);
16351 rtx op1 = gen_reg_rtx (XFmode);
16352 rtx op2 = assign_386_stack_local (HImode, 1);
16353 rtx op3 = assign_386_stack_local (HImode, 2);
16354
16355 ix86_optimize_mode_switching = 1;
16356
16357 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16358 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16359
5b1f1e63 16360 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
edeacc14
UB
16361 DONE;
16362})
16363
16364(define_expand "ceilxf2"
16365 [(use (match_operand:XF 0 "register_operand" ""))
16366 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 16367 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16368 && flag_unsafe_math_optimizations"
16369{
16370 rtx op2 = assign_386_stack_local (HImode, 1);
16371 rtx op3 = assign_386_stack_local (HImode, 2);
16372
16373 ix86_optimize_mode_switching = 1;
16374
16375 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16376 DONE;
16377})
16378
16379(define_insn "frndintxf2_trunc"
16380 [(set (match_operand:XF 0 "register_operand" "=f")
16381 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16382 UNSPEC_FRNDINT_TRUNC))
16383 (use (match_operand:HI 2 "memory_operand" "m"))
16384 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 16385 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16386 && flag_unsafe_math_optimizations"
16387 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16388 [(set_attr "type" "frndint")
16389 (set_attr "i387_cw" "trunc")
16390 (set_attr "mode" "XF")])
16391
16392(define_expand "btruncdf2"
16393 [(use (match_operand:DF 0 "register_operand" ""))
16394 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 16395 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16396 && flag_unsafe_math_optimizations"
16397{
16398 rtx op0 = gen_reg_rtx (XFmode);
16399 rtx op1 = gen_reg_rtx (XFmode);
16400 rtx op2 = assign_386_stack_local (HImode, 1);
16401 rtx op3 = assign_386_stack_local (HImode, 2);
16402
16403 ix86_optimize_mode_switching = 1;
16404
16405 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16406 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16407
5b1f1e63 16408 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
edeacc14
UB
16409 DONE;
16410})
16411
16412(define_expand "btruncsf2"
16413 [(use (match_operand:SF 0 "register_operand" ""))
16414 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 16415 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16416 && flag_unsafe_math_optimizations"
16417{
16418 rtx op0 = gen_reg_rtx (XFmode);
16419 rtx op1 = gen_reg_rtx (XFmode);
16420 rtx op2 = assign_386_stack_local (HImode, 1);
16421 rtx op3 = assign_386_stack_local (HImode, 2);
16422
16423 ix86_optimize_mode_switching = 1;
16424
16425 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16426 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16427
5b1f1e63 16428 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
edeacc14
UB
16429 DONE;
16430})
16431
16432(define_expand "btruncxf2"
16433 [(use (match_operand:XF 0 "register_operand" ""))
16434 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 16435 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16436 && flag_unsafe_math_optimizations"
16437{
16438 rtx op2 = assign_386_stack_local (HImode, 1);
16439 rtx op3 = assign_386_stack_local (HImode, 2);
16440
16441 ix86_optimize_mode_switching = 1;
16442
16443 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16444 DONE;
16445})
16446
16447(define_insn "frndintxf2_mask_pm"
16448 [(set (match_operand:XF 0 "register_operand" "=f")
16449 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16450 UNSPEC_FRNDINT_MASK_PM))
16451 (use (match_operand:HI 2 "memory_operand" "m"))
16452 (use (match_operand:HI 3 "memory_operand" "m"))]
ba2baa55 16453 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16454 && flag_unsafe_math_optimizations"
16455 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16456 [(set_attr "type" "frndint")
16457 (set_attr "i387_cw" "mask_pm")
16458 (set_attr "mode" "XF")])
16459
16460(define_expand "nearbyintdf2"
16461 [(use (match_operand:DF 0 "register_operand" ""))
16462 (use (match_operand:DF 1 "register_operand" ""))]
ba2baa55 16463 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16464 && flag_unsafe_math_optimizations"
16465{
16466 rtx op0 = gen_reg_rtx (XFmode);
16467 rtx op1 = gen_reg_rtx (XFmode);
16468 rtx op2 = assign_386_stack_local (HImode, 1);
16469 rtx op3 = assign_386_stack_local (HImode, 2);
16470
16471 ix86_optimize_mode_switching = 1;
16472
16473 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16474 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16475
5b1f1e63 16476 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
edeacc14
UB
16477 DONE;
16478})
16479
16480(define_expand "nearbyintsf2"
16481 [(use (match_operand:SF 0 "register_operand" ""))
16482 (use (match_operand:SF 1 "register_operand" ""))]
ba2baa55 16483 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16484 && flag_unsafe_math_optimizations"
16485{
16486 rtx op0 = gen_reg_rtx (XFmode);
16487 rtx op1 = gen_reg_rtx (XFmode);
16488 rtx op2 = assign_386_stack_local (HImode, 1);
16489 rtx op3 = assign_386_stack_local (HImode, 2);
16490
16491 ix86_optimize_mode_switching = 1;
16492
16493 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16494 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16495
5b1f1e63 16496 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
edeacc14
UB
16497 DONE;
16498})
16499
16500(define_expand "nearbyintxf2"
16501 [(use (match_operand:XF 0 "register_operand" ""))
16502 (use (match_operand:XF 1 "register_operand" ""))]
ba2baa55 16503 "TARGET_USE_FANCY_MATH_387
edeacc14
UB
16504 && flag_unsafe_math_optimizations"
16505{
16506 rtx op2 = assign_386_stack_local (HImode, 1);
16507 rtx op3 = assign_386_stack_local (HImode, 2);
16508
16509 ix86_optimize_mode_switching = 1;
16510
16511 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16512 op2, op3));
16513 DONE;
16514})
16515
e075ae69
RH
16516\f
16517;; Block operation instructions
886c62d1 16518
7c7ef435 16519(define_insn "cld"
8bc527af 16520 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
7c7ef435
JH
16521 ""
16522 "cld"
16523 [(set_attr "type" "cld")])
16524
70128ad9 16525(define_expand "movmemsi"
f90800f8
JH
16526 [(use (match_operand:BLK 0 "memory_operand" ""))
16527 (use (match_operand:BLK 1 "memory_operand" ""))
79f05c19 16528 (use (match_operand:SI 2 "nonmemory_operand" ""))
f90800f8 16529 (use (match_operand:SI 3 "const_int_operand" ""))]
c43fa1f5 16530 "! optimize_size"
886c62d1 16531{
70128ad9 16532 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
0945b39d
JH
16533 DONE;
16534 else
16535 FAIL;
0f40f9f7 16536})
79f05c19 16537
70128ad9 16538(define_expand "movmemdi"
0945b39d
JH
16539 [(use (match_operand:BLK 0 "memory_operand" ""))
16540 (use (match_operand:BLK 1 "memory_operand" ""))
16541 (use (match_operand:DI 2 "nonmemory_operand" ""))
16542 (use (match_operand:DI 3 "const_int_operand" ""))]
16543 "TARGET_64BIT"
0945b39d 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
0945b39d
JH
16551;; Most CPUs don't like single string operations
16552;; Handle this case here to simplify previous expander.
79f05c19 16553
4e44c1ef
JJ
16554(define_expand "strmov"
16555 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16556 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16557 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
8bc527af 16558 (clobber (reg:CC FLAGS_REG))])
4e44c1ef 16559 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
8bc527af 16560 (clobber (reg:CC FLAGS_REG))])]
79f05c19 16561 ""
79f05c19 16562{
4e44c1ef 16563 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
79f05c19 16564
4e44c1ef
JJ
16565 /* If .md ever supports :P for Pmode, these can be directly
16566 in the pattern above. */
16567 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16568 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
0945b39d 16569
f90800f8 16570 if (TARGET_SINGLE_STRINGOP || optimize_size)
886c62d1 16571 {
4e44c1ef
JJ
16572 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16573 operands[2], operands[3],
16574 operands[5], operands[6]));
f90800f8
JH
16575 DONE;
16576 }
886c62d1 16577
4e44c1ef 16578 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
0f40f9f7 16579})
f90800f8 16580
4e44c1ef
JJ
16581(define_expand "strmov_singleop"
16582 [(parallel [(set (match_operand 1 "memory_operand" "")
16583 (match_operand 3 "memory_operand" ""))
16584 (set (match_operand 0 "register_operand" "")
16585 (match_operand 4 "" ""))
16586 (set (match_operand 2 "register_operand" "")
16587 (match_operand 5 "" ""))
8bc527af 16588 (use (reg:SI DIRFLAG_REG))])]
4e44c1ef
JJ
16589 "TARGET_SINGLE_STRINGOP || optimize_size"
16590 "")
0945b39d 16591
4e44c1ef 16592(define_insn "*strmovdi_rex_1"
0945b39d
JH
16593 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16594 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16595 (set (match_operand:DI 0 "register_operand" "=D")
16596 (plus:DI (match_dup 2)
16597 (const_int 8)))
16598 (set (match_operand:DI 1 "register_operand" "=S")
16599 (plus:DI (match_dup 3)
16600 (const_int 8)))
8bc527af 16601 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16602 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16603 "movsq"
16604 [(set_attr "type" "str")
16605 (set_attr "mode" "DI")
16606 (set_attr "memory" "both")])
16607
4e44c1ef 16608(define_insn "*strmovsi_1"
79f05c19
JH
16609 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16610 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16611 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16612 (plus:SI (match_dup 2)
79f05c19
JH
16613 (const_int 4)))
16614 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 16615 (plus:SI (match_dup 3)
79f05c19 16616 (const_int 4)))
8bc527af 16617 (use (reg:SI DIRFLAG_REG))]
0945b39d 16618 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
371bc54b 16619 "{movsl|movsd}"
0945b39d
JH
16620 [(set_attr "type" "str")
16621 (set_attr "mode" "SI")
16622 (set_attr "memory" "both")])
16623
4e44c1ef 16624(define_insn "*strmovsi_rex_1"
0945b39d
JH
16625 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16626 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16627 (set (match_operand:DI 0 "register_operand" "=D")
16628 (plus:DI (match_dup 2)
16629 (const_int 4)))
16630 (set (match_operand:DI 1 "register_operand" "=S")
16631 (plus:DI (match_dup 3)
16632 (const_int 4)))
8bc527af 16633 (use (reg:SI DIRFLAG_REG))]
0945b39d 16634 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
371bc54b 16635 "{movsl|movsd}"
79f05c19 16636 [(set_attr "type" "str")
6ef67412 16637 (set_attr "mode" "SI")
79f05c19
JH
16638 (set_attr "memory" "both")])
16639
4e44c1ef 16640(define_insn "*strmovhi_1"
f90800f8
JH
16641 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16642 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16643 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16644 (plus:SI (match_dup 2)
f90800f8
JH
16645 (const_int 2)))
16646 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 16647 (plus:SI (match_dup 3)
f90800f8 16648 (const_int 2)))
8bc527af 16649 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16650 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16651 "movsw"
16652 [(set_attr "type" "str")
16653 (set_attr "memory" "both")
16654 (set_attr "mode" "HI")])
16655
4e44c1ef 16656(define_insn "*strmovhi_rex_1"
0945b39d
JH
16657 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16658 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16659 (set (match_operand:DI 0 "register_operand" "=D")
16660 (plus:DI (match_dup 2)
16661 (const_int 2)))
16662 (set (match_operand:DI 1 "register_operand" "=S")
16663 (plus:DI (match_dup 3)
16664 (const_int 2)))
8bc527af 16665 (use (reg:SI DIRFLAG_REG))]
0945b39d 16666 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
f90800f8
JH
16667 "movsw"
16668 [(set_attr "type" "str")
16669 (set_attr "memory" "both")
6ef67412 16670 (set_attr "mode" "HI")])
f90800f8 16671
4e44c1ef 16672(define_insn "*strmovqi_1"
f90800f8
JH
16673 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16674 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16675 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16676 (plus:SI (match_dup 2)
f90800f8
JH
16677 (const_int 1)))
16678 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 16679 (plus:SI (match_dup 3)
f90800f8 16680 (const_int 1)))
8bc527af 16681 (use (reg:SI DIRFLAG_REG))]
0945b39d 16682 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
f90800f8
JH
16683 "movsb"
16684 [(set_attr "type" "str")
6ef67412
JH
16685 (set_attr "memory" "both")
16686 (set_attr "mode" "QI")])
f90800f8 16687
4e44c1ef 16688(define_insn "*strmovqi_rex_1"
0945b39d
JH
16689 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16690 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16691 (set (match_operand:DI 0 "register_operand" "=D")
16692 (plus:DI (match_dup 2)
16693 (const_int 1)))
16694 (set (match_operand:DI 1 "register_operand" "=S")
16695 (plus:DI (match_dup 3)
16696 (const_int 1)))
8bc527af 16697 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16698 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16699 "movsb"
16700 [(set_attr "type" "str")
16701 (set_attr "memory" "both")
16702 (set_attr "mode" "QI")])
16703
4e44c1ef
JJ
16704(define_expand "rep_mov"
16705 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16706 (set (match_operand 0 "register_operand" "")
16707 (match_operand 5 "" ""))
16708 (set (match_operand 2 "register_operand" "")
16709 (match_operand 6 "" ""))
16710 (set (match_operand 1 "memory_operand" "")
16711 (match_operand 3 "memory_operand" ""))
16712 (use (match_dup 4))
8bc527af 16713 (use (reg:SI DIRFLAG_REG))])]
4e44c1ef
JJ
16714 ""
16715 "")
16716
16717(define_insn "*rep_movdi_rex64"
0945b39d
JH
16718 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16719 (set (match_operand:DI 0 "register_operand" "=D")
16720 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16721 (const_int 3))
16722 (match_operand:DI 3 "register_operand" "0")))
16723 (set (match_operand:DI 1 "register_operand" "=S")
16724 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16725 (match_operand:DI 4 "register_operand" "1")))
16726 (set (mem:BLK (match_dup 3))
16727 (mem:BLK (match_dup 4)))
16728 (use (match_dup 5))
8bc527af 16729 (use (reg:SI DIRFLAG_REG))]
0945b39d 16730 "TARGET_64BIT"
8554d9a4 16731 "{rep\;movsq|rep movsq}"
0945b39d
JH
16732 [(set_attr "type" "str")
16733 (set_attr "prefix_rep" "1")
16734 (set_attr "memory" "both")
16735 (set_attr "mode" "DI")])
16736
4e44c1ef 16737(define_insn "*rep_movsi"
f90800f8 16738 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
f90800f8 16739 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
16740 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16741 (const_int 2))
16742 (match_operand:SI 3 "register_operand" "0")))
f90800f8 16743 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb
JH
16744 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16745 (match_operand:SI 4 "register_operand" "1")))
f90800f8
JH
16746 (set (mem:BLK (match_dup 3))
16747 (mem:BLK (match_dup 4)))
b1cdafbb 16748 (use (match_dup 5))
8bc527af 16749 (use (reg:SI DIRFLAG_REG))]
0945b39d 16750 "!TARGET_64BIT"
8554d9a4 16751 "{rep\;movsl|rep movsd}"
0945b39d
JH
16752 [(set_attr "type" "str")
16753 (set_attr "prefix_rep" "1")
16754 (set_attr "memory" "both")
16755 (set_attr "mode" "SI")])
16756
4e44c1ef 16757(define_insn "*rep_movsi_rex64"
0945b39d
JH
16758 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16759 (set (match_operand:DI 0 "register_operand" "=D")
16760 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16761 (const_int 2))
16762 (match_operand:DI 3 "register_operand" "0")))
16763 (set (match_operand:DI 1 "register_operand" "=S")
16764 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16765 (match_operand:DI 4 "register_operand" "1")))
16766 (set (mem:BLK (match_dup 3))
16767 (mem:BLK (match_dup 4)))
16768 (use (match_dup 5))
8bc527af 16769 (use (reg:SI DIRFLAG_REG))]
0945b39d 16770 "TARGET_64BIT"
8554d9a4 16771 "{rep\;movsl|rep movsd}"
f90800f8 16772 [(set_attr "type" "str")
6ef67412
JH
16773 (set_attr "prefix_rep" "1")
16774 (set_attr "memory" "both")
16775 (set_attr "mode" "SI")])
f90800f8 16776
4e44c1ef 16777(define_insn "*rep_movqi"
f90800f8 16778 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
f90800f8 16779 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
16780 (plus:SI (match_operand:SI 3 "register_operand" "0")
16781 (match_operand:SI 5 "register_operand" "2")))
f90800f8 16782 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 16783 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
f90800f8
JH
16784 (set (mem:BLK (match_dup 3))
16785 (mem:BLK (match_dup 4)))
b1cdafbb 16786 (use (match_dup 5))
8bc527af 16787 (use (reg:SI DIRFLAG_REG))]
0945b39d 16788 "!TARGET_64BIT"
8554d9a4 16789 "{rep\;movsb|rep movsb}"
0945b39d
JH
16790 [(set_attr "type" "str")
16791 (set_attr "prefix_rep" "1")
16792 (set_attr "memory" "both")
16793 (set_attr "mode" "SI")])
16794
4e44c1ef 16795(define_insn "*rep_movqi_rex64"
0945b39d
JH
16796 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16797 (set (match_operand:DI 0 "register_operand" "=D")
16798 (plus:DI (match_operand:DI 3 "register_operand" "0")
16799 (match_operand:DI 5 "register_operand" "2")))
16800 (set (match_operand:DI 1 "register_operand" "=S")
16801 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16802 (set (mem:BLK (match_dup 3))
16803 (mem:BLK (match_dup 4)))
16804 (use (match_dup 5))
8bc527af 16805 (use (reg:SI DIRFLAG_REG))]
0945b39d 16806 "TARGET_64BIT"
8554d9a4 16807 "{rep\;movsb|rep movsb}"
f90800f8 16808 [(set_attr "type" "str")
6ef67412
JH
16809 (set_attr "prefix_rep" "1")
16810 (set_attr "memory" "both")
16811 (set_attr "mode" "SI")])
886c62d1 16812
70128ad9 16813(define_expand "clrmemsi"
e2e52e1b 16814 [(use (match_operand:BLK 0 "memory_operand" ""))
79f05c19 16815 (use (match_operand:SI 1 "nonmemory_operand" ""))
0945b39d 16816 (use (match_operand 2 "const_int_operand" ""))]
0ae40045 16817 ""
0ae40045 16818{
70128ad9 16819 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
0945b39d
JH
16820 DONE;
16821 else
16822 FAIL;
0f40f9f7 16823})
e2e52e1b 16824
70128ad9 16825(define_expand "clrmemdi"
0945b39d
JH
16826 [(use (match_operand:BLK 0 "memory_operand" ""))
16827 (use (match_operand:DI 1 "nonmemory_operand" ""))
16828 (use (match_operand 2 "const_int_operand" ""))]
16829 "TARGET_64BIT"
0945b39d 16830{
70128ad9 16831 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
0945b39d
JH
16832 DONE;
16833 else
16834 FAIL;
0f40f9f7 16835})
e2e52e1b 16836
0945b39d
JH
16837;; Most CPUs don't like single string operations
16838;; Handle this case here to simplify previous expander.
79f05c19 16839
4e44c1ef
JJ
16840(define_expand "strset"
16841 [(set (match_operand 1 "memory_operand" "")
16842 (match_operand 2 "register_operand" ""))
16843 (parallel [(set (match_operand 0 "register_operand" "")
16844 (match_dup 3))
8bc527af 16845 (clobber (reg:CC FLAGS_REG))])]
79f05c19 16846 ""
79f05c19 16847{
4e44c1ef
JJ
16848 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16849 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
79f05c19 16850
4e44c1ef
JJ
16851 /* If .md ever supports :P for Pmode, this can be directly
16852 in the pattern above. */
16853 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16854 GEN_INT (GET_MODE_SIZE (GET_MODE
16855 (operands[2]))));
0945b39d
JH
16856 if (TARGET_SINGLE_STRINGOP || optimize_size)
16857 {
4e44c1ef
JJ
16858 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16859 operands[3]));
0945b39d
JH
16860 DONE;
16861 }
0f40f9f7 16862})
0945b39d 16863
4e44c1ef
JJ
16864(define_expand "strset_singleop"
16865 [(parallel [(set (match_operand 1 "memory_operand" "")
16866 (match_operand 2 "register_operand" ""))
16867 (set (match_operand 0 "register_operand" "")
16868 (match_operand 3 "" ""))
8bc527af 16869 (use (reg:SI DIRFLAG_REG))])]
4e44c1ef
JJ
16870 "TARGET_SINGLE_STRINGOP || optimize_size"
16871 "")
0945b39d 16872
4e44c1ef 16873(define_insn "*strsetdi_rex_1"
22116d84
L
16874 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16875 (match_operand:DI 2 "register_operand" "a"))
0945b39d
JH
16876 (set (match_operand:DI 0 "register_operand" "=D")
16877 (plus:DI (match_dup 1)
16878 (const_int 8)))
8bc527af 16879 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16880 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16881 "stosq"
16882 [(set_attr "type" "str")
16883 (set_attr "memory" "store")
16884 (set_attr "mode" "DI")])
16885
4e44c1ef 16886(define_insn "*strsetsi_1"
79f05c19
JH
16887 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16888 (match_operand:SI 2 "register_operand" "a"))
16889 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16890 (plus:SI (match_dup 1)
79f05c19 16891 (const_int 4)))
8bc527af 16892 (use (reg:SI DIRFLAG_REG))]
0945b39d 16893 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
8554d9a4 16894 "{stosl|stosd}"
0945b39d
JH
16895 [(set_attr "type" "str")
16896 (set_attr "memory" "store")
16897 (set_attr "mode" "SI")])
16898
4e44c1ef 16899(define_insn "*strsetsi_rex_1"
0945b39d
JH
16900 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16901 (match_operand:SI 2 "register_operand" "a"))
16902 (set (match_operand:DI 0 "register_operand" "=D")
16903 (plus:DI (match_dup 1)
16904 (const_int 4)))
8bc527af 16905 (use (reg:SI DIRFLAG_REG))]
0945b39d 16906 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
8554d9a4 16907 "{stosl|stosd}"
79f05c19 16908 [(set_attr "type" "str")
6ef67412
JH
16909 (set_attr "memory" "store")
16910 (set_attr "mode" "SI")])
79f05c19 16911
4e44c1ef 16912(define_insn "*strsethi_1"
e2e52e1b
JH
16913 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16914 (match_operand:HI 2 "register_operand" "a"))
16915 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16916 (plus:SI (match_dup 1)
e2e52e1b 16917 (const_int 2)))
8bc527af 16918 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16919 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16920 "stosw"
16921 [(set_attr "type" "str")
16922 (set_attr "memory" "store")
16923 (set_attr "mode" "HI")])
16924
4e44c1ef 16925(define_insn "*strsethi_rex_1"
0945b39d
JH
16926 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16927 (match_operand:HI 2 "register_operand" "a"))
16928 (set (match_operand:DI 0 "register_operand" "=D")
16929 (plus:DI (match_dup 1)
16930 (const_int 2)))
8bc527af 16931 (use (reg:SI DIRFLAG_REG))]
0945b39d 16932 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
e2e52e1b
JH
16933 "stosw"
16934 [(set_attr "type" "str")
16935 (set_attr "memory" "store")
6ef67412 16936 (set_attr "mode" "HI")])
e2e52e1b 16937
4e44c1ef 16938(define_insn "*strsetqi_1"
e2e52e1b
JH
16939 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16940 (match_operand:QI 2 "register_operand" "a"))
16941 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 16942 (plus:SI (match_dup 1)
e2e52e1b 16943 (const_int 1)))
8bc527af 16944 (use (reg:SI DIRFLAG_REG))]
0945b39d
JH
16945 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16946 "stosb"
16947 [(set_attr "type" "str")
16948 (set_attr "memory" "store")
16949 (set_attr "mode" "QI")])
16950
4e44c1ef 16951(define_insn "*strsetqi_rex_1"
0945b39d
JH
16952 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16953 (match_operand:QI 2 "register_operand" "a"))
16954 (set (match_operand:DI 0 "register_operand" "=D")
16955 (plus:DI (match_dup 1)
16956 (const_int 1)))
8bc527af 16957 (use (reg:SI DIRFLAG_REG))]
0945b39d 16958 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
e2e52e1b
JH
16959 "stosb"
16960 [(set_attr "type" "str")
6ef67412
JH
16961 (set_attr "memory" "store")
16962 (set_attr "mode" "QI")])
e2e52e1b 16963
4e44c1ef
JJ
16964(define_expand "rep_stos"
16965 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16966 (set (match_operand 0 "register_operand" "")
16967 (match_operand 4 "" ""))
16968 (set (match_operand 2 "memory_operand" "") (const_int 0))
16969 (use (match_operand 3 "register_operand" ""))
16970 (use (match_dup 1))
8bc527af 16971 (use (reg:SI DIRFLAG_REG))])]
4e44c1ef
JJ
16972 ""
16973 "")
16974
16975(define_insn "*rep_stosdi_rex64"
0945b39d
JH
16976 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16977 (set (match_operand:DI 0 "register_operand" "=D")
16978 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16979 (const_int 3))
16980 (match_operand:DI 3 "register_operand" "0")))
16981 (set (mem:BLK (match_dup 3))
16982 (const_int 0))
16983 (use (match_operand:DI 2 "register_operand" "a"))
16984 (use (match_dup 4))
8bc527af 16985 (use (reg:SI DIRFLAG_REG))]
0945b39d 16986 "TARGET_64BIT"
8554d9a4 16987 "{rep\;stosq|rep stosq}"
0945b39d
JH
16988 [(set_attr "type" "str")
16989 (set_attr "prefix_rep" "1")
16990 (set_attr "memory" "store")
16991 (set_attr "mode" "DI")])
16992
4e44c1ef 16993(define_insn "*rep_stossi"
e2e52e1b 16994 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
e2e52e1b 16995 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
16996 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16997 (const_int 2))
16998 (match_operand:SI 3 "register_operand" "0")))
e2e52e1b 16999 (set (mem:BLK (match_dup 3))
0ae40045 17000 (const_int 0))
b1cdafbb
JH
17001 (use (match_operand:SI 2 "register_operand" "a"))
17002 (use (match_dup 4))
8bc527af 17003 (use (reg:SI DIRFLAG_REG))]
0945b39d 17004 "!TARGET_64BIT"
8554d9a4 17005 "{rep\;stosl|rep stosd}"
0945b39d
JH
17006 [(set_attr "type" "str")
17007 (set_attr "prefix_rep" "1")
17008 (set_attr "memory" "store")
17009 (set_attr "mode" "SI")])
17010
4e44c1ef 17011(define_insn "*rep_stossi_rex64"
0945b39d
JH
17012 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17013 (set (match_operand:DI 0 "register_operand" "=D")
17014 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17015 (const_int 2))
17016 (match_operand:DI 3 "register_operand" "0")))
17017 (set (mem:BLK (match_dup 3))
17018 (const_int 0))
17019 (use (match_operand:SI 2 "register_operand" "a"))
17020 (use (match_dup 4))
8bc527af 17021 (use (reg:SI DIRFLAG_REG))]
0945b39d 17022 "TARGET_64BIT"
8554d9a4 17023 "{rep\;stosl|rep stosd}"
e2e52e1b 17024 [(set_attr "type" "str")
6ef67412
JH
17025 (set_attr "prefix_rep" "1")
17026 (set_attr "memory" "store")
17027 (set_attr "mode" "SI")])
0ae40045 17028
4e44c1ef 17029(define_insn "*rep_stosqi"
e2e52e1b 17030 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
e2e52e1b 17031 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
17032 (plus:SI (match_operand:SI 3 "register_operand" "0")
17033 (match_operand:SI 4 "register_operand" "1")))
e2e52e1b
JH
17034 (set (mem:BLK (match_dup 3))
17035 (const_int 0))
b1cdafbb
JH
17036 (use (match_operand:QI 2 "register_operand" "a"))
17037 (use (match_dup 4))
8bc527af 17038 (use (reg:SI DIRFLAG_REG))]
0945b39d 17039 "!TARGET_64BIT"
8554d9a4 17040 "{rep\;stosb|rep stosb}"
0945b39d
JH
17041 [(set_attr "type" "str")
17042 (set_attr "prefix_rep" "1")
17043 (set_attr "memory" "store")
17044 (set_attr "mode" "QI")])
17045
4e44c1ef 17046(define_insn "*rep_stosqi_rex64"
0945b39d
JH
17047 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17048 (set (match_operand:DI 0 "register_operand" "=D")
17049 (plus:DI (match_operand:DI 3 "register_operand" "0")
17050 (match_operand:DI 4 "register_operand" "1")))
17051 (set (mem:BLK (match_dup 3))
17052 (const_int 0))
17053 (use (match_operand:QI 2 "register_operand" "a"))
17054 (use (match_dup 4))
8bc527af 17055 (use (reg:SI DIRFLAG_REG))]
0945b39d 17056 "TARGET_64BIT"
8554d9a4 17057 "{rep\;stosb|rep stosb}"
e2e52e1b 17058 [(set_attr "type" "str")
6ef67412
JH
17059 (set_attr "prefix_rep" "1")
17060 (set_attr "memory" "store")
17061 (set_attr "mode" "QI")])
0ae40045 17062
886c62d1 17063(define_expand "cmpstrsi"
e075ae69
RH
17064 [(set (match_operand:SI 0 "register_operand" "")
17065 (compare:SI (match_operand:BLK 1 "general_operand" "")
17066 (match_operand:BLK 2 "general_operand" "")))
0945b39d
JH
17067 (use (match_operand 3 "general_operand" ""))
17068 (use (match_operand 4 "immediate_operand" ""))]
87383233 17069 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
886c62d1 17070{
e075ae69
RH
17071 rtx addr1, addr2, out, outlow, count, countreg, align;
17072
d0a5295a
RH
17073 /* Can't use this if the user has appropriated esi or edi. */
17074 if (global_regs[4] || global_regs[5])
17075 FAIL;
17076
e075ae69
RH
17077 out = operands[0];
17078 if (GET_CODE (out) != REG)
17079 out = gen_reg_rtx (SImode);
783cdf65
JVA
17080
17081 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17082 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
4e44c1ef
JJ
17083 if (addr1 != XEXP (operands[1], 0))
17084 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17085 if (addr2 != XEXP (operands[2], 0))
17086 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17087
e075ae69 17088 count = operands[3];
d24b3457 17089 countreg = ix86_zero_extend_to_Pmode (count);
e075ae69
RH
17090
17091 /* %%% Iff we are testing strict equality, we can use known alignment
17092 to good advantage. This may be possible with combine, particularly
17093 once cc0 is dead. */
17094 align = operands[4];
783cdf65 17095
7c7ef435 17096 emit_insn (gen_cld ());
e075ae69
RH
17097 if (GET_CODE (count) == CONST_INT)
17098 {
17099 if (INTVAL (count) == 0)
17100 {
17101 emit_move_insn (operands[0], const0_rtx);
17102 DONE;
17103 }
4e44c1ef
JJ
17104 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17105 operands[1], operands[2]));
e075ae69
RH
17106 }
17107 else
e2e52e1b 17108 {
0945b39d 17109 if (TARGET_64BIT)
4e44c1ef 17110 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
0945b39d 17111 else
4e44c1ef
JJ
17112 emit_insn (gen_cmpsi_1 (countreg, countreg));
17113 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17114 operands[1], operands[2]));
e2e52e1b 17115 }
e075ae69
RH
17116
17117 outlow = gen_lowpart (QImode, out);
17118 emit_insn (gen_cmpintqi (outlow));
17119 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
783cdf65 17120
e075ae69
RH
17121 if (operands[0] != out)
17122 emit_move_insn (operands[0], out);
783cdf65 17123
e075ae69 17124 DONE;
0f40f9f7 17125})
886c62d1 17126
e075ae69
RH
17127;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17128
17129(define_expand "cmpintqi"
17130 [(set (match_dup 1)
8bc527af 17131 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
e075ae69 17132 (set (match_dup 2)
8bc527af 17133 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
e075ae69
RH
17134 (parallel [(set (match_operand:QI 0 "register_operand" "")
17135 (minus:QI (match_dup 1)
17136 (match_dup 2)))
8bc527af 17137 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
17138 ""
17139 "operands[1] = gen_reg_rtx (QImode);
17140 operands[2] = gen_reg_rtx (QImode);")
17141
f76e3b05
JVA
17142;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17143;; zero. Emit extra code to make sure that a zero-length compare is EQ.
56c0e8fa 17144
4e44c1ef 17145(define_expand "cmpstrqi_nz_1"
8bc527af 17146 [(parallel [(set (reg:CC FLAGS_REG)
4e44c1ef
JJ
17147 (compare:CC (match_operand 4 "memory_operand" "")
17148 (match_operand 5 "memory_operand" "")))
17149 (use (match_operand 2 "register_operand" ""))
17150 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af 17151 (use (reg:SI DIRFLAG_REG))
4e44c1ef
JJ
17152 (clobber (match_operand 0 "register_operand" ""))
17153 (clobber (match_operand 1 "register_operand" ""))
17154 (clobber (match_dup 2))])]
17155 ""
17156 "")
17157
17158(define_insn "*cmpstrqi_nz_1"
8bc527af 17159 [(set (reg:CC FLAGS_REG)
b1cdafbb
JH
17160 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17161 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17162 (use (match_operand:SI 6 "register_operand" "2"))
886c62d1 17163 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af 17164 (use (reg:SI DIRFLAG_REG))
b1cdafbb
JH
17165 (clobber (match_operand:SI 0 "register_operand" "=S"))
17166 (clobber (match_operand:SI 1 "register_operand" "=D"))
17167 (clobber (match_operand:SI 2 "register_operand" "=c"))]
0945b39d
JH
17168 "!TARGET_64BIT"
17169 "repz{\;| }cmpsb"
17170 [(set_attr "type" "str")
17171 (set_attr "mode" "QI")
17172 (set_attr "prefix_rep" "1")])
17173
4e44c1ef 17174(define_insn "*cmpstrqi_nz_rex_1"
8bc527af 17175 [(set (reg:CC FLAGS_REG)
0945b39d
JH
17176 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17177 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17178 (use (match_operand:DI 6 "register_operand" "2"))
17179 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af 17180 (use (reg:SI DIRFLAG_REG))
0945b39d
JH
17181 (clobber (match_operand:DI 0 "register_operand" "=S"))
17182 (clobber (match_operand:DI 1 "register_operand" "=D"))
17183 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17184 "TARGET_64BIT"
7c7ef435 17185 "repz{\;| }cmpsb"
e2e52e1b 17186 [(set_attr "type" "str")
6ef67412
JH
17187 (set_attr "mode" "QI")
17188 (set_attr "prefix_rep" "1")])
886c62d1 17189
e075ae69 17190;; The same, but the count is not known to not be zero.
886c62d1 17191
4e44c1ef 17192(define_expand "cmpstrqi_1"
8bc527af 17193 [(parallel [(set (reg:CC FLAGS_REG)
4e44c1ef
JJ
17194 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17195 (const_int 0))
17196 (compare:CC (match_operand 4 "memory_operand" "")
17197 (match_operand 5 "memory_operand" ""))
17198 (const_int 0)))
17199 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af
SB
17200 (use (reg:CC FLAGS_REG))
17201 (use (reg:SI DIRFLAG_REG))
4e44c1ef
JJ
17202 (clobber (match_operand 0 "register_operand" ""))
17203 (clobber (match_operand 1 "register_operand" ""))
17204 (clobber (match_dup 2))])]
17205 ""
17206 "")
17207
17208(define_insn "*cmpstrqi_1"
8bc527af 17209 [(set (reg:CC FLAGS_REG)
b1cdafbb 17210 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
e075ae69 17211 (const_int 0))
2bed3391 17212 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
b1cdafbb 17213 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
e075ae69
RH
17214 (const_int 0)))
17215 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af
SB
17216 (use (reg:CC FLAGS_REG))
17217 (use (reg:SI DIRFLAG_REG))
b1cdafbb
JH
17218 (clobber (match_operand:SI 0 "register_operand" "=S"))
17219 (clobber (match_operand:SI 1 "register_operand" "=D"))
17220 (clobber (match_operand:SI 2 "register_operand" "=c"))]
0945b39d
JH
17221 "!TARGET_64BIT"
17222 "repz{\;| }cmpsb"
17223 [(set_attr "type" "str")
17224 (set_attr "mode" "QI")
17225 (set_attr "prefix_rep" "1")])
17226
4e44c1ef 17227(define_insn "*cmpstrqi_rex_1"
8bc527af 17228 [(set (reg:CC FLAGS_REG)
0945b39d
JH
17229 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17230 (const_int 0))
17231 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17232 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17233 (const_int 0)))
17234 (use (match_operand:SI 3 "immediate_operand" "i"))
8bc527af
SB
17235 (use (reg:CC FLAGS_REG))
17236 (use (reg:SI DIRFLAG_REG))
0945b39d
JH
17237 (clobber (match_operand:DI 0 "register_operand" "=S"))
17238 (clobber (match_operand:DI 1 "register_operand" "=D"))
17239 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17240 "TARGET_64BIT"
e2e52e1b
JH
17241 "repz{\;| }cmpsb"
17242 [(set_attr "type" "str")
6ef67412
JH
17243 (set_attr "mode" "QI")
17244 (set_attr "prefix_rep" "1")])
886c62d1 17245
e075ae69
RH
17246(define_expand "strlensi"
17247 [(set (match_operand:SI 0 "register_operand" "")
17248 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17249 (match_operand:QI 2 "immediate_operand" "")
8ee41eaf 17250 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
886c62d1 17251 ""
886c62d1 17252{
0945b39d
JH
17253 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17254 DONE;
17255 else
17256 FAIL;
0f40f9f7 17257})
e075ae69 17258
0945b39d
JH
17259(define_expand "strlendi"
17260 [(set (match_operand:DI 0 "register_operand" "")
17261 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17262 (match_operand:QI 2 "immediate_operand" "")
8ee41eaf 17263 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
0945b39d 17264 ""
0945b39d
JH
17265{
17266 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17267 DONE;
17268 else
17269 FAIL;
0f40f9f7 17270})
19c3fc24 17271
4e44c1ef
JJ
17272(define_expand "strlenqi_1"
17273 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
8bc527af 17274 (use (reg:SI DIRFLAG_REG))
4e44c1ef 17275 (clobber (match_operand 1 "register_operand" ""))
8bc527af 17276 (clobber (reg:CC FLAGS_REG))])]
4e44c1ef
JJ
17277 ""
17278 "")
17279
17280(define_insn "*strlenqi_1"
e075ae69 17281 [(set (match_operand:SI 0 "register_operand" "=&c")
b1cdafbb 17282 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
0945b39d 17283 (match_operand:QI 2 "register_operand" "a")
e075ae69 17284 (match_operand:SI 3 "immediate_operand" "i")
8ee41eaf 17285 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
8bc527af 17286 (use (reg:SI DIRFLAG_REG))
b1cdafbb 17287 (clobber (match_operand:SI 1 "register_operand" "=D"))
8bc527af 17288 (clobber (reg:CC FLAGS_REG))]
0945b39d
JH
17289 "!TARGET_64BIT"
17290 "repnz{\;| }scasb"
17291 [(set_attr "type" "str")
17292 (set_attr "mode" "QI")
17293 (set_attr "prefix_rep" "1")])
17294
4e44c1ef 17295(define_insn "*strlenqi_rex_1"
0945b39d
JH
17296 [(set (match_operand:DI 0 "register_operand" "=&c")
17297 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17298 (match_operand:QI 2 "register_operand" "a")
17299 (match_operand:DI 3 "immediate_operand" "i")
8ee41eaf 17300 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
8bc527af 17301 (use (reg:SI DIRFLAG_REG))
0945b39d 17302 (clobber (match_operand:DI 1 "register_operand" "=D"))
8bc527af 17303 (clobber (reg:CC FLAGS_REG))]
0945b39d 17304 "TARGET_64BIT"
7c7ef435 17305 "repnz{\;| }scasb"
e2e52e1b 17306 [(set_attr "type" "str")
6ef67412
JH
17307 (set_attr "mode" "QI")
17308 (set_attr "prefix_rep" "1")])
a3e991f2
ZW
17309
17310;; Peephole optimizations to clean up after cmpstr*. This should be
17311;; handled in combine, but it is not currently up to the task.
17312;; When used for their truth value, the cmpstr* expanders generate
17313;; code like this:
17314;;
17315;; repz cmpsb
17316;; seta %al
17317;; setb %dl
17318;; cmpb %al, %dl
17319;; jcc label
17320;;
17321;; The intermediate three instructions are unnecessary.
17322
17323;; This one handles cmpstr*_nz_1...
17324(define_peephole2
17325 [(parallel[
8bc527af 17326 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
17327 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17328 (mem:BLK (match_operand 5 "register_operand" ""))))
17329 (use (match_operand 6 "register_operand" ""))
17330 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af 17331 (use (reg:SI DIRFLAG_REG))
a3e991f2
ZW
17332 (clobber (match_operand 0 "register_operand" ""))
17333 (clobber (match_operand 1 "register_operand" ""))
17334 (clobber (match_operand 2 "register_operand" ""))])
17335 (set (match_operand:QI 7 "register_operand" "")
8bc527af 17336 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
a3e991f2 17337 (set (match_operand:QI 8 "register_operand" "")
8bc527af 17338 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
42fabf21 17339 (set (reg FLAGS_REG)
a3e991f2
ZW
17340 (compare (match_dup 7) (match_dup 8)))
17341 ]
244ec848 17342 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
a3e991f2 17343 [(parallel[
8bc527af 17344 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
17345 (compare:CC (mem:BLK (match_dup 4))
17346 (mem:BLK (match_dup 5))))
17347 (use (match_dup 6))
17348 (use (match_dup 3))
8bc527af 17349 (use (reg:SI DIRFLAG_REG))
a3e991f2
ZW
17350 (clobber (match_dup 0))
17351 (clobber (match_dup 1))
244ec848 17352 (clobber (match_dup 2))])]
a3e991f2
ZW
17353 "")
17354
17355;; ...and this one handles cmpstr*_1.
17356(define_peephole2
17357 [(parallel[
8bc527af 17358 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
17359 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17360 (const_int 0))
17361 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17362 (mem:BLK (match_operand 5 "register_operand" "")))
17363 (const_int 0)))
17364 (use (match_operand:SI 3 "immediate_operand" ""))
8bc527af
SB
17365 (use (reg:CC FLAGS_REG))
17366 (use (reg:SI DIRFLAG_REG))
a3e991f2
ZW
17367 (clobber (match_operand 0 "register_operand" ""))
17368 (clobber (match_operand 1 "register_operand" ""))
17369 (clobber (match_operand 2 "register_operand" ""))])
17370 (set (match_operand:QI 7 "register_operand" "")
8bc527af 17371 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
a3e991f2 17372 (set (match_operand:QI 8 "register_operand" "")
8bc527af 17373 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
42fabf21 17374 (set (reg FLAGS_REG)
a3e991f2
ZW
17375 (compare (match_dup 7) (match_dup 8)))
17376 ]
244ec848 17377 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
a3e991f2 17378 [(parallel[
8bc527af 17379 (set (reg:CC FLAGS_REG)
a3e991f2
ZW
17380 (if_then_else:CC (ne (match_dup 6)
17381 (const_int 0))
17382 (compare:CC (mem:BLK (match_dup 4))
17383 (mem:BLK (match_dup 5)))
17384 (const_int 0)))
17385 (use (match_dup 3))
8bc527af
SB
17386 (use (reg:CC FLAGS_REG))
17387 (use (reg:SI DIRFLAG_REG))
a3e991f2
ZW
17388 (clobber (match_dup 0))
17389 (clobber (match_dup 1))
244ec848 17390 (clobber (match_dup 2))])]
a3e991f2
ZW
17391 "")
17392
17393
e075ae69
RH
17394\f
17395;; Conditional move instructions.
726e2d54 17396
44cf5b6a 17397(define_expand "movdicc"
885a70fd
JH
17398 [(set (match_operand:DI 0 "register_operand" "")
17399 (if_then_else:DI (match_operand 1 "comparison_operator" "")
44cf5b6a
JH
17400 (match_operand:DI 2 "general_operand" "")
17401 (match_operand:DI 3 "general_operand" "")))]
885a70fd
JH
17402 "TARGET_64BIT"
17403 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17404
e74061a9 17405(define_insn "x86_movdicc_0_m1_rex64"
885a70fd 17406 [(set (match_operand:DI 0 "register_operand" "=r")
e6e81735 17407 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
885a70fd
JH
17408 (const_int -1)
17409 (const_int 0)))
8bc527af 17410 (clobber (reg:CC FLAGS_REG))]
885a70fd 17411 "TARGET_64BIT"
0f40f9f7 17412 "sbb{q}\t%0, %0"
885a70fd
JH
17413 ; Since we don't have the proper number of operands for an alu insn,
17414 ; fill in all the blanks.
17415 [(set_attr "type" "alu")
890d52e8 17416 (set_attr "pent_pair" "pu")
885a70fd
JH
17417 (set_attr "memory" "none")
17418 (set_attr "imm_disp" "false")
17419 (set_attr "mode" "DI")
17420 (set_attr "length_immediate" "0")])
17421
eaa49b49 17422(define_insn "*movdicc_c_rex64"
885a70fd
JH
17423 [(set (match_operand:DI 0 "register_operand" "=r,r")
17424 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
42fabf21 17425 [(reg FLAGS_REG) (const_int 0)])
885a70fd
JH
17426 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17427 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17428 "TARGET_64BIT && TARGET_CMOVE
17429 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17430 "@
048b1c95
JJ
17431 cmov%O2%C1\t{%2, %0|%0, %2}
17432 cmov%O2%c1\t{%3, %0|%0, %3}"
885a70fd
JH
17433 [(set_attr "type" "icmov")
17434 (set_attr "mode" "DI")])
17435
e075ae69 17436(define_expand "movsicc"
6a4a5d95 17437 [(set (match_operand:SI 0 "register_operand" "")
e075ae69
RH
17438 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17439 (match_operand:SI 2 "general_operand" "")
17440 (match_operand:SI 3 "general_operand" "")))]
17441 ""
17442 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
726e2d54 17443
e075ae69
RH
17444;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17445;; the register first winds up with `sbbl $0,reg', which is also weird.
17446;; So just document what we're doing explicitly.
17447
17448(define_insn "x86_movsicc_0_m1"
17449 [(set (match_operand:SI 0 "register_operand" "=r")
e6e81735 17450 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
e075ae69
RH
17451 (const_int -1)
17452 (const_int 0)))
8bc527af 17453 (clobber (reg:CC FLAGS_REG))]
e075ae69 17454 ""
0f40f9f7 17455 "sbb{l}\t%0, %0"
e075ae69
RH
17456 ; Since we don't have the proper number of operands for an alu insn,
17457 ; fill in all the blanks.
17458 [(set_attr "type" "alu")
890d52e8 17459 (set_attr "pent_pair" "pu")
e075ae69
RH
17460 (set_attr "memory" "none")
17461 (set_attr "imm_disp" "false")
6ef67412
JH
17462 (set_attr "mode" "SI")
17463 (set_attr "length_immediate" "0")])
e075ae69 17464
6343a50e 17465(define_insn "*movsicc_noc"
e075ae69 17466 [(set (match_operand:SI 0 "register_operand" "=r,r")
9076b9c1 17467 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
42fabf21 17468 [(reg FLAGS_REG) (const_int 0)])
e075ae69
RH
17469 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17470 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
d525dfdf
JH
17471 "TARGET_CMOVE
17472 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 17473 "@
048b1c95
JJ
17474 cmov%O2%C1\t{%2, %0|%0, %2}
17475 cmov%O2%c1\t{%3, %0|%0, %3}"
6ef67412
JH
17476 [(set_attr "type" "icmov")
17477 (set_attr "mode" "SI")])
726e2d54 17478
726e2d54
JW
17479(define_expand "movhicc"
17480 [(set (match_operand:HI 0 "register_operand" "")
17481 (if_then_else:HI (match_operand 1 "comparison_operator" "")
4977bab6
ZW
17482 (match_operand:HI 2 "general_operand" "")
17483 (match_operand:HI 3 "general_operand" "")))]
17484 "TARGET_HIMODE_MATH"
e075ae69 17485 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
726e2d54 17486
6343a50e 17487(define_insn "*movhicc_noc"
e075ae69 17488 [(set (match_operand:HI 0 "register_operand" "=r,r")
9076b9c1 17489 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
42fabf21 17490 [(reg FLAGS_REG) (const_int 0)])
e075ae69
RH
17491 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17492 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
d525dfdf
JH
17493 "TARGET_CMOVE
17494 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 17495 "@
048b1c95
JJ
17496 cmov%O2%C1\t{%2, %0|%0, %2}
17497 cmov%O2%c1\t{%3, %0|%0, %3}"
6ef67412
JH
17498 [(set_attr "type" "icmov")
17499 (set_attr "mode" "HI")])
726e2d54 17500
4977bab6
ZW
17501(define_expand "movqicc"
17502 [(set (match_operand:QI 0 "register_operand" "")
17503 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17504 (match_operand:QI 2 "general_operand" "")
17505 (match_operand:QI 3 "general_operand" "")))]
17506 "TARGET_QIMODE_MATH"
17507 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17508
17509(define_insn_and_split "*movqicc_noc"
17510 [(set (match_operand:QI 0 "register_operand" "=r,r")
17511 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
eaa49b49
RH
17512 [(match_operand 4 "flags_reg_operand" "")
17513 (const_int 0)])
4977bab6
ZW
17514 (match_operand:QI 2 "register_operand" "r,0")
17515 (match_operand:QI 3 "register_operand" "0,r")))]
17516 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17517 "#"
17518 "&& reload_completed"
17519 [(set (match_dup 0)
17520 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17521 (match_dup 2)
17522 (match_dup 3)))]
17523 "operands[0] = gen_lowpart (SImode, operands[0]);
17524 operands[2] = gen_lowpart (SImode, operands[2]);
17525 operands[3] = gen_lowpart (SImode, operands[3]);"
17526 [(set_attr "type" "icmov")
17527 (set_attr "mode" "SI")])
17528
56710e42 17529(define_expand "movsfcc"
726e2d54 17530 [(set (match_operand:SF 0 "register_operand" "")
56710e42 17531 (if_then_else:SF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
17532 (match_operand:SF 2 "register_operand" "")
17533 (match_operand:SF 3 "register_operand" "")))]
eaa49b49 17534 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
e075ae69 17535 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
726e2d54 17536
eaa49b49
RH
17537;; These versions of min/max are aware of the instruction's behaviour
17538;; wrt -0.0 and NaN inputs. If we don't care about either, then we
17539;; should have used the smin/smax expanders in the first place.
17540(define_insn "*movsfcc_1_sse_min"
17541 [(set (match_operand:SF 0 "register_operand" "=x")
17542 (if_then_else:SF
17543 (lt:SF (match_operand:SF 1 "register_operand" "0")
17544 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17545 (match_dup 1)
17546 (match_dup 2)))]
17547 "TARGET_SSE_MATH"
17548 "minss\t{%2, %0|%0, %2}"
17549 [(set_attr "type" "sseadd")
17550 (set_attr "mode" "SF")])
17551
17552(define_insn "*movsfcc_1_sse_max"
17553 [(set (match_operand:SF 0 "register_operand" "=x")
17554 (if_then_else:SF
17555 (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
17556 (match_operand:SF 1 "register_operand" "0"))
17557 (match_dup 1)
17558 (match_dup 2)))]
17559 "TARGET_SSE_MATH"
17560 "maxss\t{%2, %0|%0, %2}"
17561 [(set_attr "type" "sseadd")
17562 (set_attr "mode" "SF")])
17563
17564(define_insn_and_split "*movsfcc_1_sse"
17565 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
17566 (if_then_else:SF
17567 (match_operator:SF 4 "sse_comparison_operator"
17568 [(match_operand:SF 5 "register_operand" "0,0,0")
17569 (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
17570 (match_operand:SF 2 "reg_or_0_operand" "C,x,1")
17571 (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
17572 (clobber (match_scratch:V4SF 1 "=X,X,x"))]
17573 "TARGET_SSE_MATH"
17574 "#"
17575 "&& reload_completed"
17576 [(const_int 0)]
17577{
17578 ix86_split_sse_movcc (operands);
17579 DONE;
17580})
17581
17582(define_insn "*movsfcc_1_387"
f380a0ce 17583 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
e075ae69 17584 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
42fabf21 17585 [(reg FLAGS_REG) (const_int 0)])
f380a0ce
JH
17586 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17587 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
eaa49b49 17588 "TARGET_80387 && TARGET_CMOVE
7093c9ea 17589 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 17590 "@
0f40f9f7
ZW
17591 fcmov%F1\t{%2, %0|%0, %2}
17592 fcmov%f1\t{%3, %0|%0, %3}
048b1c95
JJ
17593 cmov%O2%C1\t{%2, %0|%0, %2}
17594 cmov%O2%c1\t{%3, %0|%0, %3}"
7093c9ea
JH
17595 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17596 (set_attr "mode" "SF,SF,SI,SI")])
56710e42
SC
17597
17598(define_expand "movdfcc"
726e2d54 17599 [(set (match_operand:DF 0 "register_operand" "")
56710e42 17600 (if_then_else:DF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
17601 (match_operand:DF 2 "register_operand" "")
17602 (match_operand:DF 3 "register_operand" "")))]
eaa49b49 17603 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
e075ae69 17604 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
726e2d54 17605
eaa49b49
RH
17606;; These versions of min/max are aware of the instruction's behaviour
17607;; wrt -0.0 and NaN inputs. If we don't care about either, then we
17608;; should have used the smin/smax expanders in the first place.
17609(define_insn "*movdfcc_1_sse_min"
17610 [(set (match_operand:DF 0 "register_operand" "=x")
17611 (if_then_else:DF
17612 (lt:DF (match_operand:DF 1 "register_operand" "0")
17613 (match_operand:DF 2 "nonimmediate_operand" "xm"))
17614 (match_dup 1)
17615 (match_dup 2)))]
17616 "TARGET_SSE2 && TARGET_SSE_MATH"
17617 "minsd\t{%2, %0|%0, %2}"
17618 [(set_attr "type" "sseadd")
17619 (set_attr "mode" "DF")])
17620
17621(define_insn "*movdfcc_1_sse_max"
17622 [(set (match_operand:DF 0 "register_operand" "=x")
17623 (if_then_else:DF
17624 (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
17625 (match_operand:DF 1 "register_operand" "0"))
17626 (match_dup 1)
17627 (match_dup 2)))]
17628 "TARGET_SSE2 && TARGET_SSE_MATH"
17629 "maxsd\t{%2, %0|%0, %2}"
17630 [(set_attr "type" "sseadd")
17631 (set_attr "mode" "DF")])
17632
17633(define_insn_and_split "*movdfcc_1_sse"
17634 [(set (match_operand:DF 0 "register_operand" "=x,x,x")
17635 (if_then_else:DF
17636 (match_operator:DF 4 "sse_comparison_operator"
17637 [(match_operand:DF 5 "register_operand" "0,0,0")
17638 (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
17639 (match_operand:DF 2 "reg_or_0_operand" "C,x,1")
17640 (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
17641 (clobber (match_scratch:V2DF 1 "=X,X,x"))]
17642 "TARGET_SSE2 && TARGET_SSE_MATH"
17643 "#"
17644 "&& reload_completed"
17645 [(const_int 0)]
17646{
17647 ix86_split_sse_movcc (operands);
17648 DONE;
17649})
17650
6343a50e 17651(define_insn "*movdfcc_1"
f380a0ce 17652 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
e075ae69 17653 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
42fabf21 17654 [(reg FLAGS_REG) (const_int 0)])
f380a0ce
JH
17655 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17656 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
eaa49b49 17657 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
7093c9ea 17658 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 17659 "@
0f40f9f7
ZW
17660 fcmov%F1\t{%2, %0|%0, %2}
17661 fcmov%f1\t{%3, %0|%0, %3}
7093c9ea
JH
17662 #
17663 #"
17664 [(set_attr "type" "fcmov,fcmov,multi,multi")
6ef67412 17665 (set_attr "mode" "DF")])
56710e42 17666
1e07edd3 17667(define_insn "*movdfcc_1_rex64"
cd48dadc 17668 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
1e07edd3 17669 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
42fabf21 17670 [(reg FLAGS_REG) (const_int 0)])
f380a0ce
JH
17671 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17672 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
eaa49b49 17673 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
1e07edd3
JH
17674 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17675 "@
0f40f9f7
ZW
17676 fcmov%F1\t{%2, %0|%0, %2}
17677 fcmov%f1\t{%3, %0|%0, %3}
048b1c95
JJ
17678 cmov%O2%C1\t{%2, %0|%0, %2}
17679 cmov%O2%c1\t{%3, %0|%0, %3}"
1e07edd3
JH
17680 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17681 (set_attr "mode" "DF")])
17682
7093c9ea 17683(define_split
c3c637e3 17684 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
7093c9ea 17685 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
eaa49b49
RH
17686 [(match_operand 4 "flags_reg_operand" "")
17687 (const_int 0)])
7093c9ea
JH
17688 (match_operand:DF 2 "nonimmediate_operand" "")
17689 (match_operand:DF 3 "nonimmediate_operand" "")))]
c3c637e3 17690 "!TARGET_64BIT && reload_completed"
7093c9ea
JH
17691 [(set (match_dup 2)
17692 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17693 (match_dup 5)
17694 (match_dup 7)))
17695 (set (match_dup 3)
17696 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17697 (match_dup 6)
17698 (match_dup 8)))]
17699 "split_di (operands+2, 1, operands+5, operands+6);
17700 split_di (operands+3, 1, operands+7, operands+8);
17701 split_di (operands, 1, operands+2, operands+3);")
17702
56710e42 17703(define_expand "movxfcc"
726e2d54 17704 [(set (match_operand:XF 0 "register_operand" "")
56710e42 17705 (if_then_else:XF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
17706 (match_operand:XF 2 "register_operand" "")
17707 (match_operand:XF 3 "register_operand" "")))]
eaa49b49 17708 "TARGET_80387 && TARGET_CMOVE"
2b589241
JH
17709 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17710
6343a50e 17711(define_insn "*movxfcc_1"
3aeae608 17712 [(set (match_operand:XF 0 "register_operand" "=f,f")
e075ae69 17713 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
42fabf21 17714 [(reg FLAGS_REG) (const_int 0)])
3aeae608
JW
17715 (match_operand:XF 2 "register_operand" "f,0")
17716 (match_operand:XF 3 "register_operand" "0,f")))]
eaa49b49 17717 "TARGET_80387 && TARGET_CMOVE"
2b589241 17718 "@
0f40f9f7
ZW
17719 fcmov%F1\t{%2, %0|%0, %2}
17720 fcmov%f1\t{%3, %0|%0, %3}"
2b589241
JH
17721 [(set_attr "type" "fcmov")
17722 (set_attr "mode" "XF")])
7ada6625 17723
eaa49b49
RH
17724;; These versions of the min/max patterns are intentionally ignorant of
17725;; their behaviour wrt -0.0 and NaN (via the commutative operand mark).
17726;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17727;; are undefined in this condition, we're certain this is correct.
7ada6625 17728
eaa49b49
RH
17729(define_insn "sminsf3"
17730 [(set (match_operand:SF 0 "register_operand" "=x")
17731 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17732 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17733 "TARGET_SSE_MATH"
17734 "minss\t{%2, %0|%0, %2}"
17735 [(set_attr "type" "sseadd")
17736 (set_attr "mode" "SF")])
7ada6625 17737
eaa49b49
RH
17738(define_insn "smaxsf3"
17739 [(set (match_operand:SF 0 "register_operand" "=x")
17740 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17741 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17742 "TARGET_SSE_MATH"
17743 "minss\t{%2, %0|%0, %2}"
17744 [(set_attr "type" "sseadd")
17745 (set_attr "mode" "SF")])
7ada6625 17746
eaa49b49
RH
17747(define_insn "smindf3"
17748 [(set (match_operand:DF 0 "register_operand" "=x")
17749 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17750 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17751 "TARGET_SSE2 && TARGET_SSE_MATH"
17752 "minsd\t{%2, %0|%0, %2}"
17753 [(set_attr "type" "sseadd")
17754 (set_attr "mode" "DF")])
17755
17756(define_insn "smaxdf3"
17757 [(set (match_operand:DF 0 "register_operand" "=x")
17758 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17759 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17760 "TARGET_SSE2 && TARGET_SSE_MATH"
17761 "maxsd\t{%2, %0|%0, %2}"
17762 [(set_attr "type" "sseadd")
17763 (set_attr "mode" "DF")])
7ada6625 17764
7b52eede
JH
17765;; Conditional addition patterns
17766(define_expand "addqicc"
17767 [(match_operand:QI 0 "register_operand" "")
17768 (match_operand 1 "comparison_operator" "")
17769 (match_operand:QI 2 "register_operand" "")
17770 (match_operand:QI 3 "const_int_operand" "")]
17771 ""
17772 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17773
17774(define_expand "addhicc"
17775 [(match_operand:HI 0 "register_operand" "")
17776 (match_operand 1 "comparison_operator" "")
17777 (match_operand:HI 2 "register_operand" "")
17778 (match_operand:HI 3 "const_int_operand" "")]
17779 ""
17780 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17781
17782(define_expand "addsicc"
17783 [(match_operand:SI 0 "register_operand" "")
17784 (match_operand 1 "comparison_operator" "")
17785 (match_operand:SI 2 "register_operand" "")
17786 (match_operand:SI 3 "const_int_operand" "")]
17787 ""
17788 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17789
17790(define_expand "adddicc"
17791 [(match_operand:DI 0 "register_operand" "")
17792 (match_operand 1 "comparison_operator" "")
17793 (match_operand:DI 2 "register_operand" "")
17794 (match_operand:DI 3 "const_int_operand" "")]
17795 "TARGET_64BIT"
17796 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17797
e075ae69
RH
17798\f
17799;; Misc patterns (?)
726e2d54 17800
f5143c46 17801;; This pattern exists to put a dependency on all ebp-based memory accesses.
e075ae69
RH
17802;; Otherwise there will be nothing to keep
17803;;
17804;; [(set (reg ebp) (reg esp))]
17805;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17806;; (clobber (eflags)]
17807;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17808;;
17809;; in proper program order.
b19ee4bd 17810(define_insn "pro_epilogue_adjust_stack_1"
1c71e60e
JH
17811 [(set (match_operand:SI 0 "register_operand" "=r,r")
17812 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17813 (match_operand:SI 2 "immediate_operand" "i,i")))
8bc527af 17814 (clobber (reg:CC FLAGS_REG))
f2042df3 17815 (clobber (mem:BLK (scratch)))]
8362f420 17816 "!TARGET_64BIT"
e075ae69 17817{
1c71e60e 17818 switch (get_attr_type (insn))
e075ae69 17819 {
1c71e60e 17820 case TYPE_IMOV:
0f40f9f7 17821 return "mov{l}\t{%1, %0|%0, %1}";
1c71e60e
JH
17822
17823 case TYPE_ALU:
17824 if (GET_CODE (operands[2]) == CONST_INT
17825 && (INTVAL (operands[2]) == 128
17826 || (INTVAL (operands[2]) < 0
17827 && INTVAL (operands[2]) != -128)))
17828 {
17829 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 17830 return "sub{l}\t{%2, %0|%0, %2}";
1c71e60e 17831 }
0f40f9f7 17832 return "add{l}\t{%2, %0|%0, %2}";
1c71e60e
JH
17833
17834 case TYPE_LEA:
17835 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 17836 return "lea{l}\t{%a2, %0|%0, %a2}";
1c71e60e
JH
17837
17838 default:
17839 abort ();
e075ae69 17840 }
0f40f9f7 17841}
1c71e60e
JH
17842 [(set (attr "type")
17843 (cond [(eq_attr "alternative" "0")
17844 (const_string "alu")
17845 (match_operand:SI 2 "const0_operand" "")
17846 (const_string "imov")
17847 ]
6ef67412
JH
17848 (const_string "lea")))
17849 (set_attr "mode" "SI")])
578b58f5 17850
8362f420
JH
17851(define_insn "pro_epilogue_adjust_stack_rex64"
17852 [(set (match_operand:DI 0 "register_operand" "=r,r")
17853 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17854 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
8bc527af 17855 (clobber (reg:CC FLAGS_REG))
f2042df3 17856 (clobber (mem:BLK (scratch)))]
8362f420 17857 "TARGET_64BIT"
8362f420
JH
17858{
17859 switch (get_attr_type (insn))
17860 {
17861 case TYPE_IMOV:
0f40f9f7 17862 return "mov{q}\t{%1, %0|%0, %1}";
8362f420
JH
17863
17864 case TYPE_ALU:
17865 if (GET_CODE (operands[2]) == CONST_INT
b19ee4bd
JJ
17866 /* Avoid overflows. */
17867 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
8362f420
JH
17868 && (INTVAL (operands[2]) == 128
17869 || (INTVAL (operands[2]) < 0
17870 && INTVAL (operands[2]) != -128)))
17871 {
17872 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 17873 return "sub{q}\t{%2, %0|%0, %2}";
8362f420 17874 }
0f40f9f7 17875 return "add{q}\t{%2, %0|%0, %2}";
8362f420
JH
17876
17877 case TYPE_LEA:
17878 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 17879 return "lea{q}\t{%a2, %0|%0, %a2}";
8362f420
JH
17880
17881 default:
17882 abort ();
17883 }
0f40f9f7 17884}
8362f420
JH
17885 [(set (attr "type")
17886 (cond [(eq_attr "alternative" "0")
17887 (const_string "alu")
17888 (match_operand:DI 2 "const0_operand" "")
17889 (const_string "imov")
17890 ]
17891 (const_string "lea")))
17892 (set_attr "mode" "DI")])
17893
b19ee4bd
JJ
17894(define_insn "pro_epilogue_adjust_stack_rex64_2"
17895 [(set (match_operand:DI 0 "register_operand" "=r,r")
17896 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17897 (match_operand:DI 3 "immediate_operand" "i,i")))
17898 (use (match_operand:DI 2 "register_operand" "r,r"))
8bc527af 17899 (clobber (reg:CC FLAGS_REG))
b19ee4bd
JJ
17900 (clobber (mem:BLK (scratch)))]
17901 "TARGET_64BIT"
17902{
17903 switch (get_attr_type (insn))
17904 {
17905 case TYPE_ALU:
17906 return "add{q}\t{%2, %0|%0, %2}";
17907
17908 case TYPE_LEA:
17909 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17910 return "lea{q}\t{%a2, %0|%0, %a2}";
17911
17912 default:
17913 abort ();
17914 }
17915}
17916 [(set_attr "type" "alu,lea")
17917 (set_attr "mode" "DI")])
8362f420 17918
885a70fd
JH
17919(define_expand "allocate_stack_worker"
17920 [(match_operand:SI 0 "register_operand" "")]
17921 "TARGET_STACK_PROBE"
885a70fd 17922{
af9fb8ab
JH
17923 if (reload_completed)
17924 {
17925 if (TARGET_64BIT)
17926 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17927 else
17928 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17929 }
885a70fd 17930 else
af9fb8ab
JH
17931 {
17932 if (TARGET_64BIT)
17933 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17934 else
17935 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17936 }
885a70fd 17937 DONE;
0f40f9f7 17938})
885a70fd
JH
17939
17940(define_insn "allocate_stack_worker_1"
8e2cd6dd
KC
17941 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17942 UNSPECV_STACK_PROBE)
8bc527af 17943 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
af9fb8ab 17944 (clobber (match_scratch:SI 1 "=0"))
8bc527af 17945 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 17946 "!TARGET_64BIT && TARGET_STACK_PROBE"
0f40f9f7 17947 "call\t__alloca"
885a70fd
JH
17948 [(set_attr "type" "multi")
17949 (set_attr "length" "5")])
17950
af9fb8ab 17951(define_expand "allocate_stack_worker_postreload"
8e2cd6dd
KC
17952 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17953 UNSPECV_STACK_PROBE)
8bc527af 17954 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
af9fb8ab 17955 (clobber (match_dup 0))
8bc527af 17956 (clobber (reg:CC FLAGS_REG))])]
af9fb8ab
JH
17957 ""
17958 "")
17959
885a70fd 17960(define_insn "allocate_stack_worker_rex64"
8e2cd6dd
KC
17961 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17962 UNSPECV_STACK_PROBE)
8bc527af 17963 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
af9fb8ab 17964 (clobber (match_scratch:DI 1 "=0"))
8bc527af 17965 (clobber (reg:CC FLAGS_REG))]
1b0c37d7 17966 "TARGET_64BIT && TARGET_STACK_PROBE"
0f40f9f7 17967 "call\t__alloca"
e075ae69
RH
17968 [(set_attr "type" "multi")
17969 (set_attr "length" "5")])
578b58f5 17970
af9fb8ab 17971(define_expand "allocate_stack_worker_rex64_postreload"
8e2cd6dd
KC
17972 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17973 UNSPECV_STACK_PROBE)
8bc527af 17974 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
af9fb8ab 17975 (clobber (match_dup 0))
8bc527af 17976 (clobber (reg:CC FLAGS_REG))])]
af9fb8ab
JH
17977 ""
17978 "")
17979
578b58f5 17980(define_expand "allocate_stack"
e075ae69 17981 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
8bc527af 17982 (minus:SI (reg:SI SP_REG)
e075ae69 17983 (match_operand:SI 1 "general_operand" "")))
8bc527af
SB
17984 (clobber (reg:CC FLAGS_REG))])
17985 (parallel [(set (reg:SI SP_REG)
17986 (minus:SI (reg:SI SP_REG) (match_dup 1)))
17987 (clobber (reg:CC FLAGS_REG))])]
e075ae69 17988 "TARGET_STACK_PROBE"
578b58f5
RK
17989{
17990#ifdef CHECK_STACK_LIMIT
e9a25f70
JL
17991 if (GET_CODE (operands[1]) == CONST_INT
17992 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
578b58f5 17993 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
e9a25f70 17994 operands[1]));
578b58f5
RK
17995 else
17996#endif
17997 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
e9a25f70 17998 operands[1])));
578b58f5 17999
e9a25f70
JL
18000 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18001 DONE;
0f40f9f7 18002})
e31ca113 18003
fb754025
AG
18004(define_expand "builtin_setjmp_receiver"
18005 [(label_ref (match_operand 0 "" ""))]
1b0c37d7 18006 "!TARGET_64BIT && flag_pic"
fb754025 18007{
c8c03509 18008 emit_insn (gen_set_got (pic_offset_table_rtx));
fb754025 18009 DONE;
0f40f9f7 18010})
e9e80858
JH
18011\f
18012;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18013
18014(define_split
18015 [(set (match_operand 0 "register_operand" "")
18016 (match_operator 3 "promotable_binary_operator"
18017 [(match_operand 1 "register_operand" "")
2247f6ed 18018 (match_operand 2 "aligned_operand" "")]))
8bc527af 18019 (clobber (reg:CC FLAGS_REG))]
e9e80858
JH
18020 "! TARGET_PARTIAL_REG_STALL && reload_completed
18021 && ((GET_MODE (operands[0]) == HImode
285464d0
JH
18022 && ((!optimize_size && !TARGET_FAST_PREFIX)
18023 || GET_CODE (operands[2]) != CONST_INT
e9e80858
JH
18024 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18025 || (GET_MODE (operands[0]) == QImode
18026 && (TARGET_PROMOTE_QImode || optimize_size)))"
18027 [(parallel [(set (match_dup 0)
18028 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8bc527af 18029 (clobber (reg:CC FLAGS_REG))])]
e9e80858
JH
18030 "operands[0] = gen_lowpart (SImode, operands[0]);
18031 operands[1] = gen_lowpart (SImode, operands[1]);
18032 if (GET_CODE (operands[3]) != ASHIFT)
18033 operands[2] = gen_lowpart (SImode, operands[2]);
dbbbbf3b 18034 PUT_MODE (operands[3], SImode);")
e9e80858 18035
d2fc7725
EB
18036; Promote the QImode tests, as i386 has encoding of the AND
18037; instruction with 32-bit sign-extended immediate and thus the
18038; instruction size is unchanged, except in the %eax case for
18039; which it is increased by one byte, hence the ! optimize_size.
e9e80858 18040(define_split
25da5dc7
RH
18041 [(set (match_operand 0 "flags_reg_operand" "")
18042 (match_operator 2 "compare_operator"
18043 [(and (match_operand 3 "aligned_operand" "")
18044 (match_operand 4 "const_int_operand" ""))
18045 (const_int 0)]))
18046 (set (match_operand 1 "register_operand" "")
18047 (and (match_dup 3) (match_dup 4)))]
e9e80858 18048 "! TARGET_PARTIAL_REG_STALL && reload_completed
d2fc7725 18049 /* Ensure that the operand will remain sign-extended immediate. */
25da5dc7 18050 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
d2fc7725 18051 && ! optimize_size
25da5dc7
RH
18052 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18053 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18054 [(parallel [(set (match_dup 0)
18055 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18056 (const_int 0)]))
18057 (set (match_dup 1)
18058 (and:SI (match_dup 3) (match_dup 4)))])]
18059{
18060 operands[4]
18061 = gen_int_mode (INTVAL (operands[4])
18062 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18063 operands[1] = gen_lowpart (SImode, operands[1]);
18064 operands[3] = gen_lowpart (SImode, operands[3]);
18065})
e9e80858 18066
d2fc7725
EB
18067; Don't promote the QImode tests, as i386 doesn't have encoding of
18068; the TEST instruction with 32-bit sign-extended immediate and thus
18069; the instruction size would at least double, which is not what we
18070; want even with ! optimize_size.
e9e80858 18071(define_split
25da5dc7
RH
18072 [(set (match_operand 0 "flags_reg_operand" "")
18073 (match_operator 1 "compare_operator"
18074 [(and (match_operand:HI 2 "aligned_operand" "")
18075 (match_operand:HI 3 "const_int_operand" ""))
18076 (const_int 0)]))]
e9e80858 18077 "! TARGET_PARTIAL_REG_STALL && reload_completed
d2fc7725 18078 /* Ensure that the operand will remain sign-extended immediate. */
25da5dc7 18079 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
d2fc7725
EB
18080 && ! TARGET_FAST_PREFIX
18081 && ! optimize_size"
25da5dc7
RH
18082 [(set (match_dup 0)
18083 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18084 (const_int 0)]))]
18085{
18086 operands[3]
18087 = gen_int_mode (INTVAL (operands[3])
18088 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18089 operands[2] = gen_lowpart (SImode, operands[2]);
18090})
e9e80858
JH
18091
18092(define_split
18093 [(set (match_operand 0 "register_operand" "")
18094 (neg (match_operand 1 "register_operand" "")))
8bc527af 18095 (clobber (reg:CC FLAGS_REG))]
e9e80858
JH
18096 "! TARGET_PARTIAL_REG_STALL && reload_completed
18097 && (GET_MODE (operands[0]) == HImode
18098 || (GET_MODE (operands[0]) == QImode
18099 && (TARGET_PROMOTE_QImode || optimize_size)))"
18100 [(parallel [(set (match_dup 0)
18101 (neg:SI (match_dup 1)))
8bc527af 18102 (clobber (reg:CC FLAGS_REG))])]
e9e80858
JH
18103 "operands[0] = gen_lowpart (SImode, operands[0]);
18104 operands[1] = gen_lowpart (SImode, operands[1]);")
18105
18106(define_split
18107 [(set (match_operand 0 "register_operand" "")
18108 (not (match_operand 1 "register_operand" "")))]
18109 "! TARGET_PARTIAL_REG_STALL && reload_completed
18110 && (GET_MODE (operands[0]) == HImode
18111 || (GET_MODE (operands[0]) == QImode
18112 && (TARGET_PROMOTE_QImode || optimize_size)))"
18113 [(set (match_dup 0)
18114 (not:SI (match_dup 1)))]
18115 "operands[0] = gen_lowpart (SImode, operands[0]);
18116 operands[1] = gen_lowpart (SImode, operands[1]);")
18117
18118(define_split
18119 [(set (match_operand 0 "register_operand" "")
18120 (if_then_else (match_operator 1 "comparison_operator"
42fabf21 18121 [(reg FLAGS_REG) (const_int 0)])
e9e80858
JH
18122 (match_operand 2 "register_operand" "")
18123 (match_operand 3 "register_operand" "")))]
18124 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18125 && (GET_MODE (operands[0]) == HImode
18126 || (GET_MODE (operands[0]) == QImode
18127 && (TARGET_PROMOTE_QImode || optimize_size)))"
18128 [(set (match_dup 0)
18129 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18130 "operands[0] = gen_lowpart (SImode, operands[0]);
18131 operands[2] = gen_lowpart (SImode, operands[2]);
18132 operands[3] = gen_lowpart (SImode, operands[3]);")
18133
e075ae69
RH
18134\f
18135;; RTL Peephole optimizations, run before sched2. These primarily look to
18136;; transform a complex memory operation into two memory to register operations.
18137
18138;; Don't push memory operands
18139(define_peephole2
3071fab5
RH
18140 [(set (match_operand:SI 0 "push_operand" "")
18141 (match_operand:SI 1 "memory_operand" ""))
18142 (match_scratch:SI 2 "r")]
e075ae69
RH
18143 "! optimize_size && ! TARGET_PUSH_MEMORY"
18144 [(set (match_dup 2) (match_dup 1))
18145 (set (match_dup 0) (match_dup 2))]
18146 "")
18147
cc2e591b
JH
18148(define_peephole2
18149 [(set (match_operand:DI 0 "push_operand" "")
18150 (match_operand:DI 1 "memory_operand" ""))
18151 (match_scratch:DI 2 "r")]
18152 "! optimize_size && ! TARGET_PUSH_MEMORY"
18153 [(set (match_dup 2) (match_dup 1))
18154 (set (match_dup 0) (match_dup 2))]
18155 "")
18156
e9e80858
JH
18157;; We need to handle SFmode only, because DFmode and XFmode is split to
18158;; SImode pushes.
18159(define_peephole2
18160 [(set (match_operand:SF 0 "push_operand" "")
18161 (match_operand:SF 1 "memory_operand" ""))
18162 (match_scratch:SF 2 "r")]
18163 "! optimize_size && ! TARGET_PUSH_MEMORY"
18164 [(set (match_dup 2) (match_dup 1))
18165 (set (match_dup 0) (match_dup 2))]
18166 "")
18167
e075ae69 18168(define_peephole2
3071fab5
RH
18169 [(set (match_operand:HI 0 "push_operand" "")
18170 (match_operand:HI 1 "memory_operand" ""))
18171 (match_scratch:HI 2 "r")]
e075ae69
RH
18172 "! optimize_size && ! TARGET_PUSH_MEMORY"
18173 [(set (match_dup 2) (match_dup 1))
18174 (set (match_dup 0) (match_dup 2))]
18175 "")
18176
18177(define_peephole2
3071fab5
RH
18178 [(set (match_operand:QI 0 "push_operand" "")
18179 (match_operand:QI 1 "memory_operand" ""))
18180 (match_scratch:QI 2 "q")]
e075ae69
RH
18181 "! optimize_size && ! TARGET_PUSH_MEMORY"
18182 [(set (match_dup 2) (match_dup 1))
18183 (set (match_dup 0) (match_dup 2))]
18184 "")
18185
18186;; Don't move an immediate directly to memory when the instruction
18187;; gets too big.
18188(define_peephole2
18189 [(match_scratch:SI 1 "r")
18190 (set (match_operand:SI 0 "memory_operand" "")
18191 (const_int 0))]
23280139 18192 "! optimize_size
591702de 18193 && ! TARGET_USE_MOV0
23280139
RH
18194 && TARGET_SPLIT_LONG_MOVES
18195 && get_attr_length (insn) >= ix86_cost->large_insn
18196 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69 18197 [(parallel [(set (match_dup 1) (const_int 0))
8bc527af 18198 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
18199 (set (match_dup 0) (match_dup 1))]
18200 "")
18201
18202(define_peephole2
18203 [(match_scratch:HI 1 "r")
18204 (set (match_operand:HI 0 "memory_operand" "")
18205 (const_int 0))]
23280139 18206 "! optimize_size
591702de 18207 && ! TARGET_USE_MOV0
23280139
RH
18208 && TARGET_SPLIT_LONG_MOVES
18209 && get_attr_length (insn) >= ix86_cost->large_insn
18210 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 18211 [(parallel [(set (match_dup 2) (const_int 0))
8bc527af 18212 (clobber (reg:CC FLAGS_REG))])
e075ae69 18213 (set (match_dup 0) (match_dup 1))]
1e2115dc 18214 "operands[2] = gen_lowpart (SImode, operands[1]);")
e075ae69
RH
18215
18216(define_peephole2
18217 [(match_scratch:QI 1 "q")
18218 (set (match_operand:QI 0 "memory_operand" "")
18219 (const_int 0))]
23280139 18220 "! optimize_size
591702de 18221 && ! TARGET_USE_MOV0
23280139
RH
18222 && TARGET_SPLIT_LONG_MOVES
18223 && get_attr_length (insn) >= ix86_cost->large_insn
18224 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 18225 [(parallel [(set (match_dup 2) (const_int 0))
8bc527af 18226 (clobber (reg:CC FLAGS_REG))])
e075ae69 18227 (set (match_dup 0) (match_dup 1))]
1e2115dc 18228 "operands[2] = gen_lowpart (SImode, operands[1]);")
e075ae69
RH
18229
18230(define_peephole2
18231 [(match_scratch:SI 2 "r")
18232 (set (match_operand:SI 0 "memory_operand" "")
18233 (match_operand:SI 1 "immediate_operand" ""))]
23280139
RH
18234 "! optimize_size
18235 && get_attr_length (insn) >= ix86_cost->large_insn
18236 && TARGET_SPLIT_LONG_MOVES"
e075ae69
RH
18237 [(set (match_dup 2) (match_dup 1))
18238 (set (match_dup 0) (match_dup 2))]
18239 "")
18240
18241(define_peephole2
18242 [(match_scratch:HI 2 "r")
18243 (set (match_operand:HI 0 "memory_operand" "")
18244 (match_operand:HI 1 "immediate_operand" ""))]
18245 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18246 && TARGET_SPLIT_LONG_MOVES"
18247 [(set (match_dup 2) (match_dup 1))
18248 (set (match_dup 0) (match_dup 2))]
18249 "")
18250
18251(define_peephole2
18252 [(match_scratch:QI 2 "q")
18253 (set (match_operand:QI 0 "memory_operand" "")
18254 (match_operand:QI 1 "immediate_operand" ""))]
18255 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18256 && TARGET_SPLIT_LONG_MOVES"
18257 [(set (match_dup 2) (match_dup 1))
18258 (set (match_dup 0) (match_dup 2))]
18259 "")
18260
18261;; Don't compare memory with zero, load and use a test instead.
18262(define_peephole2
25da5dc7
RH
18263 [(set (match_operand 0 "flags_reg_operand" "")
18264 (match_operator 1 "compare_operator"
18265 [(match_operand:SI 2 "memory_operand" "")
18266 (const_int 0)]))
3071fab5 18267 (match_scratch:SI 3 "r")]
16189740 18268 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
25da5dc7
RH
18269 [(set (match_dup 3) (match_dup 2))
18270 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
e075ae69
RH
18271 "")
18272
18273;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18274;; Don't split NOTs with a displacement operand, because resulting XOR
d1f87653 18275;; will not be pairable anyway.
e075ae69 18276;;
1e5f1716 18277;; On AMD K6, NOT is vector decoded with memory operand that cannot be
e075ae69
RH
18278;; represented using a modRM byte. The XOR replacement is long decoded,
18279;; so this split helps here as well.
18280;;
23280139
RH
18281;; Note: Can't do this as a regular split because we can't get proper
18282;; lifetime information then.
e075ae69
RH
18283
18284(define_peephole2
d5d6a58b
RH
18285 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18286 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
e075ae69 18287 "!optimize_size
23280139 18288 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
18289 && ((TARGET_PENTIUM
18290 && (GET_CODE (operands[0]) != MEM
18291 || !memory_displacement_operand (operands[0], SImode)))
18292 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18293 [(parallel [(set (match_dup 0)
18294 (xor:SI (match_dup 1) (const_int -1)))
8bc527af 18295 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18296 "")
18297
18298(define_peephole2
d5d6a58b
RH
18299 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18300 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
e075ae69 18301 "!optimize_size
23280139 18302 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
18303 && ((TARGET_PENTIUM
18304 && (GET_CODE (operands[0]) != MEM
18305 || !memory_displacement_operand (operands[0], HImode)))
18306 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18307 [(parallel [(set (match_dup 0)
18308 (xor:HI (match_dup 1) (const_int -1)))
8bc527af 18309 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18310 "")
18311
18312(define_peephole2
d5d6a58b
RH
18313 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18314 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
e075ae69 18315 "!optimize_size
23280139 18316 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
18317 && ((TARGET_PENTIUM
18318 && (GET_CODE (operands[0]) != MEM
18319 || !memory_displacement_operand (operands[0], QImode)))
18320 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18321 [(parallel [(set (match_dup 0)
18322 (xor:QI (match_dup 1) (const_int -1)))
8bc527af 18323 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18324 "")
18325
18326;; Non pairable "test imm, reg" instructions can be translated to
18327;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18328;; byte opcode instead of two, have a short form for byte operands),
18329;; so do it for other CPUs as well. Given that the value was dead,
f5143c46 18330;; this should not create any new dependencies. Pass on the sub-word
e075ae69
RH
18331;; versions if we're concerned about partial register stalls.
18332
18333(define_peephole2
25da5dc7
RH
18334 [(set (match_operand 0 "flags_reg_operand" "")
18335 (match_operator 1 "compare_operator"
18336 [(and:SI (match_operand:SI 2 "register_operand" "")
18337 (match_operand:SI 3 "immediate_operand" ""))
18338 (const_int 0)]))]
16189740 18339 "ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
18340 && (true_regnum (operands[2]) != 0
18341 || (GET_CODE (operands[3]) == CONST_INT
18342 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18343 && peep2_reg_dead_p (1, operands[2])"
e075ae69 18344 [(parallel
25da5dc7
RH
18345 [(set (match_dup 0)
18346 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18347 (const_int 0)]))
18348 (set (match_dup 2)
18349 (and:SI (match_dup 2) (match_dup 3)))])]
e075ae69
RH
18350 "")
18351
e9e80858
JH
18352;; We don't need to handle HImode case, because it will be promoted to SImode
18353;; on ! TARGET_PARTIAL_REG_STALL
e075ae69
RH
18354
18355(define_peephole2
25da5dc7
RH
18356 [(set (match_operand 0 "flags_reg_operand" "")
18357 (match_operator 1 "compare_operator"
18358 [(and:QI (match_operand:QI 2 "register_operand" "")
18359 (match_operand:QI 3 "immediate_operand" ""))
18360 (const_int 0)]))]
e075ae69 18361 "! TARGET_PARTIAL_REG_STALL
16189740 18362 && ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
18363 && true_regnum (operands[2]) != 0
18364 && peep2_reg_dead_p (1, operands[2])"
e075ae69 18365 [(parallel
25da5dc7
RH
18366 [(set (match_dup 0)
18367 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18368 (const_int 0)]))
18369 (set (match_dup 2)
18370 (and:QI (match_dup 2) (match_dup 3)))])]
e075ae69
RH
18371 "")
18372
18373(define_peephole2
25da5dc7
RH
18374 [(set (match_operand 0 "flags_reg_operand" "")
18375 (match_operator 1 "compare_operator"
18376 [(and:SI
18377 (zero_extract:SI
18378 (match_operand 2 "ext_register_operand" "")
18379 (const_int 8)
18380 (const_int 8))
18381 (match_operand 3 "const_int_operand" ""))
18382 (const_int 0)]))]
e075ae69 18383 "! TARGET_PARTIAL_REG_STALL
16189740 18384 && ix86_match_ccmode (insn, CCNOmode)
25da5dc7
RH
18385 && true_regnum (operands[2]) != 0
18386 && peep2_reg_dead_p (1, operands[2])"
18387 [(parallel [(set (match_dup 0)
18388 (match_op_dup 1
18389 [(and:SI
18390 (zero_extract:SI
18391 (match_dup 2)
18392 (const_int 8)
18393 (const_int 8))
18394 (match_dup 3))
18395 (const_int 0)]))
18396 (set (zero_extract:SI (match_dup 2)
e075ae69
RH
18397 (const_int 8)
18398 (const_int 8))
18399 (and:SI
18400 (zero_extract:SI
25da5dc7 18401 (match_dup 2)
e075ae69
RH
18402 (const_int 8)
18403 (const_int 8))
25da5dc7 18404 (match_dup 3)))])]
e075ae69
RH
18405 "")
18406
18407;; Don't do logical operations with memory inputs.
18408(define_peephole2
18409 [(match_scratch:SI 2 "r")
18410 (parallel [(set (match_operand:SI 0 "register_operand" "")
18411 (match_operator:SI 3 "arith_or_logical_operator"
18412 [(match_dup 0)
18413 (match_operand:SI 1 "memory_operand" "")]))
8bc527af 18414 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18415 "! optimize_size && ! TARGET_READ_MODIFY"
18416 [(set (match_dup 2) (match_dup 1))
18417 (parallel [(set (match_dup 0)
18418 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
8bc527af 18419 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18420 "")
18421
18422(define_peephole2
18423 [(match_scratch:SI 2 "r")
18424 (parallel [(set (match_operand:SI 0 "register_operand" "")
18425 (match_operator:SI 3 "arith_or_logical_operator"
18426 [(match_operand:SI 1 "memory_operand" "")
18427 (match_dup 0)]))
8bc527af 18428 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18429 "! optimize_size && ! TARGET_READ_MODIFY"
18430 [(set (match_dup 2) (match_dup 1))
18431 (parallel [(set (match_dup 0)
18432 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
8bc527af 18433 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18434 "")
18435
18436; Don't do logical operations with memory outputs
18437;
18438; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18439; instruction into two 1-uop insns plus a 2-uop insn. That last has
18440; the same decoder scheduling characteristics as the original.
18441
18442(define_peephole2
18443 [(match_scratch:SI 2 "r")
18444 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18445 (match_operator:SI 3 "arith_or_logical_operator"
18446 [(match_dup 0)
18447 (match_operand:SI 1 "nonmemory_operand" "")]))
8bc527af 18448 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18449 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18450 [(set (match_dup 2) (match_dup 0))
18451 (parallel [(set (match_dup 2)
18452 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
8bc527af 18453 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
18454 (set (match_dup 0) (match_dup 2))]
18455 "")
18456
18457(define_peephole2
18458 [(match_scratch:SI 2 "r")
18459 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18460 (match_operator:SI 3 "arith_or_logical_operator"
18461 [(match_operand:SI 1 "nonmemory_operand" "")
18462 (match_dup 0)]))
8bc527af 18463 (clobber (reg:CC FLAGS_REG))])]
e075ae69
RH
18464 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18465 [(set (match_dup 2) (match_dup 0))
18466 (parallel [(set (match_dup 2)
18467 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8bc527af 18468 (clobber (reg:CC FLAGS_REG))])
e075ae69
RH
18469 (set (match_dup 0) (match_dup 2))]
18470 "")
18471
18472;; Attempt to always use XOR for zeroing registers.
18473(define_peephole2
18474 [(set (match_operand 0 "register_operand" "")
18475 (const_int 0))]
18476 "(GET_MODE (operands[0]) == QImode
18477 || GET_MODE (operands[0]) == HImode
cc2e591b
JH
18478 || GET_MODE (operands[0]) == SImode
18479 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
e075ae69 18480 && (! TARGET_USE_MOV0 || optimize_size)
23280139 18481 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69 18482 [(parallel [(set (match_dup 0) (const_int 0))
8bc527af 18483 (clobber (reg:CC FLAGS_REG))])]
1e2115dc
JZ
18484 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18485 operands[0]);")
d3a923ee 18486
6ef67412
JH
18487(define_peephole2
18488 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18489 (const_int 0))]
18490 "(GET_MODE (operands[0]) == QImode
18491 || GET_MODE (operands[0]) == HImode)
18492 && (! TARGET_USE_MOV0 || optimize_size)
18493 && peep2_regno_dead_p (0, FLAGS_REG)"
18494 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
8bc527af 18495 (clobber (reg:CC FLAGS_REG))])])
6ef67412 18496
e075ae69
RH
18497;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18498(define_peephole2
591702de 18499 [(set (match_operand 0 "register_operand" "")
e075ae69 18500 (const_int -1))]
591702de 18501 "(GET_MODE (operands[0]) == HImode
cc2e591b
JH
18502 || GET_MODE (operands[0]) == SImode
18503 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
591702de 18504 && (optimize_size || TARGET_PENTIUM)
23280139 18505 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 18506 [(parallel [(set (match_dup 0) (const_int -1))
8bc527af 18507 (clobber (reg:CC FLAGS_REG))])]
1e2115dc
JZ
18508 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18509 operands[0]);")
1c27d4b2
JH
18510
18511;; Attempt to convert simple leas to adds. These can be created by
18512;; move expanders.
18513(define_peephole2
18514 [(set (match_operand:SI 0 "register_operand" "")
18515 (plus:SI (match_dup 0)
18516 (match_operand:SI 1 "nonmemory_operand" "")))]
23280139 18517 "peep2_regno_dead_p (0, FLAGS_REG)"
1c27d4b2 18518 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
8bc527af 18519 (clobber (reg:CC FLAGS_REG))])]
1c27d4b2
JH
18520 "")
18521
cc2e591b
JH
18522(define_peephole2
18523 [(set (match_operand:SI 0 "register_operand" "")
18524 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18525 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18526 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18527 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
8bc527af 18528 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
18529 "operands[2] = gen_lowpart (SImode, operands[2]);")
18530
18531(define_peephole2
18532 [(set (match_operand:DI 0 "register_operand" "")
18533 (plus:DI (match_dup 0)
18534 (match_operand:DI 1 "x86_64_general_operand" "")))]
18535 "peep2_regno_dead_p (0, FLAGS_REG)"
18536 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
8bc527af 18537 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
18538 "")
18539
1c27d4b2
JH
18540(define_peephole2
18541 [(set (match_operand:SI 0 "register_operand" "")
18542 (mult:SI (match_dup 0)
cc2e591b 18543 (match_operand:SI 1 "const_int_operand" "")))]
23280139
RH
18544 "exact_log2 (INTVAL (operands[1])) >= 0
18545 && peep2_regno_dead_p (0, FLAGS_REG)"
1c27d4b2 18546 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
8bc527af 18547 (clobber (reg:CC FLAGS_REG))])]
1c27d4b2 18548 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
bdeb029c 18549
cc2e591b
JH
18550(define_peephole2
18551 [(set (match_operand:DI 0 "register_operand" "")
18552 (mult:DI (match_dup 0)
18553 (match_operand:DI 1 "const_int_operand" "")))]
18554 "exact_log2 (INTVAL (operands[1])) >= 0
18555 && peep2_regno_dead_p (0, FLAGS_REG)"
18556 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
8bc527af 18557 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
18558 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18559
18560(define_peephole2
18561 [(set (match_operand:SI 0 "register_operand" "")
18562 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18563 (match_operand:DI 2 "const_int_operand" "")) 0))]
4c9c9a3d 18564 "exact_log2 (INTVAL (operands[2])) >= 0
cc2e591b
JH
18565 && REGNO (operands[0]) == REGNO (operands[1])
18566 && peep2_regno_dead_p (0, FLAGS_REG)"
18567 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
8bc527af 18568 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
18569 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18570
bdeb029c
JH
18571;; The ESP adjustments can be done by the push and pop instructions. Resulting
18572;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18573;; many CPUs it is also faster, since special hardware to avoid esp
f5143c46 18574;; dependencies is present.
bdeb029c 18575
d6a7951f 18576;; While some of these conversions may be done using splitters, we use peepholes
bdeb029c
JH
18577;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18578
f5143c46 18579;; Convert prologue esp subtractions to push.
bdeb029c
JH
18580;; We need register to push. In order to keep verify_flow_info happy we have
18581;; two choices
18582;; - use scratch and clobber it in order to avoid dependencies
18583;; - use already live register
18584;; We can't use the second way right now, since there is no reliable way how to
18585;; verify that given register is live. First choice will also most likely in
18586;; fewer dependencies. On the place of esp adjustments it is very likely that
18587;; call clobbered registers are dead. We may want to use base pointer as an
18588;; alternative when no register is available later.
18589
18590(define_peephole2
18591 [(match_scratch:SI 0 "r")
8bc527af
SB
18592 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18593 (clobber (reg:CC FLAGS_REG))
f2042df3 18594 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
18595 "optimize_size || !TARGET_SUB_ESP_4"
18596 [(clobber (match_dup 0))
8bc527af 18597 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
f2042df3 18598 (clobber (mem:BLK (scratch)))])])
bdeb029c
JH
18599
18600(define_peephole2
18601 [(match_scratch:SI 0 "r")
8bc527af
SB
18602 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18603 (clobber (reg:CC FLAGS_REG))
f2042df3 18604 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
18605 "optimize_size || !TARGET_SUB_ESP_8"
18606 [(clobber (match_dup 0))
8bc527af
SB
18607 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18608 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
f2042df3 18609 (clobber (mem:BLK (scratch)))])])
bdeb029c 18610
f5143c46 18611;; Convert esp subtractions to push.
bdeb029c
JH
18612(define_peephole2
18613 [(match_scratch:SI 0 "r")
8bc527af
SB
18614 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18615 (clobber (reg:CC FLAGS_REG))])]
bdeb029c
JH
18616 "optimize_size || !TARGET_SUB_ESP_4"
18617 [(clobber (match_dup 0))
8bc527af 18618 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
bdeb029c
JH
18619
18620(define_peephole2
18621 [(match_scratch:SI 0 "r")
8bc527af
SB
18622 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18623 (clobber (reg:CC FLAGS_REG))])]
bdeb029c
JH
18624 "optimize_size || !TARGET_SUB_ESP_8"
18625 [(clobber (match_dup 0))
8bc527af
SB
18626 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18627 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
bdeb029c
JH
18628
18629;; Convert epilogue deallocator to pop.
18630(define_peephole2
18631 [(match_scratch:SI 0 "r")
8bc527af
SB
18632 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18633 (clobber (reg:CC FLAGS_REG))
f2042df3 18634 (clobber (mem:BLK (scratch)))])]
bdeb029c 18635 "optimize_size || !TARGET_ADD_ESP_4"
8bc527af
SB
18636 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18637 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 18638 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
18639 "")
18640
18641;; Two pops case is tricky, since pop causes dependency on destination register.
18642;; We use two registers if available.
18643(define_peephole2
18644 [(match_scratch:SI 0 "r")
18645 (match_scratch:SI 1 "r")
8bc527af
SB
18646 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18647 (clobber (reg:CC FLAGS_REG))
f2042df3 18648 (clobber (mem:BLK (scratch)))])]
bdeb029c 18649 "optimize_size || !TARGET_ADD_ESP_8"
8bc527af
SB
18650 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18651 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 18652 (clobber (mem:BLK (scratch)))])
8bc527af
SB
18653 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18654 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
18655 "")
18656
18657(define_peephole2
18658 [(match_scratch:SI 0 "r")
8bc527af
SB
18659 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18660 (clobber (reg:CC FLAGS_REG))
f2042df3 18661 (clobber (mem:BLK (scratch)))])]
bdeb029c 18662 "optimize_size"
8bc527af
SB
18663 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18664 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
f2042df3 18665 (clobber (mem:BLK (scratch)))])
8bc527af
SB
18666 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18667 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
18668 "")
18669
18670;; Convert esp additions to pop.
18671(define_peephole2
18672 [(match_scratch:SI 0 "r")
8bc527af
SB
18673 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18674 (clobber (reg:CC FLAGS_REG))])]
bdeb029c 18675 ""
8bc527af
SB
18676 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18677 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
18678 "")
18679
18680;; Two pops case is tricky, since pop causes dependency on destination register.
18681;; We use two registers if available.
18682(define_peephole2
18683 [(match_scratch:SI 0 "r")
18684 (match_scratch:SI 1 "r")
8bc527af
SB
18685 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18686 (clobber (reg:CC FLAGS_REG))])]
bdeb029c 18687 ""
8bc527af
SB
18688 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18689 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18690 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18691 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c
JH
18692 "")
18693
18694(define_peephole2
18695 [(match_scratch:SI 0 "r")
8bc527af
SB
18696 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18697 (clobber (reg:CC FLAGS_REG))])]
bdeb029c 18698 "optimize_size"
8bc527af
SB
18699 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18700 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18701 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18702 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
bdeb029c 18703 "")
69404d6f 18704\f
9dcbdc7e 18705;; Convert compares with 1 to shorter inc/dec operations when CF is not
25da5dc7 18706;; required and register dies. Similarly for 128 to plus -128.
9dcbdc7e 18707(define_peephole2
25da5dc7
RH
18708 [(set (match_operand 0 "flags_reg_operand" "")
18709 (match_operator 1 "compare_operator"
18710 [(match_operand 2 "register_operand" "")
18711 (match_operand 3 "const_int_operand" "")]))]
18712 "(INTVAL (operands[3]) == -1
18713 || INTVAL (operands[3]) == 1
18714 || INTVAL (operands[3]) == 128)
18715 && ix86_match_ccmode (insn, CCGCmode)
18716 && peep2_reg_dead_p (1, operands[2])"
18717 [(parallel [(set (match_dup 0)
18718 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18719 (clobber (match_dup 2))])]
9dcbdc7e
JH
18720 "")
18721\f
cc2e591b
JH
18722(define_peephole2
18723 [(match_scratch:DI 0 "r")
8bc527af
SB
18724 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18725 (clobber (reg:CC FLAGS_REG))
f2042df3 18726 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
18727 "optimize_size || !TARGET_SUB_ESP_4"
18728 [(clobber (match_dup 0))
8bc527af 18729 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
f2042df3 18730 (clobber (mem:BLK (scratch)))])])
cc2e591b
JH
18731
18732(define_peephole2
18733 [(match_scratch:DI 0 "r")
8bc527af
SB
18734 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18735 (clobber (reg:CC FLAGS_REG))
f2042df3 18736 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
18737 "optimize_size || !TARGET_SUB_ESP_8"
18738 [(clobber (match_dup 0))
8bc527af
SB
18739 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18740 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
f2042df3 18741 (clobber (mem:BLK (scratch)))])])
cc2e591b 18742
f5143c46 18743;; Convert esp subtractions to push.
cc2e591b
JH
18744(define_peephole2
18745 [(match_scratch:DI 0 "r")
8bc527af
SB
18746 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18747 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
18748 "optimize_size || !TARGET_SUB_ESP_4"
18749 [(clobber (match_dup 0))
8bc527af 18750 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
cc2e591b
JH
18751
18752(define_peephole2
18753 [(match_scratch:DI 0 "r")
8bc527af
SB
18754 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18755 (clobber (reg:CC FLAGS_REG))])]
cc2e591b
JH
18756 "optimize_size || !TARGET_SUB_ESP_8"
18757 [(clobber (match_dup 0))
8bc527af
SB
18758 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18759 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
cc2e591b
JH
18760
18761;; Convert epilogue deallocator to pop.
18762(define_peephole2
18763 [(match_scratch:DI 0 "r")
8bc527af
SB
18764 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18765 (clobber (reg:CC FLAGS_REG))
f2042df3 18766 (clobber (mem:BLK (scratch)))])]
cc2e591b 18767 "optimize_size || !TARGET_ADD_ESP_4"
8bc527af
SB
18768 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18769 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 18770 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
18771 "")
18772
18773;; Two pops case is tricky, since pop causes dependency on destination register.
18774;; We use two registers if available.
18775(define_peephole2
18776 [(match_scratch:DI 0 "r")
18777 (match_scratch:DI 1 "r")
8bc527af
SB
18778 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18779 (clobber (reg:CC FLAGS_REG))
f2042df3 18780 (clobber (mem:BLK (scratch)))])]
cc2e591b 18781 "optimize_size || !TARGET_ADD_ESP_8"
8bc527af
SB
18782 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18783 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 18784 (clobber (mem:BLK (scratch)))])
8bc527af
SB
18785 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18786 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
18787 "")
18788
18789(define_peephole2
18790 [(match_scratch:DI 0 "r")
8bc527af
SB
18791 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18792 (clobber (reg:CC FLAGS_REG))
f2042df3 18793 (clobber (mem:BLK (scratch)))])]
cc2e591b 18794 "optimize_size"
8bc527af
SB
18795 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18796 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
f2042df3 18797 (clobber (mem:BLK (scratch)))])
8bc527af
SB
18798 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18799 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
18800 "")
18801
18802;; Convert esp additions to pop.
18803(define_peephole2
18804 [(match_scratch:DI 0 "r")
8bc527af
SB
18805 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18806 (clobber (reg:CC FLAGS_REG))])]
cc2e591b 18807 ""
8bc527af
SB
18808 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18809 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
18810 "")
18811
18812;; Two pops case is tricky, since pop causes dependency on destination register.
18813;; We use two registers if available.
18814(define_peephole2
18815 [(match_scratch:DI 0 "r")
18816 (match_scratch:DI 1 "r")
8bc527af
SB
18817 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18818 (clobber (reg:CC FLAGS_REG))])]
cc2e591b 18819 ""
8bc527af
SB
18820 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18821 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18822 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18823 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
18824 "")
18825
18826(define_peephole2
18827 [(match_scratch:DI 0 "r")
8bc527af
SB
18828 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18829 (clobber (reg:CC FLAGS_REG))])]
cc2e591b 18830 "optimize_size"
8bc527af
SB
18831 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18832 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18833 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18834 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
cc2e591b
JH
18835 "")
18836\f
cf14e33d
RS
18837;; Convert imul by three, five and nine into lea
18838(define_peephole2
18839 [(parallel
18840 [(set (match_operand:SI 0 "register_operand" "")
18841 (mult:SI (match_operand:SI 1 "register_operand" "")
18842 (match_operand:SI 2 "const_int_operand" "")))
18843 (clobber (reg:CC FLAGS_REG))])]
18844 "INTVAL (operands[2]) == 3
18845 || INTVAL (operands[2]) == 5
18846 || INTVAL (operands[2]) == 9"
18847 [(set (match_dup 0)
18848 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18849 (match_dup 1)))]
18850 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18851
18852(define_peephole2
18853 [(parallel
18854 [(set (match_operand:SI 0 "register_operand" "")
18855 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18856 (match_operand:SI 2 "const_int_operand" "")))
18857 (clobber (reg:CC FLAGS_REG))])]
18858 "!optimize_size
18859 && (INTVAL (operands[2]) == 3
18860 || INTVAL (operands[2]) == 5
18861 || INTVAL (operands[2]) == 9)"
18862 [(set (match_dup 0) (match_dup 1))
18863 (set (match_dup 0)
18864 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18865 (match_dup 0)))]
18866 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18867
18868(define_peephole2
18869 [(parallel
18870 [(set (match_operand:DI 0 "register_operand" "")
18871 (mult:DI (match_operand:DI 1 "register_operand" "")
18872 (match_operand:DI 2 "const_int_operand" "")))
18873 (clobber (reg:CC FLAGS_REG))])]
18874 "TARGET_64BIT
18875 && (INTVAL (operands[2]) == 3
18876 || INTVAL (operands[2]) == 5
18877 || INTVAL (operands[2]) == 9)"
18878 [(set (match_dup 0)
18879 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18880 (match_dup 1)))]
18881 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18882
18883(define_peephole2
18884 [(parallel
18885 [(set (match_operand:DI 0 "register_operand" "")
18886 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18887 (match_operand:DI 2 "const_int_operand" "")))
18888 (clobber (reg:CC FLAGS_REG))])]
18889 "TARGET_64BIT
18890 && !optimize_size
18891 && (INTVAL (operands[2]) == 3
18892 || INTVAL (operands[2]) == 5
18893 || INTVAL (operands[2]) == 9)"
18894 [(set (match_dup 0) (match_dup 1))
18895 (set (match_dup 0)
18896 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18897 (match_dup 0)))]
18898 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18899
f56e86bd
JH
18900;; Imul $32bit_imm, mem, reg is vector decoded, while
18901;; imul $32bit_imm, reg, reg is direct decoded.
18902(define_peephole2
18903 [(match_scratch:DI 3 "r")
18904 (parallel [(set (match_operand:DI 0 "register_operand" "")
18905 (mult:DI (match_operand:DI 1 "memory_operand" "")
18906 (match_operand:DI 2 "immediate_operand" "")))
8bc527af 18907 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
18908 "TARGET_K8 && !optimize_size
18909 && (GET_CODE (operands[2]) != CONST_INT
18910 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18911 [(set (match_dup 3) (match_dup 1))
18912 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
8bc527af 18913 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
18914"")
18915
18916(define_peephole2
18917 [(match_scratch:SI 3 "r")
18918 (parallel [(set (match_operand:SI 0 "register_operand" "")
18919 (mult:SI (match_operand:SI 1 "memory_operand" "")
18920 (match_operand:SI 2 "immediate_operand" "")))
8bc527af 18921 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
18922 "TARGET_K8 && !optimize_size
18923 && (GET_CODE (operands[2]) != CONST_INT
18924 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18925 [(set (match_dup 3) (match_dup 1))
18926 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
8bc527af 18927 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
18928"")
18929
18930(define_peephole2
18931 [(match_scratch:SI 3 "r")
18932 (parallel [(set (match_operand:DI 0 "register_operand" "")
18933 (zero_extend:DI
18934 (mult:SI (match_operand:SI 1 "memory_operand" "")
18935 (match_operand:SI 2 "immediate_operand" ""))))
8bc527af 18936 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
18937 "TARGET_K8 && !optimize_size
18938 && (GET_CODE (operands[2]) != CONST_INT
18939 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18940 [(set (match_dup 3) (match_dup 1))
18941 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
8bc527af 18942 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
18943"")
18944
18945;; imul $8/16bit_imm, regmem, reg is vector decoded.
18946;; Convert it into imul reg, reg
18947;; It would be better to force assembler to encode instruction using long
18948;; immediate, but there is apparently no way to do so.
18949(define_peephole2
18950 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18951 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18952 (match_operand:DI 2 "const_int_operand" "")))
8bc527af 18953 (clobber (reg:CC FLAGS_REG))])
f56e86bd
JH
18954 (match_scratch:DI 3 "r")]
18955 "TARGET_K8 && !optimize_size
18956 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18957 [(set (match_dup 3) (match_dup 2))
18958 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
8bc527af 18959 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
18960{
18961 if (!rtx_equal_p (operands[0], operands[1]))
18962 emit_move_insn (operands[0], operands[1]);
18963})
18964
18965(define_peephole2
18966 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18967 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18968 (match_operand:SI 2 "const_int_operand" "")))
8bc527af 18969 (clobber (reg:CC FLAGS_REG))])
f56e86bd
JH
18970 (match_scratch:SI 3 "r")]
18971 "TARGET_K8 && !optimize_size
18972 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18973 [(set (match_dup 3) (match_dup 2))
18974 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
8bc527af 18975 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
18976{
18977 if (!rtx_equal_p (operands[0], operands[1]))
18978 emit_move_insn (operands[0], operands[1]);
18979})
18980
18981(define_peephole2
18982 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18983 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18984 (match_operand:HI 2 "immediate_operand" "")))
8bc527af 18985 (clobber (reg:CC FLAGS_REG))])
f56e86bd
JH
18986 (match_scratch:HI 3 "r")]
18987 "TARGET_K8 && !optimize_size"
18988 [(set (match_dup 3) (match_dup 2))
18989 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
8bc527af 18990 (clobber (reg:CC FLAGS_REG))])]
f56e86bd
JH
18991{
18992 if (!rtx_equal_p (operands[0], operands[1]))
18993 emit_move_insn (operands[0], operands[1]);
18994})
18995\f
69404d6f
RH
18996;; Call-value patterns last so that the wildcard operand does not
18997;; disrupt insn-recog's switch tables.
18998
94bb5d0c
RH
18999(define_insn "*call_value_pop_0"
19000 [(set (match_operand 0 "" "")
e1ff012c 19001 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c 19002 (match_operand:SI 2 "" "")))
8bc527af 19003 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 19004 (match_operand:SI 3 "immediate_operand" "")))]
1e07edd3 19005 "!TARGET_64BIT"
94bb5d0c
RH
19006{
19007 if (SIBLING_CALL_P (insn))
0f40f9f7 19008 return "jmp\t%P1";
94bb5d0c 19009 else
0f40f9f7
ZW
19010 return "call\t%P1";
19011}
94bb5d0c
RH
19012 [(set_attr "type" "callv")])
19013
69404d6f
RH
19014(define_insn "*call_value_pop_1"
19015 [(set (match_operand 0 "" "")
e1ff012c 19016 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
94bb5d0c 19017 (match_operand:SI 2 "" "")))
8bc527af 19018 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
90d10fb9 19019 (match_operand:SI 3 "immediate_operand" "i")))]
1e07edd3 19020 "!TARGET_64BIT"
69404d6f 19021{
e427abbf 19022 if (constant_call_address_operand (operands[1], Pmode))
94bb5d0c
RH
19023 {
19024 if (SIBLING_CALL_P (insn))
0f40f9f7 19025 return "jmp\t%P1";
94bb5d0c 19026 else
0f40f9f7 19027 return "call\t%P1";
94bb5d0c 19028 }
94bb5d0c 19029 if (SIBLING_CALL_P (insn))
0f40f9f7 19030 return "jmp\t%A1";
94bb5d0c 19031 else
0f40f9f7
ZW
19032 return "call\t%A1";
19033}
94bb5d0c
RH
19034 [(set_attr "type" "callv")])
19035
19036(define_insn "*call_value_0"
19037 [(set (match_operand 0 "" "")
e1ff012c 19038 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c 19039 (match_operand:SI 2 "" "")))]
32ee7d1d 19040 "!TARGET_64BIT"
32ee7d1d
JH
19041{
19042 if (SIBLING_CALL_P (insn))
0f40f9f7 19043 return "jmp\t%P1";
32ee7d1d 19044 else
0f40f9f7
ZW
19045 return "call\t%P1";
19046}
32ee7d1d
JH
19047 [(set_attr "type" "callv")])
19048
19049(define_insn "*call_value_0_rex64"
19050 [(set (match_operand 0 "" "")
19051 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19052 (match_operand:DI 2 "const_int_operand" "")))]
19053 "TARGET_64BIT"
94bb5d0c
RH
19054{
19055 if (SIBLING_CALL_P (insn))
0f40f9f7 19056 return "jmp\t%P1";
94bb5d0c 19057 else
0f40f9f7
ZW
19058 return "call\t%P1";
19059}
69404d6f
RH
19060 [(set_attr "type" "callv")])
19061
69404d6f
RH
19062(define_insn "*call_value_1"
19063 [(set (match_operand 0 "" "")
e1ff012c 19064 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
94bb5d0c 19065 (match_operand:SI 2 "" "")))]
4977bab6 19066 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
32ee7d1d 19067{
e427abbf 19068 if (constant_call_address_operand (operands[1], Pmode))
4977bab6 19069 return "call\t%P1";
6a46f71d 19070 return "call\t%A1";
4977bab6
ZW
19071}
19072 [(set_attr "type" "callv")])
19073
19074(define_insn "*sibcall_value_1"
19075 [(set (match_operand 0 "" "")
19076 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19077 (match_operand:SI 2 "" "")))]
19078 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19079{
e427abbf 19080 if (constant_call_address_operand (operands[1], Pmode))
4977bab6 19081 return "jmp\t%P1";
6a46f71d 19082 return "jmp\t%A1";
0f40f9f7 19083}
32ee7d1d
JH
19084 [(set_attr "type" "callv")])
19085
19086(define_insn "*call_value_1_rex64"
19087 [(set (match_operand 0 "" "")
19088 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19089 (match_operand:DI 2 "" "")))]
4977bab6 19090 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
69404d6f 19091{
e427abbf 19092 if (constant_call_address_operand (operands[1], Pmode))
4977bab6
ZW
19093 return "call\t%P1";
19094 return "call\t%A1";
0f40f9f7 19095}
69404d6f 19096 [(set_attr "type" "callv")])
4977bab6
ZW
19097
19098(define_insn "*sibcall_value_1_rex64"
19099 [(set (match_operand 0 "" "")
19100 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19101 (match_operand:DI 2 "" "")))]
19102 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19103 "jmp\t%P1"
19104 [(set_attr "type" "callv")])
19105
19106(define_insn "*sibcall_value_1_rex64_v"
19107 [(set (match_operand 0 "" "")
19108 (call (mem:QI (reg:DI 40))
19109 (match_operand:DI 1 "" "")))]
19110 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19111 "jmp\t*%%r11"
19112 [(set_attr "type" "callv")])
9e3e266c
GM
19113\f
19114(define_insn "trap"
19115 [(trap_if (const_int 1) (const_int 5))]
19116 ""
0f40f9f7 19117 "int\t$5")
9e3e266c
GM
19118
19119;;; ix86 doesn't have conditional trap instructions, but we fake them
19120;;; for the sake of bounds checking. By emitting bounds checks as
19121;;; conditional traps rather than as conditional jumps around
19122;;; unconditional traps we avoid introducing spurious basic-block
19123;;; boundaries and facilitate elimination of redundant checks. In
19124;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19125;;; interrupt 5.
19126;;;
19127;;; FIXME: Static branch prediction rules for ix86 are such that
19128;;; forward conditional branches predict as untaken. As implemented
19129;;; below, pseudo conditional traps violate that rule. We should use
19130;;; .pushsection/.popsection to place all of the `int 5's in a special
19131;;; section loaded at the end of the text segment and branch forward
19132;;; there on bounds-failure, and then jump back immediately (in case
19133;;; the system chooses to ignore bounds violations, or to report
19134;;; violations and continue execution).
19135
19136(define_expand "conditional_trap"
19137 [(trap_if (match_operator 0 "comparison_operator"
19138 [(match_dup 2) (const_int 0)])
19139 (match_operand 1 "const_int_operand" ""))]
19140 ""
9e3e266c
GM
19141{
19142 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
a1b8572c 19143 ix86_expand_compare (GET_CODE (operands[0]),
df4ae160 19144 NULL, NULL),
9e3e266c
GM
19145 operands[1]));
19146 DONE;
0f40f9f7 19147})
9e3e266c 19148
0f40f9f7 19149(define_insn "*conditional_trap_1"
9e3e266c 19150 [(trap_if (match_operator 0 "comparison_operator"
42fabf21 19151 [(reg FLAGS_REG) (const_int 0)])
9e3e266c
GM
19152 (match_operand 1 "const_int_operand" ""))]
19153 ""
9e3e266c
GM
19154{
19155 operands[2] = gen_label_rtx ();
0f40f9f7 19156 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
4977bab6 19157 (*targetm.asm_out.internal_label) (asm_out_file, "L",
9e3e266c
GM
19158 CODE_LABEL_NUMBER (operands[2]));
19159 RET;
0f40f9f7 19160})
915119a5 19161
ef719a44
RH
19162(define_expand "sse_prologue_save"
19163 [(parallel [(set (match_operand:BLK 0 "" "")
19164 (unspec:BLK [(reg:DI 21)
19165 (reg:DI 22)
19166 (reg:DI 23)
19167 (reg:DI 24)
19168 (reg:DI 25)
19169 (reg:DI 26)
19170 (reg:DI 27)
19171 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19172 (use (match_operand:DI 1 "register_operand" ""))
19173 (use (match_operand:DI 2 "immediate_operand" ""))
19174 (use (label_ref:DI (match_operand 3 "" "")))])]
19175 "TARGET_64BIT"
19176 "")
0703dceb 19177
ef719a44
RH
19178(define_insn "*sse_prologue_save_insn"
19179 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19180 (match_operand:DI 4 "const_int_operand" "n")))
19181 (unspec:BLK [(reg:DI 21)
19182 (reg:DI 22)
19183 (reg:DI 23)
19184 (reg:DI 24)
19185 (reg:DI 25)
19186 (reg:DI 26)
19187 (reg:DI 27)
19188 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19189 (use (match_operand:DI 1 "register_operand" "r"))
19190 (use (match_operand:DI 2 "const_int_operand" "i"))
19191 (use (label_ref:DI (match_operand 3 "" "X")))]
19192 "TARGET_64BIT
19193 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19194 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19195 "*
0703dceb 19196{
ef719a44
RH
19197 int i;
19198 operands[0] = gen_rtx_MEM (Pmode,
19199 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19200 output_asm_insn (\"jmp\\t%A1\", operands);
19201 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19202 {
19203 operands[4] = adjust_address (operands[0], DImode, i*16);
19204 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19205 PUT_MODE (operands[4], TImode);
19206 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19207 output_asm_insn (\"rex\", operands);
19208 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19209 }
19210 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19211 CODE_LABEL_NUMBER (operands[3]));
19212 RET;
0703dceb 19213}
ef719a44
RH
19214 "
19215 [(set_attr "type" "other")
19216 (set_attr "length_immediate" "0")
19217 (set_attr "length_address" "0")
19218 (set_attr "length" "135")
19219 (set_attr "memory" "store")
19220 (set_attr "modrm" "0")
3d34cd91 19221 (set_attr "mode" "DI")])
915119a5 19222
ef719a44
RH
19223(define_expand "prefetch"
19224 [(prefetch (match_operand 0 "address_operand" "")
19225 (match_operand:SI 1 "const_int_operand" "")
19226 (match_operand:SI 2 "const_int_operand" ""))]
19227 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
1c47af84 19228{
ef719a44
RH
19229 int rw = INTVAL (operands[1]);
19230 int locality = INTVAL (operands[2]);
1c47af84 19231
ef719a44
RH
19232 if (rw != 0 && rw != 1)
19233 abort ();
19234 if (locality < 0 || locality > 3)
19235 abort ();
19236 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19237 abort ();
1c47af84 19238
ef719a44
RH
19239 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19240 suported by SSE counterpart or the SSE prefetch is not available
19241 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19242 of locality. */
19243 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19244 operands[2] = GEN_INT (3);
19245 else
19246 operands[1] = const0_rtx;
1c47af84
RH
19247})
19248
ef719a44
RH
19249(define_insn "*prefetch_sse"
19250 [(prefetch (match_operand:SI 0 "address_operand" "p")
19251 (const_int 0)
19252 (match_operand:SI 1 "const_int_operand" ""))]
19253 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
4977bab6 19254{
ef719a44
RH
19255 static const char * const patterns[4] = {
19256 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19257 };
fbe5eb6d 19258
ef719a44
RH
19259 int locality = INTVAL (operands[1]);
19260 if (locality < 0 || locality > 3)
19261 abort ();
fbe5eb6d 19262
ef719a44
RH
19263 return patterns[locality];
19264}
fbe5eb6d 19265 [(set_attr "type" "sse")
ef719a44 19266 (set_attr "memory" "none")])
fbe5eb6d 19267
ef719a44
RH
19268(define_insn "*prefetch_sse_rex"
19269 [(prefetch (match_operand:DI 0 "address_operand" "p")
19270 (const_int 0)
19271 (match_operand:SI 1 "const_int_operand" ""))]
19272 "TARGET_PREFETCH_SSE && TARGET_64BIT"
fbe5eb6d 19273{
ef719a44
RH
19274 static const char * const patterns[4] = {
19275 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19276 };
22c7c85e 19277
ef719a44
RH
19278 int locality = INTVAL (operands[1]);
19279 if (locality < 0 || locality > 3)
19280 abort ();
22c7c85e 19281
ef719a44
RH
19282 return patterns[locality];
19283}
22c7c85e 19284 [(set_attr "type" "sse")
ef719a44 19285 (set_attr "memory" "none")])
22c7c85e 19286
ef719a44
RH
19287(define_insn "*prefetch_3dnow"
19288 [(prefetch (match_operand:SI 0 "address_operand" "p")
19289 (match_operand:SI 1 "const_int_operand" "n")
19290 (const_int 3))]
19291 "TARGET_3DNOW && !TARGET_64BIT"
19292{
19293 if (INTVAL (operands[1]) == 0)
19294 return "prefetch\t%a0";
19295 else
19296 return "prefetchw\t%a0";
19297}
19298 [(set_attr "type" "mmx")
19299 (set_attr "memory" "none")])
22c7c85e 19300
ef719a44
RH
19301(define_insn "*prefetch_3dnow_rex"
19302 [(prefetch (match_operand:DI 0 "address_operand" "p")
19303 (match_operand:SI 1 "const_int_operand" "n")
19304 (const_int 3))]
19305 "TARGET_3DNOW && TARGET_64BIT"
19306{
19307 if (INTVAL (operands[1]) == 0)
19308 return "prefetch\t%a0";
19309 else
19310 return "prefetchw\t%a0";
19311}
19312 [(set_attr "type" "mmx")
19313 (set_attr "memory" "none")])
22c7c85e 19314
ef719a44 19315(include "sse.md")
80e8bb90 19316(include "mmx.md")
This page took 6.584584 seconds and 5 git commands to generate.